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,
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 {
}
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);
}
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++;
_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);
}
}
public bool add (G key) {
- Node<G>* node = lookup_node (key);
+ Node<G>** node = lookup_node (key);
if (*node != null) {
return false;
} else {
}
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++;
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 ());
}
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 ());
}
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;
}
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)) {
ccheck.add_argument (cnonnull);
}
- if (ret_type == null) {
+ if (ret_type is VoidType) {
/* void function */
ccheck.call = new CCodeIdentifier ("g_return_if_fail");
} else {
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;
}
{
$$ = 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
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
}
| 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);
}
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);
#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>
#include <vala/valaunaryexpression.h>
#include <vala/valaunresolvedtype.h>
#include <vala/valavariabledeclarator.h>
+#include <vala/valavoidtype.h>
#include <vala/valawhilestatement.h>
* @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;
}
/* 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 ||
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 () ||
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);
+ }
}
}
}
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);
+ }
}
}
}
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 */
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);
+ }
}
}
}
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;
+ }
}
/**
* 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;
+ }
}
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");
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;
}
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) {
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) {
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");
}
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");
}
}
- 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 */
public override bool stricter (DataType! type2) {
return (type2 is VoidType);
}
+
+ public override string! to_string () {
+ return "void";
+ }
}