On Wed, 2011-04-20 at 21:51 +0200, Maciej Marcin Piechotka wrote: > Hello. > > For some libgee work I need to have working volatile. The problem is > that this support needs a bit care (in short - it does not work on any > profile but it breaks in different places - see bug #622338 [1] for > breakage on lexer in non-dova profile and bug #648330 [2] for silently > not working in dova profile) > > I guess that the problem is that from POV of vala there is no > possibility of annotating pointers. I.e. the modifications of types > applies to types only and not to pointers (for ex. const pointers are > not supported). > > However the problem with most usage of volatile is that it *requires* > low-level access: > > - int volatile * specifies a pointer to volatile area (i.e. one that is > beyond control of processor). It can be specified as volatile int * as > well. > - int * volatile specifies a pointer that is beyond control of > processor > > Those are two distinct cases. Arguably the second one is more common in > mid-HL languages (the first one is need for the original use of volatile > i.e. the memory-mapped I/O). > > I can produce patches for it but: > > - How should the volatile pointer be specified in syntax? > - How should the pointer to volatile memory be specified? Is it needed > at all? > - Do we want to keep compatibility with C bracketing? > - What about brother of volatile (const)? > > Solutions: > > - volatile brackets like in C. I.e. volatile int * is (volatile int) * > not volatile (int *) > - volatile brackets like in C but can be only on RHS of the bracketing > int volatile * is (int volatile) * while int * volatile is (int *) > volatile > - volatile only corresponds to memory it specifies. I.e. volatile int * > is volatile (int *). This is implemented by patches to bug 648330 [2] > > Regards > > [1] https://bugzilla.gnome.org/show_bug.cgi?id=622338 > [2] https://bugzilla.gnome.org/show_bug.cgi?id=648330
I took the liberty of producing patch anyway and attaching it to bug as well as to this e-mail. The main difference is it makes it property of type (as is weak or unowned). It also allows to have much more complicated types as volatile pointer to volatile memory. - volatile on LHS keeps compatibility with C. I.e. int volatile * is pointer to volatile int while int * volatile is volatile pointer to int. - volatile on RHS is not parsed as in C. it refers to field as whole. So volatile void * is the same as void * volatile not void volatile * Regards PS. Happy <insert holidays you are celebrating>
From 692d8e0c3c2442453f8317de91879a7464bf62c8 Mon Sep 17 00:00:00 2001 From: Maciej Piechotka <[email protected]> Date: Sun, 24 Apr 2011 09:14:27 +0200 Subject: [PATCH] Implement more advanced handling of volatile - Made it property of type rather then field. It allows such things like pointer to volatile memory or volatile pointer to volatile memory - Implement handling of volatile similar to one from C except that initial volatile have precedence highier only to array (i.e. referes to whole type or whole element rather then to type alone). --- ccode/valaccodedeclaration.vala | 3 --- ccode/valaccodemodifiers.vala | 1 - codegen/valagdbusmodule.vala | 4 ++-- codegen/valatyperegisterfunction.vala | 5 +---- vala/Makefile.am | 1 + vala/valaparser.vala | 31 ++++++++++++++++--------------- vala/valapointertype.vala | 10 ++++++---- vala/valasymbolresolver.vala | 13 +++++++++++++ vala/valaunresolvedtype.vala | 2 +- vala/valavaluetype.vala | 5 ++++- vala/valavolatiletype.vala | 31 +++++++++++++++++++++++++++++++ 11 files changed, 75 insertions(+), 31 deletions(-) create mode 100644 vala/valavolatiletype.vala diff --git a/ccode/valaccodedeclaration.vala b/ccode/valaccodedeclaration.vala index 95216f8..9429dfd 100644 --- a/ccode/valaccodedeclaration.vala +++ b/ccode/valaccodedeclaration.vala @@ -76,9 +76,6 @@ public class Vala.CCodeDeclaration : CCodeStatement { if ((modifiers & CCodeModifiers.STATIC) != 0) { writer.write_string ("static "); } - if ((modifiers & CCodeModifiers.VOLATILE) != 0) { - writer.write_string ("volatile "); - } if ((modifiers & CCodeModifiers.EXTERN) != 0 && !has_initializer ()) { writer.write_string ("extern "); } diff --git a/ccode/valaccodemodifiers.vala b/ccode/valaccodemodifiers.vala index 4dd7455..3b1520e 100644 --- a/ccode/valaccodemodifiers.vala +++ b/ccode/valaccodemodifiers.vala @@ -31,7 +31,6 @@ public enum Vala.CCodeModifiers { REGISTER = 1 << 1, EXTERN = 1 << 2, INLINE = 1 << 3, - VOLATILE = 1 << 4, DEPRECATED = 1 << 5, THREAD_LOCAL = 1 << 6 } diff --git a/codegen/valagdbusmodule.vala b/codegen/valagdbusmodule.vala index 9f13281..c0e3e5f 100644 --- a/codegen/valagdbusmodule.vala +++ b/codegen/valagdbusmodule.vala @@ -91,9 +91,9 @@ public class Vala.GDBusModule : GVariantModule { string quark_name = "%squark_volatile".printf (edomain.get_lower_case_cprefix ()); - cdecl = new CCodeDeclaration ("gsize"); + cdecl = new CCodeDeclaration ("gsize volatile"); cdecl.add_declarator (new CCodeVariableDeclarator (quark_name, new CCodeConstant ("0"))); - cdecl.modifiers = CCodeModifiers.STATIC | CCodeModifiers.VOLATILE; + cdecl.modifiers = CCodeModifiers.STATIC; cquark_block.add_statement (cdecl); var register_call = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_error_register_error_domain")); diff --git a/codegen/valatyperegisterfunction.vala b/codegen/valatyperegisterfunction.vala index e3f38ad..dede020 100644 --- a/codegen/valatyperegisterfunction.vala +++ b/codegen/valatyperegisterfunction.vala @@ -49,16 +49,13 @@ public abstract class Vala.TypeRegisterFunction { var type_block = new CCodeBlock (); CCodeDeclaration cdecl; if (use_thread_safe) { - cdecl = new CCodeDeclaration ("gsize"); + cdecl = new CCodeDeclaration ("gsize volatile"); cdecl.add_declarator (new CCodeVariableDeclarator (type_id_name + "__volatile", new CCodeConstant ("0"))); } else { cdecl = new CCodeDeclaration ("GType"); cdecl.add_declarator (new CCodeVariableDeclarator (type_id_name, new CCodeConstant ("0"))); } cdecl.modifiers = CCodeModifiers.STATIC; - if (use_thread_safe) { - cdecl.modifiers |= CCodeModifiers.VOLATILE; - } if (!plugin) { type_block.add_statement (cdecl); } else { diff --git a/vala/Makefile.am b/vala/Makefile.am index b20c832..e2bc478 100644 --- a/vala/Makefile.am +++ b/vala/Makefile.am @@ -160,6 +160,7 @@ libvalacore_la_VALASOURCES = \ valavaluetype.vala \ valavariable.vala \ valavoidtype.vala \ + valavolatiletype.vala \ valawhilestatement.vala \ valayieldstatement.vala \ $(NULL) diff --git a/vala/valaparser.vala b/vala/valaparser.vala index 136bf01..3e2defa 100644 --- a/vala/valaparser.vala +++ b/vala/valaparser.vala @@ -242,7 +242,6 @@ public class Vala.Parser : CodeVisitor { case TokenType.VAR: case TokenType.VIRTUAL: case TokenType.VOID: - case TokenType.VOLATILE: case TokenType.WEAK: case TokenType.WHILE: case TokenType.YIELD: @@ -409,11 +408,14 @@ public class Vala.Parser : CodeVisitor { if (accept (TokenType.VOID)) { DataType type = new VoidType (get_src (begin)); while (accept (TokenType.STAR)) { - type = new PointerType (type); + var ptr = new PointerType (type); + ptr.is_volatile = accept (TokenType.VOLATILE); + type = ptr; } return type; } + bool is_volatile = accept (TokenType.VOLATILE); bool is_dynamic = accept (TokenType.DYNAMIC); bool value_owned = owned_by_default; @@ -438,21 +440,28 @@ public class Vala.Parser : CodeVisitor { var sym = parse_symbol_name (); List<DataType> type_arg_list = parse_type_argument_list (false); - DataType type = new UnresolvedType.from_symbol (sym, get_src (begin)); + VolatileType utype = new UnresolvedType.from_symbol (sym, get_src (begin)); if (type_arg_list != null) { foreach (DataType type_arg in type_arg_list) { - type.add_type_argument (type_arg); + utype.add_type_argument (type_arg); } } + utype.is_volatile = accept (TokenType.VOLATILE); + while (accept (TokenType.STAR)) { - type = new PointerType (type, get_src (begin)); + var ptr = new PointerType (utype, get_src (begin)); + ptr.is_volatile = accept (TokenType.VOLATILE); + utype = ptr; } - if (!(type is PointerType)) { - type.nullable = accept (TokenType.INTERR); + if (!(utype is PointerType)) { + utype.nullable = accept (TokenType.INTERR); } + utype.is_volatile = is_volatile; + + DataType type = utype; // array brackets in types are read from right to left, // this is more logical, especially when nullable arrays // or pointers are involved @@ -2314,7 +2323,6 @@ public class Vala.Parser : CodeVisitor { case TokenType.STATIC: case TokenType.STRUCT: case TokenType.VIRTUAL: - case TokenType.VOLATILE: return RecoveryState.DECLARATION_BEGIN; case TokenType.BREAK: case TokenType.CONTINUE: @@ -2485,9 +2493,6 @@ public class Vala.Parser : CodeVisitor { var begin = get_location (); var access = parse_access_modifier (); var flags = parse_member_declaration_modifiers (); - if (context.profile == Profile.DOVA) { - accept (TokenType.VOLATILE); - } var type = parse_type (true, true); string id = parse_identifier (); @@ -3203,9 +3208,6 @@ public class Vala.Parser : CodeVisitor { direction = ParameterDirection.REF; } - if (context.profile == Profile.DOVA) { - accept (TokenType.VOLATILE); - } DataType type; if (direction == ParameterDirection.IN) { // in parameters are unowned by default @@ -3499,7 +3501,6 @@ public class Vala.Parser : CodeVisitor { case TokenType.STATIC: case TokenType.STRUCT: case TokenType.VIRTUAL: - case TokenType.VOLATILE: return true; default: return false; diff --git a/vala/valapointertype.vala b/vala/valapointertype.vala index d7da3d8..d27cd81 100644 --- a/vala/valapointertype.vala +++ b/vala/valapointertype.vala @@ -25,7 +25,7 @@ using GLib; /** * A pointer type. */ -public class Vala.PointerType : DataType { +public class Vala.PointerType : VolatileType { /** * The base type the pointer is referring to. */ @@ -46,14 +46,16 @@ public class Vala.PointerType : DataType { } public override string to_qualified_string (Scope? scope) { - return base_type.to_qualified_string (scope) + "*"; + string volatile_type = is_volatile ? " volatile" : ""; + return base_type.to_qualified_string (scope) + "*" + volatile_type; } public override string? get_cname () { + string volatile_type = is_volatile ? " volatile" : ""; if (base_type.data_type != null && base_type.data_type.is_reference_type ()) { - return base_type.get_cname (); + return base_type.get_cname () + volatile_type; } else { - return base_type.get_cname () + "*"; + return base_type.get_cname () + "*" + volatile_type; } } diff --git a/vala/valasymbolresolver.vala b/vala/valasymbolresolver.vala index 3f874fa..8c0afeb 100644 --- a/vala/valasymbolresolver.vala +++ b/vala/valasymbolresolver.vala @@ -368,6 +368,19 @@ public class Vala.SymbolResolver : CodeVisitor { type.nullable = unresolved_type.nullable; } + if (unresolved_type.is_volatile && !type.nullable) { + VolatileType? vtype = type as VolatileType; + if (vtype != null) { + if (!type.nullable) { + vtype.is_volatile = true; + } else { + Report.error (unresolved_type.source_reference, "`%s' cannot be nullable and volatile not being a pointer".printf (sym.get_full_name ())); + } + } else { + Report.error (unresolved_type.source_reference, "`%s' cannot be volatile".printf (sym.get_full_name ())); + } + } + type.is_dynamic = unresolved_type.is_dynamic; foreach (DataType type_arg in unresolved_type.get_type_arguments ()) { type.add_type_argument (type_arg); diff --git a/vala/valaunresolvedtype.vala b/vala/valaunresolvedtype.vala index 527fa0a..3e722c4 100644 --- a/vala/valaunresolvedtype.vala +++ b/vala/valaunresolvedtype.vala @@ -26,7 +26,7 @@ using GLib; /** * An unresolved reference to a data type. */ -public class Vala.UnresolvedType : DataType { +public class Vala.UnresolvedType : VolatileType { /** * The unresolved reference to a type symbol. */ diff --git a/vala/valavaluetype.vala b/vala/valavaluetype.vala index baec19e..8de18c4 100644 --- a/vala/valavaluetype.vala +++ b/vala/valavaluetype.vala @@ -25,7 +25,7 @@ using GLib; /** * A value type, i.e. a struct or an enum type. */ -public abstract class Vala.ValueType : DataType { +public abstract class Vala.ValueType : VolatileType { /** * The referred struct or enum. */ @@ -41,6 +41,9 @@ public abstract class Vala.ValueType : DataType { if (nullable) { ptr = "*"; } + if (is_volatile) { + ptr = " volatile"; + } return type_symbol.get_cname () + ptr; } diff --git a/vala/valavolatiletype.vala b/vala/valavolatiletype.vala new file mode 100644 index 0000000..09cc5e9 --- /dev/null +++ b/vala/valavolatiletype.vala @@ -0,0 +1,31 @@ +/* valavolatiletype.vala + * + * Copyright (C) 2011 Maciej Piechotka + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: + * Maciej Piechotka <[email protected]> + */ + +/** + * A type that can be volatile + */ +public abstract class Vala.VolatileType : DataType { + /** + * Is data volatile + */ + public bool is_volatile { get; set; default = false; } +} -- 1.7.5.rc1
signature.asc
Description: This is a digitally signed message part
_______________________________________________ vala-list mailing list [email protected] http://mail.gnome.org/mailman/listinfo/vala-list
