vala r1466 - in trunk: . compiler gobject vala



Author: juergbi
Date: Wed May 28 19:01:45 2008
New Revision: 1466
URL: http://svn.gnome.org/viewvc/vala?rev=1466&view=rev

Log:
2008-05-28  Juerg Billeter  <j bitron ch>

	* vala/Makefile.am:
	* vala/valaaddressofexpression.vala:
	* vala/valaarraycreationexpression.vala:
	* vala/valaassignment.vala:
	* vala/valabaseaccess.vala:
	* vala/valabinaryexpression.vala:
	* vala/valabooleanliteral.vala:
	* vala/valacastexpression.vala:
	* vala/valacharacterliteral.vala:
	* vala/valacodevisitor.vala:
	* vala/valaconditionalexpression.vala:
	* vala/valadatatype.vala:
	* vala/valaelementaccess.vala:
	* vala/valaexpression.vala:
	* vala/valaintegerliteral.vala:
	* vala/valaintegertype.vala:
	* vala/valainvocationexpression.vala:
	* vala/valalambdaexpression.vala:
	* vala/valamemberaccess.vala:
	* vala/valanullchecker.vala:
	* vala/valanullliteral.vala:
	* vala/valanulltype.vala:
	* vala/valaobjectcreationexpression.vala:
	* vala/valaparenthesizedexpression.vala:
	* vala/valapointerindirection.vala:
	* vala/valapostfixexpression.vala:
	* vala/valarealliteral.vala:
	* vala/valareferencetransferexpression.vala:
	* vala/valasemanticanalyzer.vala:
	* vala/valasignal.vala:
	* vala/valasizeofexpression.vala:
	* vala/valastringliteral.vala:
	* vala/valatypecheck.vala:
	* vala/valatypeofexpression.vala:
	* vala/valaunaryexpression.vala:
	* vala/valaunresolvedtype.vala:
	* vala/valavaluetype.vala:
	* gobject/valaccodeassignmentbinding.vala:
	* gobject/valaccodeelementaccessbinding.vala:
	* gobject/valaccodegenerator.vala:
	* gobject/valaccodeinvocationexpressionbinding.vala:
	* gobject/valaccodememberaccessbinding.vala:
	* gobject/valaccodemethodbinding.vala:
	* compiler/valacompiler.vala:

	Move memory management into CCodeGenerator.transform_expression
	as preparation to properly support nullable structs, fixes memory
	leak in internal substring method, fixes bug 527775


Removed:
   trunk/vala/valamemorymanager.vala
Modified:
   trunk/ChangeLog
   trunk/compiler/valacompiler.vala
   trunk/gobject/valaccodeassignmentbinding.vala
   trunk/gobject/valaccodeelementaccessbinding.vala
   trunk/gobject/valaccodegenerator.vala
   trunk/gobject/valaccodeinvocationexpressionbinding.vala
   trunk/gobject/valaccodememberaccessbinding.vala
   trunk/gobject/valaccodemethodbinding.vala
   trunk/vala/Makefile.am
   trunk/vala/valaaddressofexpression.vala
   trunk/vala/valaarraycreationexpression.vala
   trunk/vala/valaassignment.vala
   trunk/vala/valabaseaccess.vala
   trunk/vala/valabinaryexpression.vala
   trunk/vala/valabooleanliteral.vala
   trunk/vala/valacastexpression.vala
   trunk/vala/valacharacterliteral.vala
   trunk/vala/valacodevisitor.vala
   trunk/vala/valaconditionalexpression.vala
   trunk/vala/valadatatype.vala
   trunk/vala/valaelementaccess.vala
   trunk/vala/valaexpression.vala
   trunk/vala/valaintegerliteral.vala
   trunk/vala/valaintegertype.vala
   trunk/vala/valainvocationexpression.vala
   trunk/vala/valalambdaexpression.vala
   trunk/vala/valamemberaccess.vala
   trunk/vala/valanullchecker.vala
   trunk/vala/valanullliteral.vala
   trunk/vala/valanulltype.vala
   trunk/vala/valaobjectcreationexpression.vala
   trunk/vala/valaparenthesizedexpression.vala
   trunk/vala/valapointerindirection.vala
   trunk/vala/valapostfixexpression.vala
   trunk/vala/valarealliteral.vala
   trunk/vala/valareferencetransferexpression.vala
   trunk/vala/valasemanticanalyzer.vala
   trunk/vala/valasignal.vala
   trunk/vala/valasizeofexpression.vala
   trunk/vala/valastringliteral.vala
   trunk/vala/valatypecheck.vala
   trunk/vala/valatypeofexpression.vala
   trunk/vala/valaunaryexpression.vala
   trunk/vala/valaunresolvedtype.vala
   trunk/vala/valavaluetype.vala

Modified: trunk/compiler/valacompiler.vala
==============================================================================
--- trunk/compiler/valacompiler.vala	(original)
+++ trunk/compiler/valacompiler.vala	Wed May 28 19:01:45 2008
@@ -265,13 +265,6 @@
 			}
 		}
 
-		var memory_manager = new MemoryManager ();
-		memory_manager.analyze (context);
-
-		if (Report.get_errors () > 0) {
-			return quit ();
-		}
-
 		context.codegen.emit (context);
 		
 		if (Report.get_errors () > 0) {

Modified: trunk/gobject/valaccodeassignmentbinding.vala
==============================================================================
--- trunk/gobject/valaccodeassignmentbinding.vala	(original)
+++ trunk/gobject/valaccodeassignmentbinding.vala	Wed May 28 19:01:45 2008
@@ -45,9 +45,6 @@
 		} else {
 			CCodeExpression cexpr = (CCodeExpression) assignment.right.ccodenode;
 
-			// ensure to pass the value correctly typed (especially important for varargs)
-			cexpr = codegen.get_implicit_cast_expression (cexpr, assignment.right.value_type, prop.property_type);
-
 			if (!prop.no_accessor_method) {
 				if (prop.property_type.is_real_struct_type ()) {
 					cexpr = codegen.get_address_of_expression (assignment.right, cexpr);
@@ -176,7 +173,7 @@
 		}
 		
 		// third resp. sixth argument: handler
-		ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier (generate_signal_handler_wrapper (m, sig)), "GCallback"));
+		ccall.add_argument (new CCodeCastExpression ((CCodeExpression) assignment.right.ccodenode, "GCallback"));
 
 		if (m.binding == MemberBinding.INSTANCE) {
 			// g_signal_connect_object or g_signal_handlers_disconnect_matched
@@ -210,120 +207,10 @@
 		codenode = ccall;
 	}
 
-	private string generate_signal_handler_wrapper (Method m, Signal sig) {
-		var dynamic_signal = sig as DynamicSignal;
-
-		string wrapper_name;
-		if (dynamic_signal != null) {
-			wrapper_name = "_%s_%s".printf (m.get_cname (), codegen.dynamic_signal_binding (dynamic_signal).get_dynamic_cname ());
-		} else {
-			wrapper_name = "_%s_%s%s".printf (m.get_cname (), sig.parent_symbol.get_lower_case_cprefix (), sig.get_cname ());
-		}
-
-		if (!codegen.add_wrapper (wrapper_name)) {
-			// wrapper already defined
-			return wrapper_name;
-		}
-
-		// declaration
-
-		var function = new CCodeFunction (wrapper_name, m.return_type.get_cname ());
-		function.modifiers = CCodeModifiers.STATIC;
-		m.ccodenode = function;
-
-		var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
-
-		var cparam = new CCodeFormalParameter ("self", "gpointer");
-		cparam_map.set (codegen.get_param_pos (-1), cparam);
-
-		cparam = new CCodeFormalParameter ("_sender", ((TypeSymbol) sig.parent_symbol).get_cname () + "*");
-		cparam_map.set (codegen.get_param_pos (0), cparam);
-		foreach (FormalParameter param in sig.get_parameters()) {
-			// ensure that C code node has been generated
-			param.accept (codegen);
-
-			cparam_map.set (codegen.get_param_pos (param.cparameter_position), (CCodeFormalParameter) param.ccodenode);
-		}
-
-		// append C parameters in the right order
-		int last_pos = -1;
-		int min_pos;
-		while (true) {
-			min_pos = -1;
-			foreach (int pos in cparam_map.get_keys ()) {
-				if (pos > last_pos && (min_pos == -1 || pos < min_pos)) {
-					min_pos = pos;
-				}
-			}
-			if (min_pos == -1) {
-				break;
-			}
-			function.add_parameter (cparam_map.get (min_pos));
-			last_pos = min_pos;
-		}
-
-
-		// definition
-
-		var carg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
-
-		if (m.binding == MemberBinding.INSTANCE) {
-			carg_map.set (codegen.get_param_pos (m.cinstance_parameter_position), new CCodeIdentifier ("self"));
-		}
-
-		int i = -1;
-		var sig_params = sig.get_parameters ();
-		foreach (FormalParameter param in m.get_parameters ()) {
-			CCodeExpression arg;
-			if (i < 0) {
-				arg = new CCodeIdentifier ("_sender");
-			} else {
-				arg = new CCodeIdentifier ((sig_params.get (i).ccodenode as CCodeFormalParameter).name);
-			}
-			carg_map.set (codegen.get_param_pos (param.cparameter_position), arg);
-			i++;
-		}
-		var ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_cname ()));
-
-		// append C arguments in the right order
-		last_pos = -1;
-		while (true) {
-			min_pos = -1;
-			foreach (int pos in carg_map.get_keys ()) {
-				if (pos > last_pos && (min_pos == -1 || pos < min_pos)) {
-					min_pos = pos;
-				}
-			}
-			if (min_pos == -1) {
-				break;
-			}
-			ccall.add_argument (carg_map.get (min_pos));
-			last_pos = min_pos;
-		}
-
-		var block = new CCodeBlock ();
-		if (m.return_type is VoidType) {
-			block.add_statement (new CCodeExpressionStatement (ccall));
-		} else {
-			block.add_statement (new CCodeReturnStatement (ccall));
-		}
-
-		// append to file
-
-		codegen.source_type_member_declaration.append (function.copy ());
-
-		function.block = block;
-		codegen.source_type_member_definition.append (function);
-
-		return wrapper_name;
-	}
-
 	private void emit_non_array_element_access () {
 		// custom element access
 		CCodeExpression rhs = (CCodeExpression) assignment.right.ccodenode;
 
-		rhs = codegen.get_implicit_cast_expression (rhs, assignment.right.value_type, assignment.left.value_type);
-
 		var expr = (ElementAccess) assignment.left;
 		var container_type = expr.container.value_type.data_type;
 		Collection<Expression> indices = expr.get_indices ();
@@ -368,8 +255,6 @@
 	private void emit_simple_assignment () {
 		CCodeExpression rhs = (CCodeExpression) assignment.right.ccodenode;
 
-		rhs = codegen.get_implicit_cast_expression (rhs, assignment.right.value_type, assignment.left.value_type);
-
 		bool unref_old = codegen.requires_destroy (assignment.left.value_type);
 		bool array = false;
 		bool instance_delegate = false;
@@ -470,7 +355,5 @@
 		}
 
 		assignment.ccodenode = codenode;
-
-		codegen.visit_expression (assignment);
 	}
 }

