Commit b261df87 authored by Jürg Billeter's avatar Jürg Billeter Committed by Jürg Billeter

update to be compatible with new pointer types

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
parent 415d9160
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,
......
......@@ -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++;
......
......@@ -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++;
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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);
......
......@@ -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>
......@@ -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;
......
......@@ -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 () ||
......
......@@ -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);
}
}
}
}
......
......@@ -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;
}
}
......@@ -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;
}
}
......@@ -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");
......
......@@ -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 */
......
......@@ -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";
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment