From: Marc-André Lureau Date: Tue, 26 Jan 2010 00:47:55 +0000 (+0100) Subject: Use TypeRegisterFunction for enum/flags X-Git-Tag: 0.8.0~92 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=240a80c90136272b5d56e538c19ae443a9ba8c70;p=thirdparty%2Fvala.git Use TypeRegisterFunction for enum/flags Fixes bug 592904. --- diff --git a/codegen/Makefile.am b/codegen/Makefile.am index b672c2784..8a452b268 100644 --- a/codegen/Makefile.am +++ b/codegen/Makefile.am @@ -34,6 +34,7 @@ libvala_la_VALASOURCES = \ valadbusinterfaceregisterfunction.vala \ valadbusmodule.vala \ valadbusservermodule.vala \ + valaenumregisterfunction.vala \ valagerrormodule.vala \ valagirwriter.vala \ valagobjectmodule.vala \ diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 1beb9fa08..ea136b213 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -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 index 000000000..e54098c76 --- /dev/null +++ b/codegen/valaenumregisterfunction.vala @@ -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 + */ + +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 (); + } +} diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala index 7353e6670..152fcae54 100644 --- a/codegen/valagtypemodule.vala +++ b/codegen/valagtypemodule.vala @@ -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; diff --git a/codegen/valastructregisterfunction.vala b/codegen/valastructregisterfunction.vala index 1f79fdb47..2684b48b5 100644 --- a/codegen/valastructregisterfunction.vala +++ b/codegen/valastructregisterfunction.vala @@ -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; diff --git a/codegen/valatyperegisterfunction.vala b/codegen/valatyperegisterfunction.vala index 571bca64a..b56f1593e 100644 --- a/codegen/valatyperegisterfunction.vala +++ b/codegen/valatyperegisterfunction.vala @@ -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;