Modified: trunk/gobject/valaccodeelementaccessbinding.vala
==============================================================================
--- trunk/gobject/valaccodeelementaccessbinding.vala	(original)
+++ trunk/gobject/valaccodeelementaccessbinding.vala	Wed May 28 19:01:45 2008
@@ -97,7 +97,5 @@
 		}
 
 		expr.ccodenode = codenode;
-
-		codegen.visit_expression (expr);
 	}
 }

Modified: trunk/gobject/valaccodegenerator.vala
==============================================================================
--- trunk/gobject/valaccodegenerator.vala	(original)
+++ trunk/gobject/valaccodegenerator.vala	Wed May 28 19:01:45 2008
@@ -595,14 +595,16 @@
 
 			if (f.initializer != null) {
 				var rhs = (CCodeExpression) f.initializer.ccodenode;
-				rhs = get_implicit_cast_expression (rhs, f.initializer.value_type, f.field_type);
 
 				instance_init_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (lhs, rhs)));
 
 				if (f.field_type is ArrayType && !f.no_array_length &&
 				    f.initializer is ArrayCreationExpression) {
 					var array_type = (ArrayType) f.field_type;
-					var ma = new MemberAccess.simple (f.name);
+					var this_access = new MemberAccess.simple ("this");
+					this_access.value_type = get_data_type_for_symbol ((TypeSymbol) f.parent_symbol);
+					this_access.ccodenode = new CCodeIdentifier ("self");
+					var ma = new MemberAccess (this_access, f.name);
 					ma.symbol_reference = f;
 					
 					Gee.List<Expression> sizes = ((ArrayCreationExpression) f.initializer).get_sizes ();
@@ -615,7 +617,10 @@
 			}
 			
 			if (requires_destroy (f.field_type) && instance_dispose_fragment != null) {
-				var ma = new MemberAccess.simple (f.name);
+				var this_access = new MemberAccess.simple ("this");
+				this_access.value_type = get_data_type_for_symbol ((TypeSymbol) f.parent_symbol);
+				this_access.ccodenode = new CCodeIdentifier ("self");
+				var ma = new MemberAccess (this_access, f.name);
 				ma.symbol_reference = f;
 				instance_dispose_fragment.append (new CCodeExpressionStatement (get_unref_expression (lhs, f.field_type, ma)));
 			}
@@ -1139,7 +1144,6 @@
 		CCodeExpression rhs = null;
 		if (local.initializer != null && local.initializer.ccodenode != null) {
 			rhs = (CCodeExpression) local.initializer.ccodenode;
-			rhs = get_implicit_cast_expression (rhs, local.initializer.value_type, local.variable_type);
 
 			if (local.variable_type is ArrayType) {
 				var array_type = (ArrayType) local.variable_type;
@@ -1223,7 +1227,7 @@
 
 		var clist = new CCodeInitializerList ();
 		foreach (Expression expr in list.get_initializers ()) {
-			clist.append (get_implicit_cast_expression ((CCodeExpression) expr.ccodenode, expr.value_type, expr.target_type));
+			clist.append ((CCodeExpression) expr.ccodenode);
 		}
 		list.ccodenode = clist;
 	}
@@ -1471,8 +1475,13 @@
 			/* nothing to do without temporary variables */
 			return;
 		}
-		
-		var full_expr_var = get_temp_variable (expr.value_type, true, expr);
+
+		var expr_type = expr.value_type;
+		if (expr.target_type != null) {
+			expr_type = expr.target_type;
+		}
+
+		var full_expr_var = get_temp_variable (expr_type, true, expr);
 		expr.temp_vars.add (full_expr_var);
 		
 		var expr_list = new CCodeCommaExpression ();
@@ -1887,6 +1896,12 @@
 			
 			/* the array has no length parameter i.e. is NULL-terminated array */
 			if (array_len is CCodeConstant) {
+				// store array length for use by _vala_array_free
+				var clendecl = new CCodeDeclaration ("int");
+				clendecl.add_declarator (new CCodeVariableDeclarator.with_initializer (get_array_length_cname (collection_backup.name, 1), array_len));
+				cblock.add_statement (clendecl);
+
+
 				var it_name = "%s_it".printf (stmt.variable_name);
 			
 				var citdecl = new CCodeDeclaration (collection_type.get_cname ());
@@ -1897,23 +1912,14 @@
 
 				CCodeExpression element_expr = new CCodeIdentifier ("*%s".printf (it_name));
 
-				element_expr = get_implicit_cast_expression (element_expr, array_type.element_type, stmt.type_reference);
+				var element_type = array_type.element_type.copy ();
+				element_type.value_owned = false;
+				element_expr = transform_expression (element_expr, element_type, stmt.type_reference);
 
-				if (requires_copy (stmt.type_reference)) {
-					var ma = new MemberAccess.simple (stmt.variable_name);
-					ma.value_type = stmt.type_reference;
-					ma.ccodenode = element_expr;
-					element_expr = get_ref_expression (ma);
-
-					var clendecl = new CCodeDeclaration ("int");
-					clendecl.add_declarator (new CCodeVariableDeclarator.with_initializer (get_array_length_cname (collection_backup.name, 1), array_len));
-					cblock.add_statement (clendecl);
-
-					var cfrag = new CCodeFragment ();
-					append_temp_decl (cfrag, temp_vars);
-					cbody.add_statement (cfrag);
-					temp_vars.clear ();
-				}
+				var cfrag = new CCodeFragment ();
+				append_temp_decl (cfrag, temp_vars);
+				cbody.add_statement (cfrag);
+				temp_vars.clear ();
 
 				var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
 				cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (stmt.variable_name, element_expr));
@@ -1941,19 +1947,14 @@
 
 				CCodeExpression element_expr = new CCodeElementAccess (new CCodeIdentifier (collection_backup.name), new CCodeIdentifier (it_name));
 
-				element_expr = get_implicit_cast_expression (element_expr, array_type.element_type, stmt.type_reference);
+				var element_type = array_type.element_type.copy ();
+				element_type.value_owned = false;
+				element_expr = transform_expression (element_expr, element_type, stmt.type_reference);
 
-				if (requires_copy (stmt.type_reference)) {
-					var ma = new MemberAccess.simple (stmt.variable_name);
-					ma.value_type = stmt.type_reference;
-					ma.ccodenode = element_expr;
-					element_expr = get_ref_expression (ma);
-
-					var cfrag = new CCodeFragment ();
-					append_temp_decl (cfrag, temp_vars);
-					cbody.add_statement (cfrag);
-					temp_vars.clear ();
-				}
+				var cfrag = new CCodeFragment ();
+				append_temp_decl (cfrag, temp_vars);
+				cbody.add_statement (cfrag);
+				temp_vars.clear ();
 
 				var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
 				cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (stmt.variable_name, element_expr));
@@ -2006,22 +2007,15 @@
 				return;
 			}
 
-			var element_data_type = collection_type.get_type_arguments ().get (0);
-			element_expr = get_implicit_cast_expression (element_expr, element_data_type, stmt.type_reference);
+			var element_data_type = collection_type.get_type_arguments ().get (0).copy ();
+			element_data_type.value_owned = false;
+			element_data_type.is_type_argument = true;
+			element_expr = transform_expression (element_expr, element_data_type, stmt.type_reference);
 
-			element_expr = convert_from_generic_pointer (element_expr, stmt.type_reference);
-
-			if (requires_copy (stmt.type_reference)) {
-				var ma = new MemberAccess.simple (stmt.variable_name);
-				ma.value_type = stmt.type_reference;
-				ma.ccodenode = element_expr;
-				element_expr = get_ref_expression (ma);
-
-				var cfrag = new CCodeFragment ();
-				append_temp_decl (cfrag, temp_vars);
-				cbody.add_statement (cfrag);
-				temp_vars.clear ();
-			}
+			var cfrag = new CCodeFragment ();
+			append_temp_decl (cfrag, temp_vars);
+			cbody.add_statement (cfrag);
+			temp_vars.clear ();
 
 			var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
 			var cvardecl = new CCodeVariableDeclarator.with_initializer (stmt.variable_name, element_expr);
@@ -2058,25 +2052,16 @@
 			get_ccall.add_argument (new CCodeIdentifier (it_name));
 			CCodeExpression element_expr = get_ccall;
 
-			element_expr = convert_from_generic_pointer (element_expr, stmt.type_reference);
-
 			Iterator<DataType> type_arg_it = it_method.return_type.get_type_arguments ().iterator ();
 			type_arg_it.next ();
 			var it_type = SemanticAnalyzer.get_actual_type (stmt.collection.value_type, it_method, type_arg_it.get (), stmt);
 
