From 692d8e0c3c2442453f8317de91879a7464bf62c8 Mon Sep 17 00:00:00 2001 From: Maciej Piechotka 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 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 + */ + +/** + * 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