]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Use TypeRegisterFunction for enum/flags
authorMarc-André Lureau <marcandre.lureau@gmail.com>
Tue, 26 Jan 2010 00:47:55 +0000 (01:47 +0100)
committerJürg Billeter <j@bitron.ch>
Sun, 21 Mar 2010 22:43:28 +0000 (23:43 +0100)
Fixes bug 592904.

codegen/Makefile.am
codegen/valaccodebasemodule.vala
codegen/valaenumregisterfunction.vala [new file with mode: 0644]
codegen/valagtypemodule.vala
codegen/valastructregisterfunction.vala
codegen/valatyperegisterfunction.vala

index b672c27840483046ee34de54fe6c1ac170650bdf..8a452b268c091e843d530ce51251f40256c7fec6 100644 (file)
@@ -34,6 +34,7 @@ libvala_la_VALASOURCES = \
        valadbusinterfaceregisterfunction.vala \
        valadbusmodule.vala \
        valadbusservermodule.vala \
+       valaenumregisterfunction.vala \
        valagerrormodule.vala \
        valagirwriter.vala \
        valagobjectmodule.vala \
index 1beb9fa08f1a36568448d5da07d5b9b2d30ddaad..ea136b213862113d097b628b3df27de2ff23add5 100644 (file)
@@ -804,79 +804,6 @@ internal class Vala.CCodeBaseModule : CCodeModule {
                if (!en.is_private_symbol ()) {
                        generate_enum_declaration (en, internal_header_declarations);
                }
-
-               if (!en.has_type_id) {
-                       return;
-               }
-
-               var clist = new CCodeInitializerList (); /* or during visit time? */
-               CCodeInitializerList clist_ev = null;
-               foreach (EnumValue ev in en.get_values ()) {
-                       clist_ev = new CCodeInitializerList ();
-                       clist_ev.append (new CCodeConstant (ev.get_cname ()));
-                       clist_ev.append (new CCodeIdentifier ("\"%s\"".printf (ev.get_cname ())));
-                       clist_ev.append (ev.get_canonical_cconstant ());
-                       clist.append (clist_ev);
-               }
-
-               clist_ev = new CCodeInitializerList ();
-               clist_ev.append (new CCodeConstant ("0"));
-               clist_ev.append (new CCodeConstant ("NULL"));
-               clist_ev.append (new CCodeConstant ("NULL"));
-               clist.append (clist_ev);
-
-               var enum_decl = new CCodeVariableDeclarator ("values[]", clist);
-
-               CCodeDeclaration cdecl = null;
-               if (en.is_flags) {
-                       cdecl = new CCodeDeclaration ("const GFlagsValue");
-               } else {
-                       cdecl = new CCodeDeclaration ("const GEnumValue");
-               }
-
-               cdecl.add_declarator (enum_decl);
-               cdecl.modifiers = CCodeModifiers.STATIC;
-
-               var type_init = new CCodeBlock ();
-
-               type_init.add_statement (cdecl);
-
-               var fun_name = "%s_get_type".printf (en.get_lower_case_cname (null));
-               var regfun = new CCodeFunction (fun_name, "GType");
-               var regblock = new CCodeBlock ();
-
-               cdecl = new CCodeDeclaration ("GType");
-               string type_id_name = "%s_type_id".printf (en.get_lower_case_cname (null));
-               cdecl.add_declarator (new CCodeVariableDeclarator (type_id_name, new CCodeConstant ("0")));
-               cdecl.modifiers = CCodeModifiers.STATIC;
-               regblock.add_statement (cdecl);
-
-               CCodeFunctionCall reg_call;
-               if (en.is_flags) {
-                       reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_flags_register_static"));
-               } else {
-                       reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_enum_register_static"));
-               }
-
-               reg_call.add_argument (new CCodeConstant ("\"%s\"".printf (en.get_cname())));
-               reg_call.add_argument (new CCodeIdentifier ("values"));
-
-               type_init.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier (type_id_name), reg_call)));
-
-               var cond = new CCodeFunctionCall (new CCodeIdentifier ("G_UNLIKELY"));
-               cond.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeIdentifier (type_id_name), new CCodeConstant ("0")));
-               var cif = new CCodeIfStatement (cond, type_init);
-               regblock.add_statement (cif);
-
-               regblock.add_statement (new CCodeReturnStatement (new CCodeConstant (type_id_name)));
-
-               if (en.access == SymbolAccessibility.PRIVATE) {
-                       regfun.modifiers = CCodeModifiers.STATIC;
-               }
-               regfun.block = regblock;
-
-               source_type_member_definition.append (new CCodeNewline ());
-               source_type_member_definition.append (regfun);
        }
 
        public override void visit_member (Member m) {
diff --git a/codegen/valaenumregisterfunction.vala b/codegen/valaenumregisterfunction.vala
new file mode 100644 (file)
index 0000000..e54098c
--- /dev/null
@@ -0,0 +1,57 @@
+/* valaenumregisterfunction.vala
+ *
+ * Copyright (C) 2008  Jürg Billeter
+ * Copyright (C) 2010  Marc-Andre Lureau
+ *
+ * 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:
+ *     Jürg Billeter <j@bitron.ch>
+ */
+
+using GLib;
+
+/**
+ * C function to register an enum at runtime.
+ */
+public class Vala.EnumRegisterFunction : TypeRegisterFunction {
+       /**
+        * Specifies the enum to be registered.
+        */
+       public weak Enum enum_reference { get; set; }
+
+       /**
+        * Creates a new C function to register the specified enum at runtime.
+        *
+        * @param en an enum
+        * @return   newly created enum register function
+        */
+       public EnumRegisterFunction (Enum en, CodeContext context) {
+               enum_reference = en;
+               this.context = context;
+       }
+
+       public override TypeSymbol get_type_declaration () {
+               return enum_reference;
+       }
+
+       public override SymbolAccessibility get_accessibility () {
+               return enum_reference.access;
+       }
+
+       public override CCodeFragment get_type_interface_init_statements (bool plugin) {
+               return new CCodeFragment ();
+       }
+}
index 7353e6670226a998e487005ffd7815e317466421..152fcae541a5e91d9e4becd617c3d43422c5a675 100644 (file)
@@ -2017,6 +2017,16 @@ internal class Vala.GTypeModule : GErrorModule {
                }
        }
 
