update to be compatible with new pointer types
authorJuerg Billeter <j@bitron.ch>
Sat, 15 Dec 2007 11:54:52 +0000 (11:54 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Sat, 15 Dec 2007 11:54:52 +0000 (11:54 +0000)
2007-12-15  Juerg Billeter  <j@bitron.ch>

* gee/hashmap.vala, gee/hashset.vala: update to be compatible with new
  pointer types

* vala/parser.y, vala/vala.h, vala/valaclass.vala,
  vala/valadatatype.vala, vala/valamemorymanager.vala,
  vala/valanulltype.vala, vala/valapointertype.vala,
  vala/valasemanticanalyzer.vala, vala/valasymbolresolver.vala,
  vala/valavoidtype.vala, gobject/valaccodegenerator.vala,
  gobject/valaccodegeneratormethod.vala: use PointerType

svn path=/trunk/; revision=774

15 files changed:
ChangeLog
gee/hashmap.vala
gee/hashset.vala
gobject/valaccodegenerator.vala
gobject/valaccodegeneratormethod.vala
vala/parser.y
vala/vala.h
vala/valaclass.vala
vala/valadatatype.vala
vala/valamemorymanager.vala
vala/valanulltype.vala
vala/valapointertype.vala
vala/valasemanticanalyzer.vala
vala/valasymbolresolver.vala
vala/valavoidtype.vala

index 5527f11..15c8da3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
 2007-12-15  Jürg Billeter  <j@bitron.ch>
 
+       * gee/hashmap.vala, gee/hashset.vala: update to be compatible with new
+         pointer types
+
+       * vala/parser.y, vala/vala.h, vala/valaclass.vala,
+         vala/valadatatype.vala, vala/valamemorymanager.vala,
+         vala/valanulltype.vala, vala/valapointertype.vala,
+         vala/valasemanticanalyzer.vala, vala/valasymbolresolver.vala,
+         vala/valavoidtype.vala, gobject/valaccodegenerator.vala,
+         gobject/valaccodegeneratormethod.vala: use PointerType
+
+2007-12-15  Jürg Billeter  <j@bitron.ch>
+
        * vala/Makefile.am, vala/valaarraytype.vala, vala/valaclass.vala,
          vala/valaclasstype.vala, vala/valainterface.vala,
          vala/valainterfacetype.vala, vala/valareferencetype.vala,
index 3557199..c6b3377 100644 (file)
@@ -74,22 +74,22 @@ public class Gee.HashMap<K,V> : Object, Map<K,V> {
                return new ValueCollection<K,V> (this);
        }
 
-       private Node<K,V>* lookup_node (K key) {
+       private Node<K,V>** lookup_node (K key) {
                uint hash_value = _key_hash_func (key);
-               Node<K,V>* node = &_nodes[hash_value % _array_size];
-               while ((*node) != null && (hash_value != (*node).key_hash || !_key_equal_func ((*node).key, key))) {
-                       node = &((*node).next);
+               Node<K,V>** node = &_nodes[hash_value % _array_size];
+               while ((*node) != null && (hash_value != ((Node<K,V>) (*node)).key_hash || !_key_equal_func (((Node<K,V>) (*node)).key, key))) {
+                       node = &(((Node<K,V>) (*node)).next);
                }
                return node;
        }
 
        public bool contains (K key) {
-               Node<K,V>* node = lookup_node (key);
+               Node<K,V>** node = lookup_node (key);
                return (*node != null);
        }
 
        public V get (K key) {
-               weak Node<K,V> node = *lookup_node (key);
+               weak Node<K,V> node = (Node<K,V>) (*lookup_node (key));
                if (node != null) {
                        return node.value;
                } else {
@@ -98,9 +98,9 @@ public class Gee.HashMap<K,V> : Object, Map<K,V> {
        }
 
        public void set (K key, V value) {
-               Node<K,V>* node = lookup_node (key);
+               Node<K,V>** node = lookup_node (key);
                if (*node != null) {
-                       (*node).value = value;
+                       ((Node<K,V>) (*node)).value = value;
                } else {
                        uint hash_value = _key_hash_func (key);
                        *node = new Node<K,V> (key, value, hash_value);
@@ -111,11 +111,11 @@ public class Gee.HashMap<K,V> : Object, Map<K,V> {
        }
 
        public bool remove (K key) {
-               Node<K,V>* node = lookup_node (key);
+               Node<K,V>** node = lookup_node (key);
                if (*node != null) {
-                       (*node).key = null;
-                       (*node).value = null;
-                       *node = (*node).next;
+                       ((Node<K,V>) (*node)).key = null;
+                       ((Node<K,V>) (*node)).value = null;
+                       *node = ((Node<K,V>) (*node)).next;
                        _nnodes--;
                        resize ();
                        _stamp++;
index b901c7f..a01b810 100644 (file)
@@ -61,17 +61,17 @@ public class Gee.HashSet<G> : Object, Iterable<G>, Collection<G>, Set<G> {
                _nodes = new Node<G>[_array_size];
        }
 
-       private Node<G>* lookup_node (G key) {
+       private Node<G>** lookup_node (G key) {
                uint hash_value = _hash_func (key);
-               Node<G>* node = &_nodes[hash_value % _array_size];
-               while ((*node) != null && (hash_value != (*node).key_hash || !_equal_func ((*node).key, key))) {
-                       node = &((*node).next);
+               Node<G>** node = &_nodes[hash_value % _array_size];
+               while ((*node) != null && (hash_value != ((Node<G>) (*node)).key_hash || !_equal_func (((Node<G>) (*node)).key, key))) {
+                       node = &(((Node<G>) (*node)).next);
                }
                return node;
        }
 
        public bool contains (G key) {
-               Node<G>* node = lookup_node (key);
+               Node<G>** node = lookup_node (key);
                return (*node != null);
        }
 
@@ -80,7 +80,7 @@ public class Gee.HashSet<G> : Object, Iterable<G>, Collection<G>, Set<G> {
        }
 
        public bool add (G key) {
-               Node<G>* node = lookup_node (key);
+               Node<G>** node = lookup_node (key);
                if (*node != null) {
                        return false;
                } else {
@@ -94,10 +94,10 @@ public class Gee.HashSet<G> : Object, Iterable<G>, Collection<G>, Set<G> {
        }
 
        public bool remove (G key) {
-               Node<G>* node = lookup_node (key);
+               Node<G>** node = lookup_node (key);
                if (*node != null) {
-                       (*node).key = null;
-                       *node = (*node).next;
+                       ((Node<G>) (*node)).key = null;
+                       *node = ((Node<G>) (*node)).next;
                        _nnodes--;
                        resize ();
                        _stamp++;
index 0d61f3f..84e85ba 100644 (file)
@@ -1206,7 +1206,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
                        cerror_block.add_statement (new CCodeExpressionStatement (cpropagate));
 
                        if (current_return_type != null && current_return_type.data_type != null) {
-                               cerror_block.add_statement (new CCodeReturnStatement (default_value_for_type (current_return_type.data_type)));
+                               cerror_block.add_statement (new CCodeReturnStatement (default_value_for_type (current_return_type)));
                        } else {
                                cerror_block.add_statement (new CCodeReturnStatement ());
                        }
@@ -1913,7 +1913,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
                temp_ref_vars.clear ();
 
                if (current_return_type != null && current_return_type.data_type != null) {
-                       cfrag.append (new CCodeReturnStatement (default_value_for_type (current_return_type.data_type)));
+                       cfrag.append (new CCodeReturnStatement (default_value_for_type (current_return_type)));
                } else {
                        cfrag.append (new CCodeReturnStatement ());
                }
@@ -2746,9 +2746,9 @@ public class Vala.CCodeGenerator : CodeGenerator {
                        return cexpr;
                }
 
-               if (context.checking && target_type.data_type.is_subtype_of (gtypeinstance_type)) {
+               if (context.checking && target_type.data_type != null && target_type.data_type.is_subtype_of (gtypeinstance_type)) {
                        return new InstanceCast (cexpr, target_type.data_type);
-               } else if (target_type.data_type.is_reference_type () && expression_type.get_cname () != target_type.get_cname ()) {
+               } else if (target_type.data_type != null && target_type.data_type.is_reference_type () && expression_type.get_cname () != target_type.get_cname ()) {
                        return new CCodeCastExpression (cexpr, target_type.get_cname ());
                } else {
                        return cexpr;
index 6d643ad..981d510 100644 (file)
@@ -541,18 +541,18 @@ public class Vala.CCodeGenerator {
        }
        
        private CCodeStatement create_method_type_check_statement (Method! m, DataType! return_type, Typesymbol! t, bool non_null, string! var_name) {
-               return create_type_check_statement (m, return_type.data_type, t, non_null, var_name);
+               return create_type_check_statement (m, return_type, t, non_null, var_name);
        }
        
        private CCodeStatement create_property_type_check_statement (Property! prop, bool getter, Typesymbol! t, bool non_null, string! var_name) {
                if (getter) {
-                       return create_type_check_statement (prop, prop.type_reference.data_type, t, non_null, var_name);
+                       return create_type_check_statement (prop, prop.type_reference, t, non_null, var_name);
                } else {
-                       return create_type_check_statement (prop, null, t, non_null, var_name);
+                       return create_type_check_statement (prop, new VoidType (), t, non_null, var_name);
                }
        }
        
-       private CCodeStatement create_type_check_statement (CodeNode! method_node, Typesymbol ret_type, Typesymbol! t, bool non_null, string! var_name) {
+       private CCodeStatement create_type_check_statement (CodeNode! method_node, DataType ret_type, Typesymbol! t, bool non_null, string! var_name) {
                var ccheck = new CCodeFunctionCall ();
                
                if ((t is Class && ((Class) t).is_subtype_of (gobject_type)) || (t is Interface && !((Interface) t).declaration_only)) {
@@ -573,7 +573,7 @@ public class Vala.CCodeGenerator {
                        ccheck.add_argument (cnonnull);
                }
                
-               if (ret_type == null) {
+               if (ret_type is VoidType) {
                        /* void function */
                        ccheck.call = new CCodeIdentifier ("g_return_if_fail");
                } else {
@@ -591,11 +591,11 @@ public class Vala.CCodeGenerator {
                return new CCodeExpressionStatement (ccheck);
        }
 
-       private CCodeExpression default_value_for_type (Typesymbol! type) {
-               if (type.is_reference_type () || type is Pointer) {
+       private CCodeExpression default_value_for_type (DataType! type) {
+               if ((type.data_type != null && type.data_type.is_reference_type ()) || type is PointerType || type.data_type is Pointer) {
                        return new CCodeConstant ("NULL");
-               } else if (type.get_default_value () != null) {
-                       return new CCodeConstant (type.get_default_value ());
+               } else if (type.data_type != null && type.data_type.get_default_value () != null) {
+                       return new CCodeConstant (type.data_type.get_default_value ());
                }
                return null;
        }
index d24ea2a..6c4eb7c 100644 (file)
@@ -566,6 +566,18 @@ type
          {
                $$ = VALA_DATA_TYPE (vala_void_type_new ());
          }
+       | VOID stars
+         {
+               int pointer_level;
+
+               $$ = VALA_DATA_TYPE (vala_void_type_new ());
+
+               for (pointer_level = $2; pointer_level > 0; pointer_level--) {
+                       ValaDataType *base_type = $$;
+                       $$ = VALA_DATA_TYPE (vala_pointer_type_new (base_type));
+                       g_object_unref (base_type);
+               }
+         }
        ;
 
 opt_argument_list
@@ -1854,6 +1866,25 @@ local_variable_type
                        vala_unresolved_type_set_non_null (VALA_UNRESOLVED_TYPE ($$), TRUE);
                }
          }
+       | VOID
+         {
+               ValaSourceReference *src = src(@1);
+               $$ = VALA_DATA_TYPE (vala_void_type_new ());
+               g_object_unref (src);
+         }
+       | VOID stars
+         {
+               int pointer_level;
+               ValaSourceReference *src = src(@1);
+               $$ = VALA_DATA_TYPE (vala_void_type_new ());
+               g_object_unref (src);
+
+               for (pointer_level = $2; pointer_level > 0; pointer_level--) {
+                       ValaDataType *base_type = $$;
+                       $$ = VALA_DATA_TYPE (vala_pointer_type_new (base_type));
+                       g_object_unref (base_type);
+               }
+         }
        ;
 
 opt_op_neg
@@ -2706,8 +2737,8 @@ class_member_declaration
          }
        | field_declaration
          {
-               /* skip declarations with errors */
-               if ($1 != NULL) {
+               /* skip declarations with errors */
+               if ($1 != NULL) {
                        vala_class_add_field (VALA_CLASS (symbol_stack->data), $1);
                        g_object_unref ($1);
                }
@@ -2777,12 +2808,14 @@ field_declaration
 
                src = src_com(@5, $1);
 
-               if (vala_unresolved_type_get_is_ref (VALA_UNRESOLVED_TYPE ($5)) || vala_unresolved_type_get_is_out (VALA_UNRESOLVED_TYPE ($5))) {
-                       vala_report_error (src, "`ref' and `out' may only be used for parameters.");
-               }
-               if (!vala_unresolved_type_get_is_weak (VALA_UNRESOLVED_TYPE ($5))) {
-                       vala_unresolved_type_set_takes_ownership (VALA_UNRESOLVED_TYPE ($5), TRUE);
-               }
+               if (VALA_IS_UNRESOLVED_TYPE ($5)) {
+                       if (vala_unresolved_type_get_is_ref (VALA_UNRESOLVED_TYPE ($5)) || vala_unresolved_type_get_is_out (VALA_UNRESOLVED_TYPE ($5))) {
+                               vala_report_error (src, "`ref' and `out' may only be used for parameters.");
+                       }
+                       if (!vala_unresolved_type_get_is_weak (VALA_UNRESOLVED_TYPE ($5))) {
+                               vala_unresolved_type_set_takes_ownership (VALA_UNRESOLVED_TYPE ($5), TRUE);
+                       }
+               }
 
                $$ = vala_code_context_create_field (context, vala_symbol_get_name (VALA_SYMBOL ($6)), $5, vala_variable_declarator_get_initializer ($6), src);
                g_object_unref (src);
index 40a2af0..2e242fd 100644 (file)
@@ -53,6 +53,7 @@
 #include <vala/valaparenthesizedexpression.h>
 #include <vala/valaparser.h>
 #include <vala/valapointerindirection.h>
+#include <vala/valapointertype.h>
 #include <vala/valapostfixexpression.h>
 #include <vala/valaproperty.h>
 #include <vala/valapropertyaccessor.h>
@@ -79,4 +80,5 @@
 #include <vala/valaunaryexpression.h>
 #include <vala/valaunresolvedtype.h>
 #include <vala/valavariabledeclarator.h>
+#include <vala/valavoidtype.h>
 #include <vala/valawhilestatement.h>
index 00f3fe0..935f16d 100644 (file)
@@ -164,8 +164,10 @@ public class Vala.Class : Typesymbol {
         * @param f a field
         */
        public void add_field (Field! f) {
-               // non_null fields not yet supported due to initialization issues
-               ((UnresolvedType) f.type_reference).non_null = false;
+               if (f.type_reference is UnresolvedType) {
+                       // non_null fields not yet supported due to initialization issues
+                       ((UnresolvedType) f.type_reference).non_null = false;
+               }
                fields.add (f);
                if (f.access == SymbolAccessibility.PRIVATE && f.instance) {
                        _has_private_fields = true;
index 9569db5..3d1acf2 100644 (file)
@@ -337,13 +337,14 @@ public class Vala.DataType : CodeNode {
                }
 
                /* only null is compatible to null */
-               if (target_type.data_type == null && target_type.type_parameter == null) {
-                       return (data_type == null && target_type.type_parameter == null);
+               if (!(target_type is PointerType) && target_type.data_type == null && target_type.type_parameter == null) {
+                       return (data_type == null && type_parameter == null);
                }
 
                if (data_type == null) {
                        /* null can be cast to any reference or array type or pointer type */
                        if (target_type.type_parameter != null ||
+                           target_type is PointerType ||
                            target_type.data_type.is_reference_type () ||
                            target_type.is_out ||
                            target_type.data_type is Pointer ||
@@ -357,7 +358,7 @@ public class Vala.DataType : CodeNode {
                        return false;
                }
 
-               if (target_type.data_type != null && target_type.data_type.get_attribute ("PointerType") != null) {
+               if (target_type is PointerType || (target_type.data_type != null && target_type.data_type.get_attribute ("PointerType") != null)) {
                        /* any reference or array type or pointer type can be cast to a generic pointer */
                        if (type_parameter != null ||
                                data_type.is_reference_type () ||
index 21fdf31..0af9c05 100644 (file)
@@ -78,10 +78,12 @@ public class Vala.MemoryManager : CodeVisitor {
 
        public override void visit_field (Field! f) {
                if (f.initializer != null) {
-                       if (f.type_reference.takes_ownership) {
-                               visit_possibly_missing_copy_expression (f.initializer);
-                       } else {
-                               visit_possibly_leaked_expression (f.initializer);
+                       if (!(f.type_reference is PointerType)) {
+                               if (f.type_reference.takes_ownership) {
+                                       visit_possibly_missing_copy_expression (f.initializer);
+                               } else {
+                                       visit_possibly_leaked_expression (f.initializer);
+                               }
                        }
                }
        }
@@ -129,10 +131,12 @@ public class Vala.MemoryManager : CodeVisitor {
                decl.accept_children (this);
 
                if (decl.initializer != null) {
-                       if (decl.type_reference.takes_ownership) {
-                               visit_possibly_missing_copy_expression (decl.initializer);
-                       } else {
-                               visit_possibly_leaked_expression (decl.initializer);
+                       if (!(decl.type_reference is PointerType)) {
+                               if (decl.type_reference.takes_ownership) {
+                                       visit_possibly_missing_copy_expression (decl.initializer);
+                               } else {
+                                       visit_possibly_leaked_expression (decl.initializer);
+                               }
                        }
                }
        }
@@ -160,10 +164,12 @@ public class Vala.MemoryManager : CodeVisitor {
                        if (current_symbol is Method) {
                                var m = (Method) current_symbol;
                                
-                               if (m.return_type.transfers_ownership) {
-                                       visit_possibly_missing_copy_expression (stmt.return_expression);
-                               } else {
-                                       visit_possibly_leaked_expression (stmt.return_expression);
+                               if (!(m.return_type is PointerType)) {
+                                       if (m.return_type.transfers_ownership) {
+                                               visit_possibly_missing_copy_expression (stmt.return_expression);
+                                       } else {
+                                               visit_possibly_leaked_expression (stmt.return_expression);
+                                       }
                                }
                        } else {
                                /* property get accessor */
@@ -287,10 +293,12 @@ public class Vala.MemoryManager : CodeVisitor {
 
                if (a.left is PointerIndirection || a.left.symbol_reference is Signal) {
                } else {
-                       if (a.left.static_type.takes_ownership) {
-                               visit_possibly_missing_copy_expression (a.right);
-                       } else {
-                               visit_possibly_leaked_expression (a.right);
+                       if (!(a.left.static_type is PointerType)) {
+                               if (a.left.static_type.takes_ownership) {
+                                       visit_possibly_missing_copy_expression (a.right);
+                               } else {
+                                       visit_possibly_leaked_expression (a.right);
+                               }
                        }
                }
        }
index 2efbaaa..3be0201 100644 (file)
@@ -28,4 +28,25 @@ using GLib;
 public class Vala.NullType : ReferenceType {
        public NullType () {
        }
+
+       public override bool compatible (DataType! target_type) {
+               if (!(target_type is PointerType) && (target_type is NullType || (target_type.data_type == null && target_type.type_parameter == null))) {
+                       return true;
+               }
+
+               /* null can be cast to any reference or array type or pointer type */
+               if (target_type.type_parameter != null ||
+                   target_type is PointerType ||
+                   target_type.data_type.is_reference_type () ||
+                   target_type.is_out ||
+                   target_type.data_type is Pointer ||
+                   target_type.data_type is Array ||
+                   target_type.data_type is Callback ||
+                   target_type.data_type.get_attribute ("PointerType") != null) {
+                       return true;
+               }
+
+               /* null is not compatible with any other type (i.e. value types) */
+               return false;
+       }
 }
index f8cf00a..9851a2a 100644 (file)
@@ -29,8 +29,37 @@ public class Vala.PointerType : DataType {
        /**
         * The base type the pointer is referring to.
         */
-       public weak DataType base_type { get; set; }
+       public DataType base_type { get; set; }
 
        public PointerType (construct DataType! base_type) {
        }
+
+       public override string! to_string () {
+               return base_type.to_string () + "*";
+       }
+
+       public override string get_cname (bool var_type = false, bool const_type = false) {
+               if (base_type.data_type != null && base_type.data_type.is_reference_type ()) {
+                       return base_type.get_cname (var_type, const_type);
+               } else {
+                       return base_type.get_cname (var_type, const_type) + "*";
+               }
+       }
+
+       public override DataType! copy () {
+               return new PointerType (base_type);
+       }
+
+       public override bool compatible (DataType! target_type) {
+               if (target_type is PointerType || (target_type.data_type != null && target_type.data_type.get_attribute ("PointerType") != null)) {
+                       return true;
+               }
+
+               /* temporarily ignore type parameters */
+               if (target_type.type_parameter != null) {
+                       return true;
+               }
+
+               return false;
+       }
 }
index 9f8bb55..6baf0bc 100644 (file)
@@ -708,7 +708,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        if (memory_management) {
                                if (decl.initializer.static_type.transfers_ownership) {
                                        /* rhs transfers ownership of the expression */
-                                       if (!decl.type_reference.takes_ownership) {
+                                       if (!(decl.type_reference is PointerType) && !decl.type_reference.takes_ownership) {
                                                /* lhs doesn't own the value */
                                                decl.error = true;
                                                Report.error (decl.source_reference, "Invalid assignment from owned expression to unowned variable");
@@ -942,15 +942,13 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        return;
                }
 
-               if (stmt.return_expression == null && current_return_type.data_type != null) {
+               if (stmt.return_expression == null && !(current_return_type is VoidType)) {
                        stmt.error = true;
                        Report.error (stmt.source_reference, "Return without value in non-void function");
                        return;
                }
 
-               if (stmt.return_expression != null &&
-                   current_return_type.data_type == null &&
-                   current_return_type.type_parameter == null) {
+               if (stmt.return_expression != null && current_return_type is VoidType) {
                        Report.error (stmt.source_reference, "Return with value in void function");
                        return;
                }
@@ -2080,17 +2078,20 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        Report.error (expr.source_reference, "internal error: unknown type of inner expression");
                        return;
                }
-               if (!(expr.inner.static_type.data_type is Pointer)) {
+               if (expr.inner.static_type is PointerType) {
+                       var pointer_type = (PointerType) expr.inner.static_type;
+                       expr.static_type = pointer_type.base_type;
+               } else if (expr.inner.static_type.data_type is Pointer) {
+                       var pointer = (Pointer) expr.inner.static_type.data_type;
+
+                       expr.static_type = new DataType ();
+                       expr.static_type.data_type = pointer.referent_type;
+                       expr.static_type.takes_ownership = expr.inner.static_type.takes_ownership;
+               } else {
                        expr.error = true;
                        Report.error (expr.source_reference, "Pointer indirection not supported for this expression");
                        return;
                }
-
-               var pointer = (Pointer) expr.inner.static_type.data_type;
-
-               expr.static_type = new DataType ();
-               expr.static_type.data_type = pointer.referent_type;
-               expr.static_type.takes_ownership = expr.inner.static_type.takes_ownership;
        }
 
        public override void visit_addressof_expression (AddressofExpression! expr) {
@@ -2108,9 +2109,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        return;
                }
 
-               expr.static_type = new DataType ();
-               expr.static_type.data_type = expr.inner.static_type.data_type.get_pointer ();
-               expr.static_type.takes_ownership = expr.inner.static_type.takes_ownership;
+               expr.static_type = new PointerType (expr.inner.static_type);
        }
 
        public override void visit_reference_transfer_expression (ReferenceTransferExpression! expr) {
@@ -2707,7 +2706,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                                if (memory_management) {
                                        if (a.right.static_type.transfers_ownership) {
                                                /* rhs transfers ownership of the expression */
-                                               if (!a.left.static_type.takes_ownership) {
+                                               if (!(a.left.static_type is PointerType) && !a.left.static_type.takes_ownership) {
                                                        /* lhs doesn't own the value */
                                                        a.error = true;
                                                        Report.error (a.source_reference, "Invalid assignment from owned expression to unowned variable");
@@ -2743,7 +2742,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                                        }
                                        var element_type = args.get (0);
 
-                                       if (!element_type.takes_ownership) {
+                                       if (!(element_type is PointerType) && !element_type.takes_ownership) {
                                                /* lhs doesn't own the value */
                                                a.error = true;
                                                Report.error (a.source_reference, "Invalid assignment from owned expression to unowned variable");
index 76269a8..aaf5c61 100644 (file)
@@ -265,20 +265,8 @@ public class Vala.SymbolResolver : CodeVisitor {
                        }
                }
 
-               if (unresolved_type.pointer_level > 0) {
-                       if (type.data_type == null) {
-                               type.error = true;
-                               Report.error (type.source_reference, "Pointer to `%s' not supported".printf (unresolved_type.type_name));
-                               return null;
-                       }
-                       var referent_type = new DataType ();
-                       referent_type.data_type = type.data_type;
-
-                       if (type.data_type.is_reference_type ()) {
-                               referent_type.takes_ownership = type.takes_ownership;
-                       }
-                       type.data_type = referent_type.data_type.get_pointer ();
-                       type.add_type_argument (referent_type);
+               for (int pointer_level = unresolved_type.pointer_level; pointer_level > 0; pointer_level--) {
+                       type = new PointerType (type);
                }
 
                /* check for array */
index 9398482..d7e6a6a 100644 (file)
@@ -32,4 +32,8 @@ public class Vala.VoidType : DataType {
        public override bool stricter (DataType! type2) {
                return (type2 is VoidType);
        }
+
+       public override string! to_string () {
+               return "void";
+       }
 }