diff options
author | Juerg Billeter <j@bitron.ch> | 2007-09-15 19:44:20 +0000 |
---|---|---|
committer | Jürg Billeter <juergbi@src.gnome.org> | 2007-09-15 19:44:20 +0000 |
commit | 087945bcf71247fbba63bd92cc232c8e0d009b8a (patch) | |
tree | 1c7e040cc20d390ab15b53980f6cf92fbc15d6ad /gobject | |
parent | 6f39dba7f628a22986961cd37c572f870bd9f79c (diff) | |
download | vala-087945bcf71247fbba63bd92cc232c8e0d009b8a.tar.gz |
support creation methods in structs, replace InstanceByReference method
2007-09-15 Juerg Billeter <j@bitron.ch>
* vala/valainterfacewriter.vala, vala/valamethod.vala,
vala/valasemanticanalyzer.vala, vala/valastruct.vala,
gobject/valacodegenerator.vala,
gobject/valacodegeneratorinvocationexpression.vala,
gobject/valacodegeneratormethod.vala, vapigen/valagidlparser.vala,
vapi/glib-2.0.vala: support creation methods in structs, replace
InstanceByReference method attribute by SimpleType type attribute
(inverse effect)
* tests/Makefile.am, tests/structs.exp, tests/structs.vala: add struct
declaration test
* vapi/gdk-2.0.vala, vapi/gtk+-2.0.vala, vapi/pango.vala: regenerated
svn path=/trunk/; revision=608
Diffstat (limited to 'gobject')
-rw-r--r-- | gobject/valacodegenerator.vala | 88 | ||||
-rw-r--r-- | gobject/valacodegeneratorinvocationexpression.vala | 7 | ||||
-rw-r--r-- | gobject/valacodegeneratormethod.vala | 25 |
3 files changed, 71 insertions, 49 deletions
diff --git a/gobject/valacodegenerator.vala b/gobject/valacodegenerator.vala index c9d572a1b..3c8b0befe 100644 --- a/gobject/valacodegenerator.vala +++ b/gobject/valacodegenerator.vala @@ -2408,44 +2408,58 @@ public class Vala.CodeGenerator : CodeVisitor { } public override void visit_end_object_creation_expression (ObjectCreationExpression! expr) { + CCodeExpression struct_instance = null; + CCodeFunctionCall creation_call = null; + + if (expr.type_reference.data_type is Struct) { + // value-type initialization + var temp_decl = get_temp_variable_declarator (expr.type_reference, false, expr); + temp_vars.add (temp_decl); + + struct_instance = new CCodeIdentifier (get_variable_cname (temp_decl.name)); + } + if (expr.symbol_reference == null) { // no creation method if (expr.type_reference.data_type == glist_type || - expr.type_reference.data_type == gslist_type) { + expr.type_reference.data_type == gslist_type) { // NULL is an empty list expr.ccodenode = new CCodeConstant ("NULL"); } else if (expr.type_reference.data_type is Class && expr.type_reference.data_type.is_subtype_of (gobject_type)) { - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_object_new")); - - ccall.add_argument (new CCodeConstant (expr.type_reference.data_type.get_type_id ())); - - ccall.add_argument (new CCodeConstant ("NULL")); - - expr.ccodenode = ccall; - } else { - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_new0")); - - ccall.add_argument (new CCodeConstant (expr.type_reference.data_type.get_cname ())); - - ccall.add_argument (new CCodeConstant ("1")); - - expr.ccodenode = ccall; + creation_call = new CCodeFunctionCall (new CCodeIdentifier ("g_object_new")); + creation_call.add_argument (new CCodeConstant (expr.type_reference.data_type.get_type_id ())); + creation_call.add_argument (new CCodeConstant ("NULL")); + } else if (expr.type_reference.data_type is Class) { + creation_call = new CCodeFunctionCall (new CCodeIdentifier ("g_new0")); + creation_call.add_argument (new CCodeConstant (expr.type_reference.data_type.get_cname ())); + creation_call.add_argument (new CCodeConstant ("1")); + } else if (expr.type_reference.data_type is Struct) { + // memset needs string.h + string_h_needed = true; + creation_call = new CCodeFunctionCall (new CCodeIdentifier ("memset")); + creation_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, struct_instance)); + creation_call.add_argument (new CCodeConstant ("0")); + creation_call.add_argument (new CCodeIdentifier ("sizeof (%s)".printf (expr.type_reference.get_cname ()))); } } else if (expr.symbol_reference is Method) { // use creation method var m = (Method) expr.symbol_reference; var params = m.get_parameters (); - var ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_cname ())); + creation_call = new CCodeFunctionCall (new CCodeIdentifier (m.get_cname ())); + + if (struct_instance != null) { + creation_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, struct_instance)); + } if (expr.type_reference.data_type is Class && expr.type_reference.data_type.is_subtype_of (gobject_type)) { foreach (TypeReference type_arg in expr.type_reference.get_type_arguments ()) { if (type_arg.takes_ownership) { - ccall.add_argument (get_dup_func_expression (type_arg)); - ccall.add_argument (get_destroy_func_expression (type_arg)); + creation_call.add_argument (get_dup_func_expression (type_arg)); + creation_call.add_argument (get_destroy_func_expression (type_arg)); } else { - ccall.add_argument (new CCodeConstant ("NULL")); - ccall.add_argument (new CCodeConstant ("NULL")); + creation_call.add_argument (new CCodeConstant ("NULL")); + creation_call.add_argument (new CCodeConstant ("NULL")); } } } @@ -2464,7 +2478,7 @@ public class Vala.CodeGenerator : CodeVisitor { } } - ccall.add_argument (cexpr); + creation_call.add_argument (cexpr); i++; } while (params_it.next ()) { @@ -2485,41 +2499,47 @@ public class Vala.CodeGenerator : CodeVisitor { * parameter yet */ param.default_expression.accept (this); - ccall.add_argument ((CCodeExpression) param.default_expression.ccodenode); + creation_call.add_argument ((CCodeExpression) param.default_expression.ccodenode); i++; } if (expr.can_fail) { // method can fail current_method_inner_error = true; - ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("inner_error"))); + creation_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("inner_error"))); } if (ellipsis) { // ensure variable argument list ends with NULL - ccall.add_argument (new CCodeConstant ("NULL")); + creation_call.add_argument (new CCodeConstant ("NULL")); } - - expr.ccodenode = ccall; } else if (expr.symbol_reference is EnumValue) { // error code var ev = (EnumValue) expr.symbol_reference; var en = (Enum) ev.parent_symbol; - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_set_error")); - ccall.add_argument (new CCodeIdentifier ("error")); - ccall.add_argument (new CCodeIdentifier (en.get_upper_case_cname ())); - ccall.add_argument (new CCodeIdentifier (ev.get_cname ())); + creation_call = new CCodeFunctionCall (new CCodeIdentifier ("g_set_error")); + creation_call.add_argument (new CCodeIdentifier ("error")); + creation_call.add_argument (new CCodeIdentifier (en.get_upper_case_cname ())); + creation_call.add_argument (new CCodeIdentifier (ev.get_cname ())); foreach (Expression arg in expr.get_argument_list ()) { - ccall.add_argument ((CCodeExpression) arg.ccodenode); + creation_call.add_argument ((CCodeExpression) arg.ccodenode); } - - expr.ccodenode = ccall; } else { assert (false); } + if (expr.type_reference.data_type is Struct) { + var ccomma = new CCodeCommaExpression (); + ccomma.append_expression (creation_call); + ccomma.append_expression (struct_instance); + + expr.ccodenode = ccomma; + } else if (creation_call != null) { + expr.ccodenode = creation_call; + } + visit_expression (expr); } diff --git a/gobject/valacodegeneratorinvocationexpression.vala b/gobject/valacodegeneratorinvocationexpression.vala index 77e309e1d..3f6e2f4bc 100644 --- a/gobject/valacodegeneratorinvocationexpression.vala +++ b/gobject/valacodegeneratorinvocationexpression.vala @@ -56,10 +56,7 @@ public class Vala.CodeGenerator { } else if (m is ArrayMoveMethod) { requires_array_move = true; } - - /* explicitly use strong reference as ccall gets unrefed - * at end of inner block - */ + CCodeExpression instance; if (m != null && m.instance) { var base_method = m; @@ -79,7 +76,7 @@ public class Vala.CodeGenerator { instance_expression_type = ma.inner.static_type; } - if (m.instance_by_reference && (ma.inner != null || m.parent_symbol != current_type_symbol)) { + if (m.parent_symbol is Struct && !((Struct) m.parent_symbol).is_simple_type () && (ma.inner != null || m.parent_symbol != current_type_symbol)) { instance = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, instance); } diff --git a/gobject/valacodegeneratormethod.vala b/gobject/valacodegeneratormethod.vala index a0399d7e7..9d69adc59 100644 --- a/gobject/valacodegeneratormethod.vala +++ b/gobject/valacodegeneratormethod.vala @@ -99,7 +99,7 @@ public class Vala.CodeGenerator { CCodeFormalParameter instance_param = null; - if (m.instance) { + if (m.instance || (m.parent_symbol is Struct && m is CreationMethod)) { var this_type = new TypeReference (); this_type.data_type = find_parent_type (m); if (m.base_interface_method != null) { @@ -111,7 +111,7 @@ public class Vala.CodeGenerator { base_type.data_type = (DataType) m.base_method.parent_symbol; instance_param = new CCodeFormalParameter ("base", base_type.get_cname ()); } else { - if (m.instance_by_reference) { + if (m.parent_symbol is Struct && !((Struct) m.parent_symbol).is_simple_type ()) { instance_param = new CCodeFormalParameter ("*self", this_type.get_cname ()); } else { instance_param = new CCodeFormalParameter ("self", this_type.get_cname ()); @@ -308,11 +308,14 @@ public class Vala.CodeGenerator { cinit.append (cdecl); } else { var st = (Struct) m.parent_symbol; - var cdecl = new CCodeDeclaration (st.get_cname () + "*"); - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_new0")); - ccall.add_argument (new CCodeIdentifier (st.get_cname ())); - cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("self", ccall)); - cinit.append (cdecl); + + // memset needs string.h + string_h_needed = true; + var czero = new CCodeFunctionCall (new CCodeIdentifier ("memset")); + czero.add_argument (new CCodeIdentifier ("self")); + czero.add_argument (new CCodeConstant ("0")); + czero.add_argument (new CCodeIdentifier ("sizeof (%s)".printf (st.get_cname ()))); + cinit.append (new CCodeExpressionStatement (czero)); } } @@ -428,9 +431,11 @@ public class Vala.CodeGenerator { function.block.add_statement (new CCodeExpressionStatement (cfreeparams)); } - var creturn = new CCodeReturnStatement (); - creturn.return_expression = new CCodeIdentifier ("self"); - function.block.add_statement (creturn); + if (current_type_symbol is Class) { + var creturn = new CCodeReturnStatement (); + creturn.return_expression = new CCodeIdentifier ("self"); + function.block.add_statement (creturn); + } } bool return_value = true; |