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

Attachment: signature.asc
Description: This is a digitally signed message part

_______________________________________________
vala-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/vala-list

Reply via email to