+       public override void visit_enum (Enum en) {
+               base.visit_enum (en);
+
+               if (en.has_type_id) {
+                       var type_fun = new EnumRegisterFunction (en, context);
+                       type_fun.init_from_type (false);
+                       source_type_member_definition.append (type_fun.get_definition ());
+               }
+       }
+
        public override void visit_method_call (MethodCall expr) {
                var ma = expr.call as MemberAccess;
                var mtype = expr.call.value_type as MethodType;
index 1f79fdb47baf1a1d27e691a9992bd8633f676feb..2684b48b504086f8db9067529ac7acce3290358e 100644 (file)
@@ -23,7 +23,7 @@
 using GLib;
 
 /**
- * C function to register a class at runtime.
+ * C function to register a struct at runtime.
  */
 public class Vala.StructRegisterFunction : TypeRegisterFunction {
        /**
@@ -32,10 +32,10 @@ public class Vala.StructRegisterFunction : TypeRegisterFunction {
        public weak Struct struct_reference { get; set; }
 
        /**
-        * Creates a new C function to register the specified class at runtime.
+        * Creates a new C function to register the specified struct at runtime.
         *
-        * @param cl a class
-        * @return   newly created class register function
+        * @param st a struct
+        * @return   newly created struct register function
         */
        public StructRegisterFunction (Struct st, CodeContext context) {
                struct_reference = st;
index 571bca64a66be20d18fe950548bb65b443d0ed10..b56f1593e548341e07fd61e237bc6b246b77275d 100644 (file)
@@ -141,6 +141,13 @@ public abstract class Vala.TypeRegisterFunction {
                CCodeFunctionCall reg_call;
                if (get_type_declaration () is Struct) {
                        reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_boxed_type_register_static"));
+               } else if (get_type_declaration () is Enum) {
+                       var en = get_type_declaration () as Enum;
+                       if (en.is_flags) {
+                               reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_flags_register_static"));
+                       } else {
+                               reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_enum_register_static"));
+                       }
                } else if (fundamental) {
                        reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_type_register_fundamental"));
                        reg_call.add_argument (new CCodeFunctionCall (new CCodeIdentifier ("g_type_fundamental_next")));
@@ -157,6 +164,39 @@ public abstract class Vala.TypeRegisterFunction {
                        var st = (Struct) get_type_declaration ();
                        reg_call.add_argument (new CCodeCastExpression (new CCodeIdentifier (st.get_dup_function ()), "GBoxedCopyFunc"));
                        reg_call.add_argument (new CCodeCastExpression (new CCodeIdentifier (st.get_free_function ()), "GBoxedFreeFunc"));
+               } else if (get_type_declaration () is Enum) {
+                       var en = get_type_declaration () as Enum;
+                       var clist = new CCodeInitializerList (); /* or during visit time? */
+
+                       CCodeInitializerList clist_ev = null;
+                       foreach (EnumValue ev in en.get_values ()) {
+                               clist_ev = new CCodeInitializerList ();
+                               clist_ev.append (new CCodeConstant (ev.get_cname ()));
+                               clist_ev.append (new CCodeIdentifier ("\"%s\"".printf (ev.get_cname ())));
+                               clist_ev.append (ev.get_canonical_cconstant ());
+                               clist.append (clist_ev);
+                       }
+
+                       clist_ev = new CCodeInitializerList ();
+                       clist_ev.append (new CCodeConstant ("0"));
+                       clist_ev.append (new CCodeConstant ("NULL"));
+                       clist_ev.append (new CCodeConstant ("NULL"));
+                       clist.append (clist_ev);
+
+                       var enum_decl = new CCodeVariableDeclarator ("values[]", clist);
+
+                       if (en.is_flags) {
+                               cdecl = new CCodeDeclaration ("const GFlagsValue");
+                       } else {
+                               cdecl = new CCodeDeclaration ("const GEnumValue");
+                       }
+
+                       cdecl.add_declarator (enum_decl);
+                       cdecl.modifiers = CCodeModifiers.STATIC;
+
+                       type_init.add_statement (cdecl);
+
+                       reg_call.add_argument (new CCodeIdentifier ("values"));
                } else {
                        reg_call.add_argument (new CCodeIdentifier ("&g_define_type_info"));
                        if (fundamental) {
@@ -172,7 +212,7 @@ public abstract class Vala.TypeRegisterFunction {
                } else {
                        type_init.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier (type_id_name), reg_call)));
                }
-               
+
                type_init.add_statement (get_type_interface_init_statements (plugin));
 
                if (!plugin) {
@@ -192,7 +232,14 @@ public abstract class Vala.TypeRegisterFunction {
                                condition = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, id, zero);
                        }
 
-                       var cif = new CCodeIfStatement (condition, type_init);
+                       CCodeExpression cond;
+                       if (use_thread_safe) {
+                               cond = condition;
+                       } else {
+                               cond = new CCodeFunctionCall (new CCodeIdentifier ("G_UNLIKELY"));
+                               (cond as CCodeFunctionCall).add_argument (condition);
+                       }
+                       var cif = new CCodeIfStatement (cond, type_init);
                        type_block.add_statement (cif);
                } else {
                        type_block = type_init;