-			element_expr = get_implicit_cast_expression (element_expr, it_type, stmt.type_reference);
-
-			if (requires_copy (stmt.type_reference) && !it_type.value_owned) {
-				var ma = new MemberAccess.simple (stmt.variable_name);
-				ma.value_type = stmt.type_reference;
-				ma.ccodenode = element_expr;
-				element_expr = get_ref_expression (ma);
+			element_expr = transform_expression (element_expr, it_type, stmt.type_reference);
 
-				var cfrag = new CCodeFragment ();
-				append_temp_decl (cfrag, temp_vars);
-				cbody.add_statement (cfrag);
-				temp_vars.clear ();
-			}
+			var cfrag = new CCodeFragment ();
+			append_temp_decl (cfrag, temp_vars);
+			cbody.add_statement (cfrag);
+			temp_vars.clear ();
 
 			var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
 			var cvardecl = new CCodeVariableDeclarator.with_initializer (stmt.variable_name, element_expr);
@@ -2204,7 +2189,12 @@
 	}
 
 	private void create_local_free_expr (Expression expr) {
-		var return_expr_decl = get_temp_variable (expr.value_type, true, expr);
+		var expr_type = expr.value_type;
+		if (expr.target_type != null) {
+			expr_type = expr.target_type;
+		}
+
+		var return_expr_decl = get_temp_variable (expr_type, true, expr);
 		
 		var ccomma = new CCodeCommaExpression ();
 		ccomma.append_expression (new CCodeAssignment (new CCodeIdentifier (return_expr_decl.name), (CCodeExpression) expr.ccodenode));
@@ -2221,20 +2211,16 @@
 	}
 
 	public override void visit_return_statement (ReturnStatement stmt) {
+		// avoid unnecessary ref/unref pair
 		if (stmt.return_expression != null) {
-			// avoid unnecessary ref/unref pair
-			if (stmt.return_expression.ref_missing &&
-			    stmt.return_expression.symbol_reference is LocalVariable) {
-				var local = (LocalVariable) stmt.return_expression.symbol_reference;
-				if (local.variable_type.value_owned) {
-					/* return expression is local variable taking ownership and
-					 * current method is transferring ownership */
-					
-					stmt.return_expression.ref_sink = true;
+			var local = stmt.return_expression.symbol_reference as LocalVariable;
+			if (current_return_type.value_owned
+			    && local != null && local.variable_type.value_owned) {
+				/* return expression is local variable taking ownership and
+				 * current method is transferring ownership */
 
-					// don't ref expression
-					stmt.return_expression.ref_missing = false;
-				}
+				// don't ref expression
+				stmt.return_expression.value_type.value_owned = true;
 			}
 		}
 
@@ -2246,19 +2232,17 @@
 			create_local_free (stmt);
 		} else {
 			Symbol return_expression_symbol = null;
-		
+
 			// avoid unnecessary ref/unref pair
-			if (stmt.return_expression.ref_sink &&
-			    stmt.return_expression.symbol_reference is LocalVariable) {
-				var local = (LocalVariable) stmt.return_expression.symbol_reference;
-				if (local.variable_type.value_owned) {
-					/* return expression is local variable taking ownership and
-					 * current method is transferring ownership */
-					
-					// don't unref expression
-					return_expression_symbol = local;
-					return_expression_symbol.active = false;
-				}
+			var local = stmt.return_expression.symbol_reference as LocalVariable;
+			if (current_return_type.value_owned
+			    && local != null && local.variable_type.value_owned) {
+				/* return expression is local variable taking ownership and
+				 * current method is transferring ownership */
+
+				// don't unref variable
+				return_expression_symbol = local;
+				return_expression_symbol.active = false;
 			}
 
 			// return array length if appropriate
@@ -2283,8 +2267,6 @@
 			}
 
 			create_local_free_expr (stmt.return_expression);
-			
-			stmt.return_expression.ccodenode = get_implicit_cast_expression ((CCodeExpression) stmt.return_expression.ccodenode, stmt.return_expression.value_type, current_return_type);
 
 			// Property getters of non simple structs shall return the struct value as out parameter,
 			// therefore replace any return statement with an assignment statement to the out formal
@@ -2448,14 +2430,19 @@
 		stmt.ccodenode = new CCodeExpressionStatement (ccall);
 	}
 
+	public override void visit_expression (Expression expr) {
+		if (expr.ccodenode != null && !expr.lvalue) {
+			// memory management, implicit casts, and boxing/unboxing
+			expr.ccodenode = transform_expression ((CCodeExpression) expr.ccodenode, expr.value_type, expr.target_type, expr);
+		}
+	}
+
 	public override void visit_array_creation_expression (ArrayCreationExpression expr) {
 		code_binding (expr).emit ();
 	}
 
 	public override void visit_boolean_literal (BooleanLiteral expr) {
 		expr.ccodenode = new CCodeConstant (expr.value ? "TRUE" : "FALSE");
-
-		visit_expression (expr);
 	}
 
 	public override void visit_character_literal (CharacterLiteral expr) {
@@ -2464,40 +2451,28 @@
 		} else {
 			expr.ccodenode = new CCodeConstant ("%uU".printf (expr.get_char ()));
 		}
-
-		visit_expression (expr);
 	}
 
 	public override void visit_integer_literal (IntegerLiteral expr) {
 		expr.ccodenode = new CCodeConstant (expr.value);
-
-		visit_expression (expr);
 	}
 
 	public override void visit_real_literal (RealLiteral expr) {
 		expr.ccodenode = new CCodeConstant (expr.value);
-
-		visit_expression (expr);
 	}
 
 	public override void visit_string_literal (StringLiteral expr) {
 		expr.ccodenode = new CCodeConstant (expr.value);
-
-		visit_expression (expr);
 	}
 
 	public override void visit_null_literal (NullLiteral expr) {
 		expr.ccodenode = new CCodeConstant ("NULL");
-
-		visit_expression (expr);
 	}
 
 	public override void visit_parenthesized_expression (ParenthesizedExpression expr) {
 		expr.accept_children (this);
 
 		expr.ccodenode = new CCodeParenthesizedExpression ((CCodeExpression) expr.inner.ccodenode);
-
-		visit_expression (expr);
 	}
 
 	public override void visit_member_access (MemberAccess expr) {
@@ -2577,30 +2552,18 @@
 				if (!field.no_array_length) {
 					var ma = (MemberAccess) array_expr;
 
-					CCodeExpression pub_inst = null;
-					TypeSymbol 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 = (TypeSymbol) current_type_symbol;
-						}
-					} else {
-						pub_inst = (CCodeExpression) ma.inner.ccodenode;
 
+					if (field.binding == MemberBinding.INSTANCE) {
+						TypeSymbol base_type = null;
 						if (ma.inner.value_type != null) {
 							base_type = ma.inner.value_type.data_type;
 						}
-					}
 
-					if (field.binding == MemberBinding.INSTANCE) {
 						var length_cname = get_array_length_cname (field.name, dim);
 						var instance_expression_type = get_data_type_for_symbol (base_type);
 						var instance_target_type = get_data_type_for_symbol ((TypeSymbol) field.parent_symbol);
-						CCodeExpression typed_inst = get_implicit_cast_expression (pub_inst, instance_expression_type, instance_target_type);
+						CCodeExpression typed_inst = (CCodeExpression) ma.inner.ccodenode;
 
 						CCodeExpression inst;
 						if (field.access == SymbolAccessibility.PRIVATE) {
@@ -2698,29 +2661,19 @@
 
 				var ma = (MemberAccess) delegate_expr;
 
-				CCodeExpression pub_inst = null;
 				TypeSymbol base_type = null;
 				CCodeExpression target_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 = (TypeSymbol) current_type_symbol;
-					}
-				} else {
-					pub_inst = (CCodeExpression) ma.inner.ccodenode;
+				var pub_inst = (CCodeExpression) ma.inner.ccodenode;
 
-					if (ma.inner.value_type != null) {
-						base_type = ma.inner.value_type.data_type;
-					}
+				if (ma.inner.value_type != null) {
+					base_type = ma.inner.value_type.data_type;
 				}
 
 				if (field.binding == MemberBinding.INSTANCE) {
 					var instance_expression_type = get_data_type_for_symbol (base_type);
 					var instance_target_type = get_data_type_for_symbol ((TypeSymbol) field.parent_symbol);
-					CCodeExpression typed_inst = get_implicit_cast_expression (pub_inst, instance_expression_type, instance_target_type);
+					CCodeExpression typed_inst = transform_expression (pub_inst, instance_expression_type, instance_target_type);
 
 					CCodeExpression inst;
 					if (field.access == SymbolAccessibility.PRIVATE) {
@@ -2745,11 +2698,7 @@
 			} else if (delegate_expr.symbol_reference is Method) {
 				var ma = (MemberAccess) delegate_expr;
 				if (ma.inner == null) {
-					if ((current_method != null && current_method.binding == MemberBinding.INSTANCE) || in_constructor) {
-						return new CCodeIdentifier ("self");
-					} else {
-						return new CCodeConstant ("NULL");
-					}
+					return new CCodeConstant ("NULL");
 				} else {
 					return (CCodeExpression) ma.inner.ccodenode;
 				}
@@ -2796,8 +2745,6 @@
 		var op = expr.increment ? CCodeUnaryOperator.POSTFIX_INCREMENT : CCodeUnaryOperator.POSTFIX_DECREMENT;
 	
 		expr.ccodenode = new CCodeUnaryExpression (op, (CCodeExpression) expr.inner.ccodenode);
-		
-		visit_expression (expr);
 	}
 	
 	private MemberAccess? find_property_access (Expression expr) {
@@ -2847,6 +2794,10 @@
 	}
 
 	private CCodeExpression? get_ref_expression (Expression expr) {
+		return get_ref_cexpression (expr.value_type, (CCodeExpression) expr.ccodenode, expr, expr);
+	}
+
+	private CCodeExpression? get_ref_cexpression (DataType expression_type, CCodeExpression cexpr, Expression? expr, CodeNode node) {
 		/* (temp = expr, temp == NULL ? NULL : ref (temp))
 		 *
 		 * can be simplified to
@@ -2854,10 +2805,10 @@
 		 * if static type of expr is non-null
 		 */
 		 
-		var dupexpr = get_dup_func_expression (expr.value_type, expr.source_reference);
+		var dupexpr = get_dup_func_expression (expression_type, node.source_reference);
 
 		if (dupexpr == null) {
-			expr.error = true;
+			node.error = true;
 			return null;
 		}
 
@@ -2869,23 +2820,23 @@
 			
 			return ccall;
 		} else {
-			var decl = get_temp_variable (expr.value_type, false, expr);
+			var decl = get_temp_variable (expression_type, false, node);
 			temp_vars.insert (0, decl);
 
 			var ctemp = new CCodeIdentifier (decl.name);
 			
 			var cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, ctemp, new CCodeConstant ("NULL"));
-			if (expr.value_type.data_type == null) {
+			if (expression_type.data_type == null) {
 				if (!(current_type_symbol is Class)) {
-					return (CCodeExpression) expr.ccodenode;
+					return cexpr;
 				}
 
 				// dup functions are optional for type parameters
-				var cdupisnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, get_dup_func_expression (expr.value_type, expr.source_reference), new CCodeConstant ("NULL"));
+				var cdupisnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, get_dup_func_expression (expression_type, node.source_reference), new CCodeConstant ("NULL"));
 				cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.OR, cisnull, cdupisnull);
 			}
 
-			if (expr.value_type.data_type != null) {
+			if (expression_type.data_type != null) {
 				ccall.add_argument (ctemp);
 			} else {
 				// cast from gconstpointer to gpointer as GBoxedCopyFunc expects gpointer
@@ -2893,10 +2844,10 @@
 			}
 
 			var ccomma = new CCodeCommaExpression ();
-			ccomma.append_expression (new CCodeAssignment (ctemp, (CCodeExpression) expr.ccodenode));
+			ccomma.append_expression (new CCodeAssignment (ctemp, cexpr));
 
 			CCodeExpression cifnull;
-			if (expr.value_type.data_type != null) {
+			if (expression_type.data_type != null) {
 				cifnull = new CCodeConstant ("NULL");
 			} else {
 				// the value might be non-null even when the dup function is null,
@@ -2911,37 +2862,6 @@
 			return ccomma;
 		}
 	}
-	
-	public void visit_expression (Expression expr) {
-		if (expr.value_type != null &&
-		    expr.value_type.value_owned &&
-		    !expr.lvalue &&
-		    expr.value_type.floating_reference) {
-			/* constructor of GInitiallyUnowned subtype
-			 * returns floating reference, sink it
-			 */
-			var csink = new CCodeFunctionCall (new CCodeIdentifier ("g_object_ref_sink"));
-			csink.add_argument ((CCodeExpression) expr.ccodenode);
-			
-			expr.ccodenode = csink;
-		}
-	
-		if (expr.ref_leaked && requires_destroy (expr.value_type)) {
-			var decl = get_temp_variable (expr.value_type, true, expr);
-			temp_vars.insert (0, decl);
-			temp_ref_vars.insert (0, decl);
-			expr.ccodenode = new CCodeParenthesizedExpression (new CCodeAssignment (new CCodeIdentifier (get_variable_cname (decl.name)), (CCodeExpression) expr.ccodenode));
-		} else if (expr.ref_missing) {
-			// ref_missing => assignment of unowned expression to owned expression
-			// requires_copy should be called on target type but we don't have this
-			// information available here, so construct approximation of target type
-			var target_type = expr.value_type.copy ();
-			target_type.value_owned = true;
-			if (requires_copy (target_type)) {
-				expr.ccodenode = get_ref_expression (expr);
-			}
-		}
-	}
 
 	public override void visit_object_creation_expression (ObjectCreationExpression expr) {
 		expr.accept_children (this);
@@ -3025,8 +2945,6 @@
 					param = params_it.get ();
 					ellipsis = param.ellipsis;
 					if (!param.ellipsis) {
-						cexpr = get_implicit_cast_expression (cexpr, arg.value_type, param.parameter_type);
-
 						// pass non-simple struct instances always by reference
 						if (param.parameter_type.data_type is Struct && !((Struct) param.parameter_type.data_type).is_simple_type ()) {
 							// we already use a reference for arguments of ref and out parameters
@@ -3127,7 +3045,7 @@
 				if (init.symbol_reference is Field) {
 					var f = (Field) init.symbol_reference;
 					var instance_target_type = get_data_type_for_symbol ((TypeSymbol) f.parent_symbol);
-					var typed_inst = get_implicit_cast_expression (instance, expr.type_reference, instance_target_type);
+					var typed_inst = transform_expression (instance, expr.type_reference, instance_target_type);
 					CCodeExpression lhs;
 					if (expr.type_reference.data_type is Struct) {
 						lhs = new CCodeMemberAccess (typed_inst, f.get_cname ());
@@ -3150,8 +3068,6 @@
 		} else if (creation_call != null) {
 			expr.ccodenode = creation_call;
 		}
-
-		visit_expression (expr);
 	}
 
 	public override void visit_sizeof_expression (SizeofExpression expr) {
@@ -3184,8 +3100,6 @@
 			op = CCodeUnaryOperator.ADDRESS_OF;
 		}
 		expr.ccodenode = new CCodeUnaryExpression (op, (CCodeExpression) expr.inner.ccodenode);
-
-		visit_expression (expr);
 	}
 
 	public override void visit_cast_expression (CastExpression expr) {
@@ -3220,8 +3134,6 @@
 			}
 			expr.ccodenode = new CCodeCastExpression ((CCodeExpression) expr.inner.ccodenode, expr.type_reference.get_cname ());
 		}
-
-		visit_expression (expr);
 	}
 	
 	public override void visit_pointer_indirection (PointerIndirection expr) {
@@ -3245,8 +3157,6 @@
 		ccomma.append_expression (new CCodeAssignment ((CCodeExpression) expr.inner.ccodenode, new CCodeConstant ("NULL")));
 		ccomma.append_expression (cvar);
 		expr.ccodenode = ccomma;
-
-		visit_expression (expr);
 	}
 
 	public override void visit_binary_expression (BinaryExpression expr) {
@@ -3292,8 +3202,6 @@
 			op = CCodeBinaryOperator.OR;
 		} else if (expr.operator == BinaryOperator.IN) {
 			expr.ccodenode = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeParenthesizedExpression (new CCodeBinaryExpression (CCodeBinaryOperator.BITWISE_AND, new CCodeParenthesizedExpression (cright), new CCodeParenthesizedExpression (cleft))), new CCodeParenthesizedExpression (cleft));
-
-			visit_expression (expr);
 			return;
 		}
 		
@@ -3340,8 +3248,6 @@
 		}
 
 		expr.ccodenode = new CCodeBinaryExpression (op, cleft, cright);
