]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
correct takes_ownership in arrays add limited support for array length
authorJürg Billeter <j@bitron.ch>
Wed, 4 Oct 2006 22:00:37 +0000 (22:00 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Wed, 4 Oct 2006 22:00:37 +0000 (22:00 +0000)
2006-10-04  Jürg Billeter  <j@bitron.ch>

* vala/valasymbolresolver.vala: correct takes_ownership in arrays
* vala/valacodegenerator.vala: add limited support for array length
  fields, store array length from array creation expression, copy array
  length in array assignments
* vala/valafield.vala: support NoArrayLength attribute
* compiler/valacompiler.vala: add NoArrayLength attribute to option
  arrays

svn path=/trunk/; revision=140

vala/ChangeLog
vala/compiler/valacompiler.vala
vala/vala/valacodegenerator.vala
vala/vala/valafield.vala
vala/vala/valasymbolresolver.vala

index 39f421795b1e52ead07f43fd16d3916dca7bc860..5c8794cafbb2acf2d6f0557e20ccff9caf1aee86 100644 (file)
@@ -1,3 +1,13 @@
+2006-10-04  Jürg Billeter  <j@bitron.ch>
+
+       * vala/valasymbolresolver.vala: correct takes_ownership in arrays
+       * vala/valacodegenerator.vala: add limited support for array length
+         fields, store array length from array creation expression, copy array
+         length in array assignments
+       * vala/valafield.vala: support NoArrayLength attribute
+       * compiler/valacompiler.vala: add NoArrayLength attribute to option
+         arrays
+
 2006-10-04  Jürg Billeter  <j@bitron.ch>
 
        * vala/valasymbolresolver.vala, vala/valasemanticanalyzer.vala: specify
index f145c9620a8dba4f89cd21aa347fefd45e99274b..87a68699834037fcef0b7eded9c88cc9c425e02a 100644 (file)
@@ -25,9 +25,12 @@ using GLib;
 class Vala.Compiler {
        static string directory;
        static bool version;
+       [NoArrayLength ()]
        static string[] sources;
+       [NoArrayLength ()]
        static string[] vapi_directories;
        static string library;
+       [NoArrayLength ()]
        static string[] packages;
        static bool disable_memory_management;
 
index 17ce907b781cf5bcb5a1aa83c324867ebdb14cf3..93415cf0a2027776d5331a1b4d2ac218b050d4c0 100644 (file)
@@ -908,15 +908,16 @@ public class Vala.CodeGenerator : CodeVisitor {
        
        public override void visit_field (Field! f) {
                CCodeExpression lhs = null;
+               CCodeStruct st = null;
                
                if (f.access != MemberAccessibility.PRIVATE) {
-                       instance_struct.add_field (f.type_reference.get_cname (), f.get_cname ());
+                       st = instance_struct;
                        if (f.instance) {
                                lhs = new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), f.get_cname ());
                        }
                } else if (f.access == MemberAccessibility.PRIVATE) {
                        if (f.instance) {
-                               instance_priv_struct.add_field (f.type_reference.get_cname (), f.get_cname ());
+                               st = instance_priv_struct;
                                lhs = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), f.get_cname ());
                        } else {
                                if (f.symbol.parent_symbol.node is DataType) {
@@ -934,8 +935,32 @@ public class Vala.CodeGenerator : CodeVisitor {
                }
 
                if (f.instance)  {
+                       st.add_field (f.type_reference.get_cname (), f.get_cname ());
+                       if (f.type_reference.data_type is Array && !f.no_array_length) {
+                               // create fields to store array dimensions
+                               var arr = (Array) f.type_reference.data_type;
+                               
+                               for (int dim = 1; dim <= arr.rank; dim++) {
+                                       var len_type = new TypeReference ();
+                                       len_type.data_type = int_type.data_type;
+
+                                       st.add_field (len_type.get_cname (), get_array_length_cname (f.name, dim));
+                               }
+                       }
+
                        if (f.initializer != null) {
                                instance_init_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (lhs, (CCodeExpression) f.initializer.ccodenode)));
+                               
+                               if (f.type_reference.data_type is Array && !f.no_array_length &&
+                                   f.initializer is ArrayCreationExpression) {
+                                       var ma = new MemberAccess.simple (f.name);
+                                       ma.symbol_reference = f.symbol;
+                                       
+                                       var array_len_lhs = get_array_length_cexpression (ma, 1);
+                                       var sizes = ((ArrayCreationExpression) f.initializer).get_sizes ();
+                                       var size = (Expression) sizes.data;
+                                       instance_init_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (array_len_lhs, (CCodeExpression) size.ccodenode)));
+                               }
                        }
                        
                        if (f.type_reference.takes_ownership) {
@@ -2257,7 +2282,11 @@ public class Vala.CodeGenerator : CodeVisitor {
                        }
                }
                