-		
-		visit_expression (expr);
 	}
 
 	static CCodeFunctionCall create_type_check (CCodeNode ccodenode, TypeSymbol type) {
@@ -3356,8 +3262,6 @@
 
 	public override void visit_conditional_expression (ConditionalExpression expr) {
 		expr.ccodenode = new CCodeConditionalExpression ((CCodeExpression) expr.condition.ccodenode, (CCodeExpression) expr.true_expression.ccodenode, (CCodeExpression) expr.false_expression.ccodenode);
-
-		visit_expression (expr);
 	}
 
 	public override void visit_lambda_expression (LambdaExpression l) {
@@ -3414,20 +3318,82 @@
 		return result;
 	}
 
-	public CCodeExpression get_implicit_cast_expression (CCodeExpression cexpr, DataType? expression_type, DataType target_type) {
+	// manage memory and implicit casts
+	public CCodeExpression transform_expression (CCodeExpression source_cexpr, DataType? expression_type, DataType? target_type, Expression? expr = null) {
+		var cexpr = source_cexpr;
 		if (expression_type == null) {
 			return cexpr;
 		}
 
-		if (expression_type.data_type != null && expression_type.data_type == target_type.data_type) {
-			// same type, no cast required
+
+		if (expression_type.value_owned
+		    && expression_type.floating_reference) {
+			/* constructor of GInitiallyUnowned subtype
+			 * returns floating reference, sink it
+			 */
+			var csink = new CCodeFunctionCall (new CCodeIdentifier ("g_object_ref_sink"));
+			csink.add_argument (cexpr);
+			
+			cexpr = csink;
+		}
+
+		if (expression_type.value_owned
+		    && (target_type == null || !target_type.value_owned)) {
+			// value leaked, destroy it
+			var pointer_type = target_type as PointerType;
+			if (pointer_type != null && !(pointer_type.base_type is VoidType)) {
+				// manual memory management for non-void pointers
+				// treat void* special to not leak memory with void* method parameters
+			} else if (requires_destroy (expression_type)) {
+				var decl = get_temp_variable (expression_type, true, expression_type);
+				temp_vars.insert (0, decl);
+				temp_ref_vars.insert (0, decl);
+				cexpr = new CCodeParenthesizedExpression (new CCodeAssignment (new CCodeIdentifier (get_variable_cname (decl.name)), cexpr));
+
+				if (expression_type is ArrayType && expr != null) {
+					var array_type = (ArrayType) expression_type;
+					var ccomma = new CCodeCommaExpression ();
+					ccomma.append_expression (cexpr);
+					for (int dim = 1; dim <= array_type.rank; dim++) {
+						var len_decl = new LocalVariable (int_type.copy (), get_array_length_cname (decl.name, dim));
+						temp_vars.insert (0, len_decl);
+						ccomma.append_expression (new CCodeAssignment (new CCodeIdentifier (get_variable_cname (len_decl.name)), get_array_length_cexpression (expr, dim)));
+					}
+					ccomma.append_expression (new CCodeIdentifier (get_variable_cname (decl.name)));
+					cexpr = ccomma;
+				}
+			}
+		}
+
+		if (target_type == null) {
+			// value will be destroyed, no need for implicit casts
 			return cexpr;
 		}
 
-		if (expression_type.type_parameter != null) {
-			return convert_from_generic_pointer (cexpr, target_type);
-		} else if (target_type.type_parameter != null) {
-			return convert_to_generic_pointer (cexpr, expression_type);
+		cexpr = get_implicit_cast_expression (cexpr, expression_type, target_type, expr);
+
+		if (expression_type.is_type_argument) {
+			cexpr = convert_from_generic_pointer (cexpr, target_type);
+		} else if (target_type.is_type_argument) {
+			cexpr = convert_to_generic_pointer (cexpr, expression_type);
+		}
+
+		if (target_type.value_owned && !expression_type.value_owned) {
+			// need to copy value
+			if (requires_copy (target_type) && !(expression_type is NullType)) {
+				cexpr = get_ref_cexpression (target_type, cexpr, expr, expression_type);
+			}
+		}
+
+		return cexpr;
+	}
+
+	private CCodeExpression get_implicit_cast_expression (CCodeExpression source_cexpr, DataType? expression_type, DataType? target_type, Expression? expr = null) {
+		var cexpr = source_cexpr;
+
+		if (expression_type.data_type != null && expression_type.data_type == target_type.data_type) {
+			// same type, no cast required
+			return cexpr;
 		}
 
 		if (expression_type is NullType) {
@@ -3466,7 +3432,18 @@
 	}
 
 	private string generate_delegate_wrapper (Method m, Delegate d) {
-		string wrapper_name = "_%s_%s".printf (m.get_cname (), Symbol.camel_case_to_lower_case (d.get_cname ()));
+		string delegate_name;
+		var sig = d.parent_symbol as Signal;
+		var dynamic_sig = sig as DynamicSignal;
+		if (dynamic_sig != null) {
+			delegate_name = dynamic_signal_binding (dynamic_sig).get_dynamic_cname ();
+		} else if (sig != null) {
+			delegate_name = sig.parent_symbol.get_lower_case_cprefix () + sig.get_cname ();
+		} else {
+			delegate_name = Symbol.camel_case_to_lower_case (d.get_cname ());
+		}
+
+		string wrapper_name = "_%s_%s".printf (m.get_cname (), delegate_name);
 
 		if (!add_wrapper (wrapper_name)) {
 			// wrapper already defined
@@ -3635,21 +3612,7 @@
 		var ccall = new CCodeFunctionCall (new CCodeIdentifier (set_func));
 
 		/* target instance is first argument */
-		CCodeExpression instance;
-
-		DataType instance_expression_type;
-		if (ma.inner == null) {
-			instance = new CCodeIdentifier ("self");
-			instance_expression_type = get_data_type_for_symbol (current_type_symbol);
-		} else {
-			instance = (CCodeExpression) ma.inner.ccodenode;
-			instance_expression_type = ma.inner.value_type;
-		}
-
-		var instance_target_type = get_data_type_for_symbol ((TypeSymbol) base_property.parent_symbol);
-		instance = get_implicit_cast_expression (instance, instance_expression_type, instance_target_type);
-
-		ccall.add_argument (instance);
+		ccall.add_argument ((CCodeExpression) ma.inner.ccodenode);
 
 		if (prop.no_accessor_method) {
 			/* property name is second argument of g_object_set */

Modified: trunk/gobject/valaccodeinvocationexpressionbinding.vala
==============================================================================
--- trunk/gobject/valaccodeinvocationexpressionbinding.vala	(original)
+++ trunk/gobject/valaccodeinvocationexpressionbinding.vala	Wed May 28 19:01:45 2008
@@ -74,21 +74,8 @@
 
 		CCodeExpression instance;
 		if (m != null && m.binding == MemberBinding.INSTANCE) {
-			var base_method = m;
-			if (m.base_method != null) {
-				base_method = m.base_method;
-			} else if (m.base_interface_method != null) {
-				base_method = m.base_interface_method;
-			}
-
-			DataType instance_expression_type;
-			if (ma.inner == null) {
-				instance = new CCodeIdentifier ("self");
-				instance_expression_type = codegen.get_data_type_for_symbol (codegen.current_type_symbol);
-			} else {
-				instance = (CCodeExpression) ma.inner.ccodenode;
-				instance_expression_type = ma.inner.value_type;
-			}
+			instance = (CCodeExpression) ma.inner.ccodenode;
+			var instance_expression_type = ma.inner.value_type;
 
 			if (instance_expression_type.data_type is Struct
 			    && !((Struct) instance_expression_type.data_type).is_simple_type ()
@@ -109,12 +96,6 @@
 				}
 			}
 
-			// parent_symbol may be null for late bound methods
-			if (base_method.parent_symbol != null) {
-				var instance_target_type = codegen.get_data_type_for_symbol ((TypeSymbol) base_method.parent_symbol);
-				instance = codegen.get_implicit_cast_expression (instance, instance_expression_type, instance_target_type);
-			}
-
 			carg_map.set (codegen.get_param_pos (m.cinstance_parameter_position), instance);
 		} else if (m != null && m.binding == MemberBinding.CLASS) {
 			var cl = (Class) m.parent_symbol;
@@ -192,10 +173,6 @@
 						carg_map.set (codegen.get_param_pos (param.cdelegate_target_parameter_position), codegen.get_delegate_target_cexpression (arg));
 						multiple_cargs = true;
 					}
-					if (param.direction == ParameterDirection.IN) {
-						// don't cast arguments passed by reference
-						cexpr = codegen.get_implicit_cast_expression (cexpr, arg.value_type, param.parameter_type);
-					}
 
 					// pass non-simple struct instances always by reference
 					if (!(arg.value_type is NullType) && param.parameter_type.data_type is Struct && !((Struct) param.parameter_type.data_type).is_simple_type ()) {
@@ -391,8 +368,6 @@
 			} else {
 				expr.ccodenode = ccall_expr;
 			}
-		
-			codegen.visit_expression (expr);
 		}
 		
 		if (m is ArrayResizeMethod) {

Modified: trunk/gobject/valaccodememberaccessbinding.vala
==============================================================================
--- trunk/gobject/valaccodememberaccessbinding.vala	(original)
+++ trunk/gobject/valaccodememberaccessbinding.vala	Wed May 28 19:01:45 2008
@@ -51,7 +51,7 @@
 					return;
 				}
 			}
-			
+
 			if (m.base_method != null) {
 				var binding = method_binding (m.base_method);
 				if (!binding.has_wrapper) {
@@ -84,16 +84,15 @@
 			if (f.binding == MemberBinding.INSTANCE) {
 				var instance_expression_type = base_type;
 				var instance_target_type = codegen.get_data_type_for_symbol ((TypeSymbol) f.parent_symbol);
-				CCodeExpression typed_inst = codegen.get_implicit_cast_expression (pub_inst, instance_expression_type, instance_target_type);
 
 				var cl = instance_target_type.data_type as Class;
 				bool is_gtypeinstance = (cl == null || !cl.is_compact);
 
 				CCodeExpression inst;
 				if (is_gtypeinstance && f.access == SymbolAccessibility.PRIVATE) {
-					inst = new CCodeMemberAccess.pointer (typed_inst, "priv");
+					inst = new CCodeMemberAccess.pointer (pub_inst, "priv");
 				} else {
-					inst = typed_inst;
+					inst = pub_inst;
 				}
 				if (instance_target_type.data_type.is_reference_type () || (expr.inner != null && expr.inner.value_type is PointerType)) {
 					expr.ccodenode = new CCodeMemberAccess.pointer (inst, f.get_cname ());
@@ -140,11 +139,7 @@
 				}
 				var ccall = new CCodeFunctionCall (new CCodeIdentifier (getter_cname));
 
-				var instance_expression_type = base_type;
-				var instance_target_type = codegen.get_data_type_for_symbol (base_property_type);
-				CCodeExpression typed_pub_inst = codegen.get_implicit_cast_expression (pub_inst, instance_expression_type, instance_target_type);
-
-				ccall.add_argument (typed_pub_inst);
+				ccall.add_argument (pub_inst);
 
 				// Property acesses to real struct types are handeled different to other properties.
 				// They are returned as out parameter.
@@ -195,7 +190,12 @@
 		} else if (expr.symbol_reference is FormalParameter) {
 			var p = (FormalParameter) expr.symbol_reference;
 			if (p.name == "this") {
-				expr.ccodenode = pub_inst;
+				var st = codegen.current_type_symbol as Struct;
+				if (st != null && !st.is_simple_type ()) {
+					expr.ccodenode = new CCodeIdentifier ("(*self)");
+				} else {
+					expr.ccodenode = new CCodeIdentifier ("self");
+				}
 			} else {
 				var type_as_struct = p.parameter_type.data_type as Struct;
 				if (p.direction != ParameterDirection.IN
@@ -221,11 +221,8 @@
 			
 			if (sig.has_emitter) {
 				var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_%s".printf (cl.get_lower_case_cname (null), sig.name)));
-				var instance_expression_type = base_type;
-				var instance_target_type = codegen.get_data_type_for_symbol (cl);
-				CCodeExpression typed_pub_inst = codegen.get_implicit_cast_expression (pub_inst, instance_expression_type, instance_target_type);
 
-				ccall.add_argument (typed_pub_inst);
+				ccall.add_argument (pub_inst);
 				expr.ccodenode = ccall;
 			} else {
 				var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_emit_by_name"));
@@ -248,21 +245,7 @@
 		CCodeExpression pub_inst = null;
 		DataType base_type = null;
 	
-		if (expr.inner == null) {
-			pub_inst = new CCodeIdentifier ("self");
-
-			if (codegen.current_type_symbol != null) {
-				/* base type is available if this is a type method */
-				if (codegen.current_type_symbol is Class) {
-					base_type = new ObjectType ((Class) codegen.current_type_symbol);
-				} else if (codegen.current_type_symbol is Interface) {
-					base_type = new ObjectType ((Interface) codegen.current_type_symbol);
-				} else {
-					base_type = new ValueType (codegen.current_type_symbol);
-					pub_inst = new CCodeIdentifier ("(*self)");
-				}
-			}
-		} else {
+		if (expr.inner != null) {
 			pub_inst = (CCodeExpression) expr.inner.ccodenode;
 
 			if (expr.inner.value_type != null) {
@@ -271,8 +254,6 @@
 		}
 
 		process_cmember (expr, pub_inst, base_type);
-
-		codegen.visit_expression (expr);
 	}
 }
 

Modified: trunk/gobject/valaccodemethodbinding.vala
==============================================================================
--- trunk/gobject/valaccodemethodbinding.vala	(original)
+++ trunk/gobject/valaccodemethodbinding.vala	Wed May 28 19:01:45 2008
@@ -234,7 +234,7 @@
 							base_expression_type = new ObjectType ((Interface) base_method.parent_symbol);
 						}
 						var self_target_type = new ObjectType (cl);
-						CCodeExpression cself = codegen.get_implicit_cast_expression (new CCodeIdentifier ("base"), base_expression_type, self_target_type);
+						CCodeExpression cself = codegen.transform_expression (new CCodeIdentifier ("base"), base_expression_type, self_target_type);
 
 						var cdecl = new CCodeDeclaration ("%s *".printf (cl.get_cname ()));
 						cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("self", cself));

Modified: trunk/vala/Makefile.am
==============================================================================
--- trunk/vala/Makefile.am	(original)
+++ trunk/vala/Makefile.am	Wed May 28 19:01:45 2008
@@ -90,7 +90,6 @@
 	valamember.vala \
 	valamemberaccess.vala \
 	valamemberinitializer.vala \
-	valamemorymanager.vala \
 	valamethod.vala \
 	valamethodtype.vala \
 	valanamedargument.vala \

Modified: trunk/vala/valaaddressofexpression.vala
==============================================================================
--- trunk/vala/valaaddressofexpression.vala	(original)
+++ trunk/vala/valaaddressofexpression.vala	Wed May 28 19:01:45 2008
@@ -56,6 +56,8 @@
 		inner.accept (visitor);
 
 		visitor.visit_addressof_expression (this);
+
+		visitor.visit_expression (this);
 	}
 
 	public override void replace_expression (Expression old_node, Expression new_node) {

Modified: trunk/vala/valaarraycreationexpression.vala
==============================================================================
--- trunk/vala/valaarraycreationexpression.vala	(original)
+++ trunk/vala/valaarraycreationexpression.vala	Wed May 28 19:01:45 2008
@@ -93,6 +93,8 @@
 
 	public override void accept (CodeVisitor visitor) {
 		visitor.visit_array_creation_expression (this);
+
+		visitor.visit_expression (this);
 	}
 
 	public override bool is_pure () {

Modified: trunk/vala/valaassignment.vala
==============================================================================
--- trunk/vala/valaassignment.vala	(original)
+++ trunk/vala/valaassignment.vala	Wed May 28 19:01:45 2008
@@ -76,6 +76,8 @@
 	
 	public override void accept (CodeVisitor visitor) {
 		visitor.visit_assignment (this);
+
+		visitor.visit_expression (this);
 	}
 
 	public override void accept_children (CodeVisitor visitor) {

Modified: trunk/vala/valabaseaccess.vala
==============================================================================
--- trunk/vala/valabaseaccess.vala	(original)
+++ trunk/vala/valabaseaccess.vala	Wed May 28 19:01:45 2008
@@ -38,6 +38,8 @@
 	
 	public override void accept (CodeVisitor visitor) {
 		visitor.visit_base_access (this);
+
+		visitor.visit_expression (this);
 	}
 
 	public override string to_string () {

Modified: trunk/vala/valabinaryexpression.vala
==============================================================================
--- trunk/vala/valabinaryexpression.vala	(original)
+++ trunk/vala/valabinaryexpression.vala	Wed May 28 19:01:45 2008
@@ -83,6 +83,8 @@
 		right.accept (visitor);			
 
 		visitor.visit_binary_expression (this);
+
+		visitor.visit_expression (this);
 	}
 
 	public override void replace_expression (Expression old_node, Expression new_node) {

Modified: trunk/vala/valabooleanliteral.vala
==============================================================================
--- trunk/vala/valabooleanliteral.vala	(original)
+++ trunk/vala/valabooleanliteral.vala	Wed May 28 19:01:45 2008
@@ -45,6 +45,8 @@
 	
 	public override void accept (CodeVisitor visitor) {
 		visitor.visit_boolean_literal (this);
+
+		visitor.visit_expression (this);
 	}
 
 	public override string to_string () {

Modified: trunk/vala/valacastexpression.vala
==============================================================================
--- trunk/vala/valacastexpression.vala	(original)
+++ trunk/vala/valacastexpression.vala	Wed May 28 19:01:45 2008
@@ -78,6 +78,8 @@
 		type_reference.accept (visitor);
 
 		visitor.visit_cast_expression (this);
+
+		visitor.visit_expression (this);
 	}
 
 	public override void replace_expression (Expression old_node, Expression new_node) {

Modified: trunk/vala/valacharacterliteral.vala
==============================================================================
--- trunk/vala/valacharacterliteral.vala	(original)
+++ trunk/vala/valacharacterliteral.vala	Wed May 28 19:01:45 2008
@@ -66,6 +66,8 @@
 	
 	public override void accept (CodeVisitor visitor) {
 		visitor.visit_character_literal (this);
+
+		visitor.visit_expression (this);
 	}
 	
 	/**

Modified: trunk/vala/valacodevisitor.vala
==============================================================================
--- trunk/vala/valacodevisitor.vala	(original)
+++ trunk/vala/valacodevisitor.vala	Wed May 28 19:01:45 2008
@@ -404,6 +404,14 @@
 	}
 
 	/**
+	 * Visit operations called for expresions.
+	 *
+	 * @param expr an expression
+	 */
+	public virtual void visit_expression (Expression expr) {
+	}
+
+	/**
 	 * Visit operations called for array creation expresions.
 	 *
 	 * @param expr an array creation expression

Modified: trunk/vala/valaconditionalexpression.vala
==============================================================================
--- trunk/vala/valaconditionalexpression.vala	(original)
+++ trunk/vala/valaconditionalexpression.vala	Wed May 28 19:01:45 2008
@@ -62,6 +62,8 @@
 		false_expression.accept (visitor);			
 
 		visitor.visit_conditional_expression (this);
+
+		visitor.visit_expression (this);
 	}
 
 	public override bool is_pure () {

Modified: trunk/vala/valadatatype.vala
==============================================================================
--- trunk/vala/valadatatype.vala	(original)
+++ trunk/vala/valadatatype.vala	Wed May 28 19:01:45 2008
@@ -40,6 +40,11 @@
 	public bool nullable { get; set; }
 
 	/**
+	 * Specifies that this type is a generic type argument.
+	 */
+	public bool is_type_argument { get; set; }
+
+	/**
 	 * The referred data type.
 	 */
 	public weak TypeSymbol data_type { get; set; }

Modified: trunk/vala/valaelementaccess.vala
==============================================================================
--- trunk/vala/valaelementaccess.vala	(original)
+++ trunk/vala/valaelementaccess.vala	Wed May 28 19:01:45 2008
@@ -59,6 +59,8 @@
 		}
 
 		visitor.visit_element_access (this);
+
+		visitor.visit_expression (this);
 	}
 
 	public override void replace_expression (Expression old_node, Expression new_node) {

Modified: trunk/vala/valaexpression.vala
==============================================================================
--- trunk/vala/valaexpression.vala	(original)
+++ trunk/vala/valaexpression.vala	Wed May 28 19:01:45 2008
@@ -45,27 +45,6 @@
 	 * The symbol this expression refers to.
 	 */
 	public weak Symbol symbol_reference { get; set; }
-	
-	/**
-	 * Specifies that this expression transfers ownership without a receiver
-	 * being present.
-	 *
-	 * The memory manager computes this value, the code generator uses it.
-	 */
-	public bool ref_leaked { get; set; }
-	
-	/**
-	 * Specifies that this expression is expected to transfer ownership but
-	 * doesn't.
-	 *
-	 * The memory manager computes this value, the code generator uses it.
-	 */
-	public bool ref_missing { get; set; }
-	
-	/**
-	 * Specifies that this expression successfully transfers ownership.
-	 */
-	public bool ref_sink { get; set; }
 
 	/**
 	 * Specifies that this expression is used as lvalue, i.e. the

Modified: trunk/vala/valaintegerliteral.vala
==============================================================================
--- trunk/vala/valaintegerliteral.vala	(original)
+++ trunk/vala/valaintegerliteral.vala	Wed May 28 19:01:45 2008
@@ -45,6 +45,8 @@
 	
 	public override void accept (CodeVisitor visitor) {
 		visitor.visit_integer_literal (this);
+
+		visitor.visit_expression (this);
 	}
 
 	public override string to_string () {

Modified: trunk/vala/valaintegertype.vala
==============================================================================
--- trunk/vala/valaintegertype.vala	(original)
+++ trunk/vala/valaintegertype.vala	Wed May 28 19:01:45 2008
@@ -36,6 +36,7 @@
 	public override DataType copy () {
 		var type = new IntegerType (type_symbol);
 		type.literal = literal;
+		type.is_type_argument = is_type_argument;
 		return type;
 	}
 

Modified: trunk/vala/valainvocationexpression.vala
==============================================================================
--- trunk/vala/valainvocationexpression.vala	(original)
+++ trunk/vala/valainvocationexpression.vala	Wed May 28 19:01:45 2008
@@ -93,6 +93,8 @@
 
 	public override void accept (CodeVisitor visitor) {
 		visitor.visit_invocation_expression (this);
+
+		visitor.visit_expression (this);
 	}
 
 	public override void accept_children (CodeVisitor visitor) {

Modified: trunk/vala/valalambdaexpression.vala
==============================================================================
--- trunk/vala/valalambdaexpression.vala	(original)
+++ trunk/vala/valalambdaexpression.vala	Wed May 28 19:01:45 2008
@@ -91,6 +91,8 @@
 	
 	public override void accept (CodeVisitor visitor) {
 		visitor.visit_lambda_expression (this);
+
+		visitor.visit_expression (this);
 	}
 
 	public override void accept_children (CodeVisitor visitor) {

Modified: trunk/vala/valamemberaccess.vala
==============================================================================
--- trunk/vala/valamemberaccess.vala	(original)
+++ trunk/vala/valamemberaccess.vala	Wed May 28 19:01:45 2008
@@ -126,6 +126,8 @@
 		}
 
 		visitor.visit_member_access (this);
+
+		visitor.visit_expression (this);
 	}
 
 	public override string to_string () {

Modified: trunk/vala/valanullchecker.vala
==============================================================================
--- trunk/vala/valanullchecker.vala	(original)
+++ trunk/vala/valanullchecker.vala	Wed May 28 19:01:45 2008
@@ -200,11 +200,7 @@
 		var mtype = expr.call.value_type as MethodType;
 		var ma = expr.call as MemberAccess;
 		if (mtype != null && mtype.method_symbol.binding == MemberBinding.INSTANCE && ma != null) {
-			if (ma.inner == null) {
-				// implicit this call, always non-null
-			} else {
-				check_non_null (ma.inner);
-			}
+			check_non_null (ma.inner);
 		}
 	}
 

Modified: trunk/vala/valanullliteral.vala
==============================================================================
--- trunk/vala/valanullliteral.vala	(original)
+++ trunk/vala/valanullliteral.vala	Wed May 28 19:01:45 2008
@@ -38,6 +38,8 @@
 	
 	public override void accept (CodeVisitor visitor) {
 		visitor.visit_null_literal (this);
+
+		visitor.visit_expression (this);
 	}
 
 	public override string to_string () {

Modified: trunk/vala/valanulltype.vala
==============================================================================
--- trunk/vala/valanulltype.vala	(original)
+++ trunk/vala/valanulltype.vala	Wed May 28 19:01:45 2008
@@ -60,4 +60,8 @@
 	public override string? get_cname () {
 		return "gpointer";
 	}
+
+	public override bool is_disposable () {
+		return false;
+	}
 }

Modified: trunk/vala/valaobjectcreationexpression.vala
==============================================================================
--- trunk/vala/valaobjectcreationexpression.vala	(original)
+++ trunk/vala/valaobjectcreationexpression.vala	Wed May 28 19:01:45 2008
@@ -110,6 +110,8 @@
 
 	public override void accept (CodeVisitor visitor) {
 		visitor.visit_object_creation_expression (this);
+
+		visitor.visit_expression (this);
 	}
 
 	public override void accept_children (CodeVisitor visitor) {

Modified: trunk/vala/valaparenthesizedexpression.vala
==============================================================================
--- trunk/vala/valaparenthesizedexpression.vala	(original)
+++ trunk/vala/valaparenthesizedexpression.vala	Wed May 28 19:01:45 2008
@@ -55,6 +55,8 @@
 	
 	public override void accept (CodeVisitor visitor) {
 		visitor.visit_parenthesized_expression (this);
+
+		visitor.visit_expression (this);
 	}
 
 	public override void accept_children (CodeVisitor visitor) {

Modified: trunk/vala/valapointerindirection.vala
==============================================================================
--- trunk/vala/valapointerindirection.vala	(original)
+++ trunk/vala/valapointerindirection.vala	Wed May 28 19:01:45 2008
@@ -56,6 +56,8 @@
 		inner.accept (visitor);
 
 		visitor.visit_pointer_indirection (this);
+
+		visitor.visit_expression (this);
 	}
 
 	public override void replace_expression (Expression old_node, Expression new_node) {

Modified: trunk/vala/valapostfixexpression.vala
==============================================================================
--- trunk/vala/valapostfixexpression.vala	(original)
+++ trunk/vala/valapostfixexpression.vala	Wed May 28 19:01:45 2008
@@ -54,6 +54,8 @@
 		inner.accept (visitor);
 
 		visitor.visit_postfix_expression (this);
+
+		visitor.visit_expression (this);
 	}
 
 	public override bool is_pure () {

Modified: trunk/vala/valarealliteral.vala
==============================================================================
--- trunk/vala/valarealliteral.vala	(original)
+++ trunk/vala/valarealliteral.vala	Wed May 28 19:01:45 2008
@@ -45,6 +45,8 @@
 	
 	public override void accept (CodeVisitor visitor) {
 		visitor.visit_real_literal (this);
+
+		visitor.visit_expression (this);
 	}
 	
 	/**

Modified: trunk/vala/valareferencetransferexpression.vala
==============================================================================
--- trunk/vala/valareferencetransferexpression.vala	(original)
+++ trunk/vala/valareferencetransferexpression.vala	Wed May 28 19:01:45 2008
@@ -54,6 +54,8 @@
 	
 	public override void accept (CodeVisitor visitor) {
 		visitor.visit_reference_transfer_expression (this);
+
+		visitor.visit_expression (this);
 	}
 	
 	public override void accept_children (CodeVisitor visitor) {

Modified: trunk/vala/valasemanticanalyzer.vala
==============================================================================
--- trunk/vala/valasemanticanalyzer.vala	(original)
+++ trunk/vala/valasemanticanalyzer.vala	Wed May 28 19:01:45 2008
@@ -59,6 +59,10 @@
 
 	private int next_lambda_id = 0;
 
+	// keep replaced alive to make sure they remain valid
+	// for the whole execution of CodeNode.accept
+	Gee.List<CodeNode> replaced_nodes = new ArrayList<CodeNode> ();
+
 	public SemanticAnalyzer () {
 	}
 
@@ -344,6 +348,10 @@
 	}
 
 	public override void visit_field (Field f) {
+		if (f.initializer != null) {
+			f.initializer.target_type = f.field_type;
+		}
+
 		f.accept_children (this);
 
 		if (f.binding == MemberBinding.INSTANCE && f.parent_symbol is Interface) {
@@ -747,6 +755,9 @@
 
 			local.variable_type = local.initializer.value_type.copy ();
 			local.variable_type.value_owned = true;
+			local.variable_type.floating_reference = false;
+
+			local.initializer.target_type = local.variable_type;
 		}
 
 		if (local.initializer != null) {
@@ -1008,6 +1019,7 @@
 		}
 
 		var collection_type = stmt.collection.value_type.copy ();
+		stmt.collection.target_type = collection_type.copy ();
 		
 		DataType element_data_type = null;
 	
@@ -1090,6 +1102,10 @@
 	}
 
 	public override void visit_return_statement (ReturnStatement stmt) {
+		if (stmt.return_expression != null) {
+			stmt.return_expression.target_type = current_return_type;
+		}
+
 		stmt.accept_children (this);
 
 		if (stmt.return_expression != null && stmt.return_expression.error) {
@@ -1456,10 +1472,14 @@
 		expr.value_type = expr.inner.value_type.copy ();
 		// don't call g_object_ref_sink on inner and outer expression
 		expr.value_type.floating_reference = false;
+
+		// don't transform expression twice
+		expr.inner.target_type = expr.inner.value_type.copy ();
 	}
 	
 	public override void visit_member_access (MemberAccess expr) {
 		Symbol base_symbol = null;
+		FormalParameter this_parameter = null;
 		bool may_access_instance_members = false;
 
 		expr.symbol_reference = null;
@@ -1480,11 +1500,28 @@
 
 			var sym = current_symbol;
 			while (sym != null && expr.symbol_reference == null) {
-				if (sym is CreationMethod || sym is Property || sym is Constructor || sym is Destructor) {
-					may_access_instance_members = true;
-				} else if (sym is Method) {
-					var m = (Method) sym;
-					may_access_instance_members = (m.binding == MemberBinding.INSTANCE);
+				if (this_parameter == null) {
+					if (sym is CreationMethod) {
+						var cm = (CreationMethod) sym;
+						this_parameter = cm.this_parameter;
+						may_access_instance_members = true;
+					} else if (sym is Property) {
+						var prop = (Property) sym;
+						this_parameter = prop.this_parameter;
+						may_access_instance_members = true;
+					} else if (sym is Constructor) {
+						var c = (Constructor) sym;
+						this_parameter = c.this_parameter;
+						may_access_instance_members = true;
+					} else if (sym is Destructor) {
+						var d = (Destructor) sym;
+						this_parameter = d.this_parameter;
+						may_access_instance_members = true;
+					} else if (sym is Method) {
+						var m = (Method) sym;
+						this_parameter = m.this_parameter;
+						may_access_instance_members = (m.binding == MemberBinding.INSTANCE);
+					}
 				}
 
 				expr.symbol_reference = symbol_lookup_inherited (sym, expr.member_name);
@@ -1715,6 +1752,13 @@
 				expr.value_type = new FieldPrototype ((Field) expr.symbol_reference);
 			}
 		} else {
+			// implicit this access
+			if (instance && expr.inner == null) {
+				expr.inner = new MemberAccess (null, "this", expr.source_reference);
+				expr.inner.value_type = this_parameter.parameter_type.copy ();
+				expr.inner.symbol_reference = this_parameter;
+			}
+
 			expr.value_type = get_value_type_for_symbol (expr.symbol_reference, expr.lvalue);
 
 			// resolve generic return values
@@ -1726,11 +1770,66 @@
 					}
 				}
 			}
+
+			if (expr.symbol_reference is Method) {
+				var m = (Method) expr.symbol_reference;
+
+				Method base_method;
+				if (m.base_method != null) {
+					base_method = m.base_method;
+				} else if (m.base_interface_method != null) {
+					base_method = m.base_interface_method;
+				} else {
+					base_method = m;
+				}
+
+				if (instance && base_method.parent_symbol != null) {
+					expr.inner.target_type = get_data_type_for_symbol ((TypeSymbol) base_method.parent_symbol);
+				}
+			} else if (expr.symbol_reference is Property) {
+				var prop = (Property) expr.symbol_reference;
+
+				Property base_property;
+				if (prop.base_property != null) {
+					base_property = prop.base_property;
+				} else if (prop.base_interface_property != null) {
+					base_property = prop.base_interface_property;
+				} else {
+					base_property = prop;
+				}
+
+				if (instance && base_property.parent_symbol != null) {
+					expr.inner.target_type = get_data_type_for_symbol ((TypeSymbol) base_property.parent_symbol);
+				}
+			} else if ((expr.symbol_reference is Field
+			            || expr.symbol_reference is Signal)
+			           && instance && expr.symbol_reference.parent_symbol != null) {
+				expr.inner.target_type = get_data_type_for_symbol ((TypeSymbol) expr.symbol_reference.parent_symbol);
+			}
 		}
 
 		current_source_file.add_symbol_dependency (expr.symbol_reference, SourceFileDependencyType.SOURCE);
 	}
 
+	public static DataType get_data_type_for_symbol (TypeSymbol sym) {
+		DataType type = null;
+
+		if (sym is ObjectTypeSymbol) {
+			type = new ObjectType ((ObjectTypeSymbol) sym);
+		} else if (sym is Struct) {
+			type = new ValueType ((Struct) sym);
+		} else if (sym is Enum) {
+			type = new ValueType ((Enum) sym);
+		} else if (sym is ErrorDomain) {
+			type = new ErrorType ((ErrorDomain) sym);
+		} else {
+			Report.error (null, "internal error: `%s' is not a supported type".printf (sym.get_full_name ()));
+			return new InvalidType ();
+		}
+
+		return type;
+	}
+
 	public override void visit_invocation_expression (InvocationExpression expr) {
 		expr.call.accept (this);
 
@@ -1760,6 +1859,8 @@
 			foreach (Expression arg in expr.get_argument_list ()) {
 				struct_creation_expression.add_argument (arg);
 			}
+			struct_creation_expression.target_type = expr.target_type;
+			replaced_nodes.add (expr);
 			expr.parent_node.replace_expression (expr, struct_creation_expression);
 			struct_creation_expression.accept (this);
 			return;
@@ -1787,6 +1888,15 @@
 
 				/* store expected type for callback parameters */
 				arg.target_type = param.parameter_type;
+
+				// resolve generic type parameters
+				var ma = expr.call as MemberAccess;
+				if (arg.target_type.type_parameter != null) {
+					if (ma != null && ma.inner != null) {
+						arg.target_type = get_actual_type (ma.inner.value_type, ma.symbol_reference, arg.target_type, arg);
+						assert (arg.target_type != null);
+					}
+				}
 			}
 		}
 
@@ -1887,10 +1997,10 @@
 						Report.error (arg.source_reference, "Invalid type for argument %d".printf (i + 1));
 						return false;
 					}
-				} else if (!arg.value_type.compatible (param.parameter_type)
+				} else if (arg.target_type != null && !arg.value_type.compatible (arg.target_type)
 				           && !(arg is NullLiteral && param.direction == ParameterDirection.OUT)) {
 					expr.error = true;
-					Report.error (arg.source_reference, "Argument %d: Cannot convert from `%s' to `%s'".printf (i + 1, arg.value_type.to_string (), param.parameter_type.to_string ()));
+					Report.error (arg.source_reference, "Argument %d: Cannot convert from `%s' to `%s'".printf (i + 1, arg.value_type.to_string (), arg.target_type.to_string ()));
 					return false;
 				} else {
 					// 0 => null, 1 => in, 2 => ref, 3 => out
@@ -2104,6 +2214,7 @@
 			return generic_type;
 		}
 		actual_type = actual_type.copy ();
+		actual_type.is_type_argument = true;
 		actual_type.value_owned = actual_type.value_owned && generic_type.value_owned;
 		return actual_type;
 	}
@@ -2569,6 +2680,8 @@
 
 			var assignment = new Assignment (ma, bin, AssignmentOperator.SIMPLE, expr.source_reference);
 			var parenthexp = new ParenthesizedExpression (assignment, expr.source_reference);
+			parenthexp.target_type = expr.target_type;
+			replaced_nodes.add (expr);
 			expr.parent_node.replace_expression (expr, parenthexp);
 			parenthexp.accept (this);
 			return;
@@ -2613,6 +2726,8 @@
 
 		expr.value_type = expr.type_reference;
 		expr.value_type.value_owned = expr.inner.value_type.value_owned;
+
+		expr.inner.target_type = expr.inner.value_type.copy ();
 	}
 
 	public override void visit_pointer_indirection (PointerIndirection expr) {
@@ -2749,7 +2864,9 @@
 
 			var concat_call = new InvocationExpression (new MemberAccess (expr.left, "concat"));
 			concat_call.add_argument (expr.right);
+			concat_call.target_type = expr.target_type;
 
+			replaced_nodes.add (expr);
 			expr.parent_node.replace_expression (expr, concat_call);
 
 			concat_call.accept (this);
@@ -3018,9 +3135,9 @@
 				a.right.target_type = ma.value_type;
 			}
 		} else if (a.left is ElementAccess) {
-			// do nothing
+			a.right.target_type = a.left.value_type;
 		} else if (a.left is PointerIndirection) {
-			// do nothing
+			a.right.target_type = a.left.value_type;
 		} else {
 			a.error = true;
 			Report.error (a.source_reference, "unsupported lvalue in assignment");
@@ -3046,6 +3163,9 @@
 				var old_value = new MemberAccess (ma.inner, ma.member_name);
 
 				var bin = new BinaryExpression (BinaryOperator.PLUS, old_value, new ParenthesizedExpression (a.right, a.right.source_reference));
+				bin.target_type = a.right.target_type;
+				a.right.target_type = a.right.target_type.copy ();
+				a.right.target_type.value_owned = false;
 
 				if (a.operator == AssignmentOperator.BITWISE_OR) {
 					bin.operator = BinaryOperator.BITWISE_OR;
@@ -3225,10 +3345,7 @@
 
 		if (a.left.value_type != null) {
 			a.value_type = a.left.value_type.copy ();
-			if (a.parent_node is ExpressionStatement) {
-				// Gee.List.get () transfers ownership but void function Gee.List.set () doesn't
-				a.value_type.value_owned = false;
-			}
+			a.value_type.value_owned = false;
 		} else {
 			a.value_type = null;
 		}

Modified: trunk/vala/valasignal.vala
==============================================================================
--- trunk/vala/valasignal.vala	(original)
+++ trunk/vala/valasignal.vala	Wed May 28 19:01:45 2008
@@ -108,6 +108,8 @@
 			foreach (FormalParameter param in parameters) {
 				generated_delegate.add_parameter (param);
 			}
+
+			scope.add (null, generated_delegate);
 		}
 		
 		return generated_delegate;

Modified: trunk/vala/valasizeofexpression.vala
==============================================================================
--- trunk/vala/valasizeofexpression.vala	(original)
+++ trunk/vala/valasizeofexpression.vala	Wed May 28 19:01:45 2008
@@ -55,6 +55,8 @@
 		type_reference.accept (visitor);
 	
 		visitor.visit_sizeof_expression (this);
+
+		visitor.visit_expression (this);
 	}
 
 	public override bool is_pure () {

Modified: trunk/vala/valastringliteral.vala
==============================================================================
--- trunk/vala/valastringliteral.vala	(original)
+++ trunk/vala/valastringliteral.vala	Wed May 28 19:01:45 2008
@@ -61,6 +61,8 @@
 	
 	public override void accept (CodeVisitor visitor) {
 		visitor.visit_string_literal (this);
+
+		visitor.visit_expression (this);
 	}
 
 	public override bool is_pure () {

Modified: trunk/vala/valatypecheck.vala
==============================================================================
--- trunk/vala/valatypecheck.vala	(original)
+++ trunk/vala/valatypecheck.vala	Wed May 28 19:01:45 2008
@@ -64,6 +64,8 @@
 		type_reference.accept (visitor);
 	
 		visitor.visit_type_check (this);
+
+		visitor.visit_expression (this);
 	}
 
 	public override bool is_pure () {

Modified: trunk/vala/valatypeofexpression.vala
==============================================================================
--- trunk/vala/valatypeofexpression.vala	(original)
+++ trunk/vala/valatypeofexpression.vala	Wed May 28 19:01:45 2008
@@ -55,6 +55,8 @@
 		type_reference.accept (visitor);
 	
 		visitor.visit_typeof_expression (this);
+
+		visitor.visit_expression (this);
 	}
 
 	public override bool is_pure () {

Modified: trunk/vala/valaunaryexpression.vala
==============================================================================
--- trunk/vala/valaunaryexpression.vala	(original)
+++ trunk/vala/valaunaryexpression.vala	Wed May 28 19:01:45 2008
@@ -66,6 +66,8 @@
 		inner.accept (visitor);
 	
 		visitor.visit_unary_expression (this);
+
+		visitor.visit_expression (this);
 	}
 
 	public override void replace_expression (Expression old_node, Expression new_node) {

Modified: trunk/vala/valaunresolvedtype.vala
==============================================================================
--- trunk/vala/valaunresolvedtype.vala	(original)
+++ trunk/vala/valaunresolvedtype.vala	Wed May 28 19:01:45 2008
@@ -72,6 +72,8 @@
 			}
 			
 			if (type_ref != null) {
+				type_ref.value_owned = true;
+
 				var type_args = ma.get_type_arguments ();
 				foreach (DataType arg in type_args) {
 					type_ref.add_type_argument (arg);

Modified: trunk/vala/valavaluetype.vala
==============================================================================
--- trunk/vala/valavaluetype.vala	(original)
+++ trunk/vala/valavaluetype.vala	Wed May 28 19:01:45 2008
@@ -43,6 +43,7 @@
 		result.nullable = nullable;
 		result.is_dynamic = is_dynamic;
 		result.floating_reference = floating_reference;
+		result.is_type_argument = is_type_argument;
 		
 		foreach (DataType arg in get_type_arguments ()) {
 			result.add_type_argument (arg.copy ());



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]