-               if (array_expr.symbol_reference != null) {
+               if (array_expr is ArrayCreationExpression) {
+                       var size = ((ArrayCreationExpression) array_expr).get_sizes ();
+                       var length_expr = (Expression) size.nth_data (dim - 1);
+                       return (CCodeExpression) length_expr.ccodenode;
+               } else if (array_expr.symbol_reference != null) {
                        if (array_expr.symbol_reference.node is FormalParameter) {
                                var param = (FormalParameter) array_expr.symbol_reference.node;
                                if (!param.no_array_length) {
@@ -2276,6 +2305,62 @@ public class Vala.CodeGenerator : CodeVisitor {
                                } else {
                                        return length_expr;
                                }
+                       } else if (array_expr.symbol_reference.node is Field) {
+                               var field = (Field) array_expr.symbol_reference.node;
+                               if (!field.no_array_length) {
+                                       var length_cname = get_array_length_cname (field.name, dim);
+
+                                       var ma = (MemberAccess) array_expr;
+
+                                       CCodeExpression pub_inst = null;
+                                       DataType base_type = null;
+                                       CCodeExpression length_expr = null;
+                               
+                                       if (ma.inner == null) {
+                                               pub_inst = new CCodeIdentifier ("self");
+
+                                               if (current_type_symbol != null) {
+                                                       /* base type is available if this is a type method */
+                                                       base_type = (DataType) current_type_symbol.node;
+                                               }
+                                       } else {
+                                               pub_inst = (CCodeExpression) ma.inner.ccodenode;
+
+                                               if (ma.inner.static_type != null) {
+                                                       base_type = ma.inner.static_type.data_type;
+                                               }
+                                       }
+
+                                       if (field.instance) {
+                                               ref CCodeExpression typed_inst;
+                                               if (field.symbol.parent_symbol.node != base_type) {
+                                                       // FIXME: use C cast if debugging disabled
+                                                       typed_inst = new CCodeFunctionCall (new CCodeIdentifier (((DataType) field.symbol.parent_symbol.node).get_upper_case_cname (null)));
+                                                       ((CCodeFunctionCall) typed_inst).add_argument (pub_inst);
+                                               } else {
+                                                       typed_inst = pub_inst;
+                                               }
+                                               ref CCodeExpression inst;
+                                               if (field.access == MemberAccessibility.PRIVATE) {
+                                                       inst = new CCodeMemberAccess.pointer (typed_inst, "priv");
+                                               } else {
+                                                       inst = typed_inst;
+                                               }
+                                               if (((DataType) field.symbol.parent_symbol.node).is_reference_type ()) {
+                                                       length_expr = new CCodeMemberAccess.pointer (inst, length_cname);
+                                               } else {
+                                                       length_expr = new CCodeMemberAccess (inst, length_cname);
+                                               }
+                                       } else {
+                                               length_expr = new CCodeIdentifier (length_cname);
+                                       }
+
+                                       if (is_out) {
+                                               return new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, length_expr);
+                                       } else {
+                                               return length_expr;
+                                       }
+                               }
                        }
                }
                
@@ -2895,14 +2980,29 @@ public class Vala.CodeGenerator : CodeVisitor {
                                rhs = ccast;
                        }
                        
-                       if (memory_management && a.left.static_type.takes_ownership) {
-                               /* unref old value */
+                       bool unref_old = (memory_management && a.left.static_type.takes_ownership);
+                       bool array = false;
+                       if (a.left.static_type.data_type is Array) {
+                               array = !(get_array_length_cexpression (a.left, 1) is CCodeConstant);
+                       }
+                       
+                       if (unref_old || array) {
                                var ccomma = new CCodeCommaExpression ();
                                
                                var temp_decl = get_temp_variable_declarator (a.left.static_type);
                                temp_vars.prepend (temp_decl);
                                ccomma.append_expression (new CCodeAssignment (new CCodeIdentifier (temp_decl.name), rhs));
-                               ccomma.append_expression (get_unref_expression ((CCodeExpression) a.left.ccodenode, a.left.static_type));
+                               if (unref_old) {
+                                       /* unref old value */
+                                       ccomma.append_expression (get_unref_expression ((CCodeExpression) a.left.ccodenode, a.left.static_type));
+                               }
+                               
+                               if (array) {
+                                       var lhs_array_len = get_array_length_cexpression (a.left, 1);
+                                       var rhs_array_len = get_array_length_cexpression (a.right, 1);
+                                       ccomma.append_expression (new CCodeAssignment (lhs_array_len, rhs_array_len));
+                               }
+                               
                                ccomma.append_expression (new CCodeIdentifier (temp_decl.name));
                                
                                rhs = ccomma;
index f8c71a4c9f73b454033ce589d3d357953b760506..c48611e0d83b421dd0d220852b18cb472e02205b 100644 (file)
@@ -61,6 +61,12 @@ public class Vala.Field : Member, Invokable, Lockable {
                        _instance = value;
                }
        }
+       
+       /**
+        * Specifies whether an array length field should implicitly be created
+        * if the field type is an array.
+        */
+       public bool no_array_length { get; set; }
 
        private string cname;
        private bool _instance = true;
@@ -137,6 +143,8 @@ public class Vala.Field : Member, Invokable, Lockable {
                foreach (Attribute a in attributes) {
                        if (a.name == "CCode") {
                                process_ccode_attribute (a);
+                       } else if (a.name == "NoArrayLength") {
+                               no_array_length = true;
                        }
                }
        }
index 1d27696fa698701ed310bbbe00a1e5e05004d585..71cfc0343bf28174249002b2877006e01d034081 100644 (file)
@@ -181,21 +181,23 @@ public class Vala.SymbolResolver : CodeVisitor {
                        type.data_type = (DataType) sym.node;
                }
                
-               if (type.data_type != null && !type.data_type.is_reference_type ()) {
-                       /* reset takes_ownership of value-types for contexts
-                        * where types are ref by default (field declarations)
-                        */
-                       type.takes_ownership = false;
-               }
-               
                /* check for array */
                if (type.array_rank > 0) {
                        var element_type = new TypeReference ();
                        element_type.data_type = type.data_type;
-                       element_type.takes_ownership = true;
+                       if (type.data_type != null && type.data_type.is_reference_type ()) {
+                               element_type.takes_ownership = true;
+                       }
                        
                        type.data_type = type.data_type.get_array (type.array_rank);
                        type.add_type_argument (element_type);
                }
+               
+               if (type.data_type != null && !type.data_type.is_reference_type ()) {
+                       /* reset takes_ownership of value-types for contexts
+                        * where types are ref by default (field declarations)
+                        */
+                       type.takes_ownership = false;
+               }
        }
 }