[vala] codegen: Use builder API
- From: Jürg Billeter <juergbi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala] codegen: Use builder API
- Date: Thu, 9 Sep 2010 14:48:25 +0000 (UTC)
commit 7a429688cdf0fd16cc1503a7666681792e309da8
Author: Jürg Billeter <j bitron ch>
Date: Sat Aug 14 15:24:18 2010 +0200
codegen: Use builder API
codegen/valaccodearraymodule.vala | 84 ++---
codegen/valaccodeassignmentmodule.vala | 4 +-
codegen/valaccodebasemodule.vala | 634 +++++++++++-------------------
codegen/valaccodecontrolflowmodule.vala | 295 +++++---------
codegen/valaccodememberaccessmodule.vala | 12 +-
codegen/valaccodemethodcallmodule.vala | 47 +--
codegen/valaccodemethodmodule.vala | 345 ++++++++---------
codegen/valaccodestructmodule.vala | 25 +-
codegen/valadovaarraymodule.vala | 2 +-
codegen/valadovaassignmentmodule.vala | 4 +-
codegen/valadovabasemodule.vala | 409 ++++++--------------
codegen/valadovacontrolflowmodule.vala | 54 +--
codegen/valadovaerrormodule.vala | 153 +++-----
codegen/valadovamemberaccessmodule.vala | 2 +-
codegen/valadovamethodcallmodule.vala | 10 +-
codegen/valadovaobjectmodule.vala | 142 ++++---
codegen/valadovastructmodule.vala | 5 -
codegen/valadovavaluemodule.vala | 17 +-
codegen/valagasyncmodule.vala | 221 ++++-------
codegen/valagerrormodule.vala | 187 ++++------
codegen/valagobjectmodule.vala | 94 ++---
codegen/valagsignalmodule.vala | 6 +-
codegen/valagtypemodule.vala | 372 ++++++++++--------
vala/valablock.vala | 4 +
vala/valaexpression.vala | 17 +-
vala/valamethod.vala | 2 +
vala/valamethodcall.vala | 1 +
vala/valayieldstatement.vala | 2 +
28 files changed, 1268 insertions(+), 1882 deletions(-)
---
diff --git a/codegen/valaccodearraymodule.vala b/codegen/valaccodearraymodule.vala
index 1a5f239..6db8f30 100644
--- a/codegen/valaccodearraymodule.vala
+++ b/codegen/valaccodearraymodule.vala
@@ -48,7 +48,7 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
var name_cnode = get_variable_cexpression (temp_var.name);
int i = 0;
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
append_initializer_list (ce, name_cnode, expr.initializer_list, expr.rank, ref i);
@@ -80,7 +80,7 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
var name_cnode = get_variable_cexpression (temp_var.name);
size.ccodenode = name_cnode;
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
csize = new CCodeAssignment (name_cnode, csize);
}
@@ -112,7 +112,7 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
var name_cnode = get_variable_cexpression (temp_var.name);
int i = 0;
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ce.append_expression (new CCodeAssignment (name_cnode, gnew));
@@ -428,15 +428,15 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
var len_var = get_temp_variable (int_type);
len_var.source_reference = expr.source_reference;
- temp_vars.add (len_var);
+ emit_temp_var (len_var);
var slice_var = get_temp_variable (expr.value_type, true, expr);
- temp_vars.add (slice_var);
+ emit_temp_var (slice_var);
if (!is_pure_ccode_expression (cstart)) {
// avoid double evaluation of start
var start_var = get_temp_variable (int_type);
- temp_vars.add (start_var);
+ emit_temp_var (start_var);
var start_assignment = new CCodeAssignment (get_variable_cexpression (start_var.name), cstart);
ccomma.append_expression (start_assignment);
@@ -674,7 +674,7 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
}
var decl = get_temp_variable (expression_type, false, node);
- temp_vars.add (decl);
+ emit_temp_var (decl);
var ctemp = get_variable_cexpression (decl.name);
@@ -752,14 +752,11 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
// definition
- var block = new CCodeBlock ();
+ push_context (new EmitContext ());
+ push_function (function);
if (requires_copy (array_type.element_type)) {
- push_context (new EmitContext ());
-
- var cdecl = new CCodeDeclaration (array_type.get_cname ());
var cvardecl = new CCodeVariableDeclarator ("result");
- cdecl.add_declarator (cvardecl);
var gnew = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
gnew.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ()));
@@ -770,28 +767,19 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
}
gnew.add_argument (length_expr);
- cvardecl.initializer = gnew;
- block.add_statement (cdecl);
-
- var idx_decl = new CCodeDeclaration ("int");
- idx_decl.add_declarator (new CCodeVariableDeclarator ("i"));
- block.add_statement (idx_decl);
-
- var loop_body = new CCodeBlock ();
- loop_body.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeElementAccess (new CCodeIdentifier ("result"), new CCodeIdentifier ("i")), get_ref_cexpression (array_type.element_type, new CCodeElementAccess (new CCodeIdentifier ("self"), new CCodeIdentifier ("i")), null, array_type))));
+ ccode.add_declaration (array_type.get_cname (), cvardecl);
+ ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("result"), gnew));
- var cfor = new CCodeForStatement (new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier ("i"), new CCodeIdentifier ("length")), loop_body);
- cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier ("i"), new CCodeConstant ("0")));
- cfor.add_iterator (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier ("i")));
- block.add_statement (cfor);
+ ccode.add_declaration ("int", new CCodeVariableDeclarator ("i"));
- block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
+ ccode.open_for (new CCodeAssignment (new CCodeIdentifier ("i"), new CCodeConstant ("0")),
+ new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier ("i"), new CCodeIdentifier ("length")),
+ new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier ("i")));
- var cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
- block.add_statement (cfrag);
+ ccode.add_expression (new CCodeAssignment (new CCodeElementAccess (new CCodeIdentifier ("result"), new CCodeIdentifier ("i")), get_ref_cexpression (array_type.element_type, new CCodeElementAccess (new CCodeIdentifier ("self"), new CCodeIdentifier ("i")), null, array_type)));
+ ccode.close ();
- pop_context ();
+ ccode.add_return (new CCodeIdentifier ("result"));
} else {
var dup_call = new CCodeFunctionCall (new CCodeIdentifier ("g_memdup"));
dup_call.add_argument (new CCodeIdentifier ("self"));
@@ -800,16 +788,16 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
sizeof_call.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ()));
dup_call.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new CCodeIdentifier ("length"), sizeof_call));
- block.add_statement (new CCodeReturnStatement (dup_call));
+ ccode.add_return (dup_call);
}
// append to file
cfile.add_function_declaration (function);
-
- function.block = block;
cfile.add_function (function);
+ pop_context ();
+
return dup_func;
}
@@ -831,28 +819,18 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
// definition
- var block = new CCodeBlock ();
+ push_context (new EmitContext ());
+ push_function (function);
if (requires_copy (array_type.element_type)) {
- push_context (new EmitContext ());
-
- var idx_decl = new CCodeDeclaration ("int");
- idx_decl.add_declarator (new CCodeVariableDeclarator ("i"));
- block.add_statement (idx_decl);
-
- var loop_body = new CCodeBlock ();
- loop_body.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeElementAccess (new CCodeIdentifier ("dest"), new CCodeIdentifier ("i")), get_ref_cexpression (array_type.element_type, new CCodeElementAccess (new CCodeIdentifier ("self"), new CCodeIdentifier ("i")), null, array_type))));
+ ccode.add_declaration ("int", new CCodeVariableDeclarator ("i"));
- var cfor = new CCodeForStatement (new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier ("i"), new CCodeConstant ("%d".printf (array_type.length))), loop_body);
- cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier ("i"), new CCodeConstant ("0")));
- cfor.add_iterator (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier ("i")));
- block.add_statement (cfor);
+ ccode.open_for (new CCodeAssignment (new CCodeIdentifier ("i"), new CCodeConstant ("0")),
+ new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier ("i"), new CCodeConstant ("%d".printf (array_type.length))),
+ new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier ("i")));
- var cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
- block.add_statement (cfrag);
- pop_context ();
+ ccode.add_expression (new CCodeAssignment (new CCodeElementAccess (new CCodeIdentifier ("dest"), new CCodeIdentifier ("i")), get_ref_cexpression (array_type.element_type, new CCodeElementAccess (new CCodeIdentifier ("self"), new CCodeIdentifier ("i")), null, array_type)));
} else {
cfile.add_include ("string.h");
@@ -864,16 +842,16 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
sizeof_call.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ()));
dup_call.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new CCodeConstant ("%d".printf (array_type.length)), sizeof_call));
- block.add_statement (new CCodeExpressionStatement (dup_call));
+ ccode.add_expression (dup_call);
}
// append to file
cfile.add_function_declaration (function);
-
- function.block = block;
cfile.add_function (function);
+ pop_context ();
+
return dup_func;
}
diff --git a/codegen/valaccodeassignmentmodule.vala b/codegen/valaccodeassignmentmodule.vala
index 20ed409..a403ada 100644
--- a/codegen/valaccodeassignmentmodule.vala
+++ b/codegen/valaccodeassignmentmodule.vala
@@ -126,13 +126,13 @@ public class Vala.CCodeAssignmentModule : CCodeMemberAccessModule {
var lhs_value_type = assignment.left.value_type.copy ();
string lhs_temp_name = "_tmp%d_".printf (next_temp_var_id++);
var lhs_temp = new LocalVariable (lhs_value_type, "*" + lhs_temp_name);
- temp_vars.add (lhs_temp);
+ emit_temp_var (lhs_temp);
outer_ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (lhs_temp_name), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, lhs)));
lhs = new CCodeParenthesizedExpression (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, get_variable_cexpression (lhs_temp_name)));
}
var temp_decl = get_temp_variable (assignment.left.value_type, true, null, false);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_decl.name), rhs));
if (unref_old) {
/* unref old value */
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index c23ebe2..4015c00 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -31,8 +31,8 @@ public class Vala.CCodeBaseModule : CodeGenerator {
public Symbol? current_symbol;
public ArrayList<Symbol> symbol_stack = new ArrayList<Symbol> ();
public TryStatement current_try;
- public CCodeSwitchStatement state_switch_statement;
- public ArrayList<LocalVariable> temp_vars = new ArrayList<LocalVariable> ();
+ public CCodeFunction ccode;
+ public ArrayList<CCodeFunction> ccode_stack = new ArrayList<CCodeFunction> ();
public ArrayList<LocalVariable> temp_ref_vars = new ArrayList<LocalVariable> ();
public int next_temp_var_id;
public bool current_method_inner_error;
@@ -152,30 +152,19 @@ public class Vala.CCodeBaseModule : CodeGenerator {
public CCodeFile internal_header_file;
public CCodeFile cfile;
- public CCodeFragment class_init_fragment;
- public CCodeFragment base_init_fragment;
- public CCodeFragment class_finalize_fragment;
- public CCodeFragment base_finalize_fragment;
- public CCodeFragment instance_init_fragment;
- public CCodeFragment instance_finalize_fragment;
+ public EmitContext class_init_context;
+ public EmitContext base_init_context;
+ public EmitContext class_finalize_context;
+ public EmitContext base_finalize_context;
+ public EmitContext instance_init_context;
+ public EmitContext instance_finalize_context;
public CCodeStruct param_spec_struct;
public CCodeStruct closure_struct;
public CCodeEnum prop_enum;
- public CCodeFunction function;
- // code nodes to be inserted before the current statement
- // used by async method calls in coroutines
- public CCodeFragment pre_statement_fragment;
+ public CCodeFunction ccode { get { return emit_context.ccode; } }
- // case statements to be inserted for the couroutine state
- public CCodeSwitchStatement state_switch_statement {
- get { return emit_context.state_switch_statement; }
- set { emit_context.state_switch_statement = value; }
- }
-
- /* all temporary variables */
- public ArrayList<LocalVariable> temp_vars { get { return emit_context.temp_vars; } }
/* temporary variables that own their content */
public ArrayList<LocalVariable> temp_ref_vars { get { return emit_context.temp_ref_vars; } }
/* cache to check whether a certain marshaller has been created yet */
@@ -483,6 +472,16 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
}
+ public void push_function (CCodeFunction func) {
+ emit_context.ccode_stack.add (ccode);
+ emit_context.ccode = func;
+ }
+
+ public void pop_function () {
+ emit_context.ccode = emit_context.ccode_stack[emit_context.ccode_stack.size - 1];
+ emit_context.ccode_stack.remove_at (emit_context.ccode_stack.size - 1);
+ }
+
public bool add_symbol_declaration (CCodeFile decl_space, Symbol sym, string name) {
if (decl_space.add_declaration (name)) {
return true;
@@ -726,13 +725,13 @@ public class Vala.CCodeBaseModule : CodeGenerator {
/* stuff meant for all lockable members */
if (m is Lockable && ((Lockable) m).get_lock_used ()) {
CCodeExpression l = new CCodeIdentifier ("self");
- CCodeFragment init_fragment = class_init_fragment;
- CCodeFragment finalize_fragment = class_finalize_fragment;
+ var init_context = class_init_context;
+ var finalize_context = class_finalize_context;
if (m.is_instance_member ()) {
l = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (l, "priv"), get_symbol_lock_name (m.name));
- init_fragment = instance_init_fragment;
- finalize_fragment = instance_finalize_fragment;
+ init_context = instance_init_context;
+ finalize_context = instance_finalize_context;
} else if (m.is_class_member ()) {
TypeSymbol parent = (TypeSymbol)m.parent_symbol;
@@ -743,14 +742,18 @@ public class Vala.CCodeBaseModule : CodeGenerator {
l = new CCodeIdentifier (get_symbol_lock_name ("%s_%s".printf(m.parent_symbol.get_lower_case_cname (), m.name)));
}
+ push_context (init_context);
var initf = new CCodeFunctionCall (new CCodeIdentifier (mutex_type.default_construction_method.get_cname ()));
initf.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, l));
- init_fragment.append (new CCodeExpressionStatement (initf));
+ ccode.add_expression (initf);
+ pop_context ();
- if (finalize_fragment != null) {
+ if (finalize_context != null) {
+ push_context (finalize_context);
var fc = new CCodeFunctionCall (new CCodeIdentifier ("g_static_rec_mutex_free"));
fc.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, l));
- finalize_fragment.append (new CCodeExpressionStatement (fc));
+ ccode.add_expression (fc);
+ pop_context ();
}
}
}
@@ -894,10 +897,6 @@ public class Vala.CCodeBaseModule : CodeGenerator {
check_type (f.variable_type);
- if (f.initializer != null) {
- f.initializer.emit (this);
- }
-
var cl = f.parent_symbol as Class;
bool is_gtypeinstance = (cl != null && !cl.is_compact);
@@ -916,9 +915,13 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
if (f.initializer != null) {
+ push_context (instance_init_context);
+
+ f.initializer.emit (this);
+
var rhs = (CCodeExpression) f.initializer.ccodenode;
- instance_init_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (lhs, rhs)));
+ ccode.add_expression (new CCodeAssignment (lhs, rhs));
if (f.variable_type is ArrayType && !f.no_array_length &&
f.initializer is ArrayCreationExpression) {
@@ -933,30 +936,31 @@ public class Vala.CCodeBaseModule : CodeGenerator {
for (int dim = 1; dim <= array_type.rank; dim++) {
var array_len_lhs = get_array_length_cexpression (ma, dim);
var size = sizes[dim - 1];
- instance_init_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (array_len_lhs, (CCodeExpression) size.ccodenode)));
+ ccode.add_expression (new CCodeAssignment (array_len_lhs, (CCodeExpression) size.ccodenode));
}
if (array_type.rank == 1 && f.is_internal_symbol ()) {
var lhs_array_size = get_array_size_cexpression (ma);
var rhs_array_len = get_array_length_cexpression (ma, 1);
- instance_init_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (lhs_array_size, rhs_array_len)));
+ ccode.add_expression (new CCodeAssignment (lhs_array_size, rhs_array_len));
}
}
- append_temp_decl (instance_init_fragment, temp_vars);
-
foreach (LocalVariable local in temp_ref_vars) {
var ma = new MemberAccess.simple (local.name);
ma.symbol_reference = local;
ma.value_type = local.variable_type.copy ();
- instance_init_fragment.append (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma)));
+ ccode.add_expression (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma));
}
- temp_vars.clear ();
temp_ref_vars.clear ();
+
+ pop_context ();
}
- if (requires_destroy (f.variable_type) && instance_finalize_fragment != null) {
+ if (requires_destroy (f.variable_type) && instance_finalize_context != null) {
+ push_context (instance_finalize_context);
+
var this_access = new MemberAccess.simple ("this");
this_access.value_type = get_data_type_for_symbol ((TypeSymbol) f.parent_symbol);
@@ -970,7 +974,9 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var ma = new MemberAccess (this_access, f.name);
ma.symbol_reference = f;
ma.value_type = f.variable_type.copy ();
- instance_finalize_fragment.append (new CCodeExpressionStatement (get_unref_expression (lhs, f.variable_type, ma)));
+ ccode.add_expression (get_unref_expression (lhs, f.variable_type, ma));
+
+ pop_context ();
}
} else if (f.binding == MemberBinding.CLASS) {
if (!is_gtypeinstance) {
@@ -988,21 +994,24 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
if (f.initializer != null) {
- var rhs = (CCodeExpression) f.initializer.ccodenode;
+ push_context (class_init_context);
+
+ f.initializer.emit (this);
- class_init_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (lhs, rhs)));
+ var rhs = (CCodeExpression) f.initializer.ccodenode;
- append_temp_decl (class_init_fragment, temp_vars);
+ ccode.add_expression (new CCodeAssignment (lhs, rhs));
foreach (LocalVariable local in temp_ref_vars) {
var ma = new MemberAccess.simple (local.name);
ma.symbol_reference = local;
ma.value_type = local.variable_type.copy ();
- class_init_fragment.append (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma)));
+ ccode.add_expression (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma));
}
- temp_vars.clear ();
temp_ref_vars.clear ();
+
+ pop_context ();
}
} else {
generate_field_declaration (f, cfile);
@@ -1019,7 +1028,15 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var var_decl = new CCodeVariableDeclarator (f.get_cname (), null, f.variable_type.get_cdeclarator_suffix ());
var_decl.initializer = default_value_for_type (f.variable_type, true);
+ if (class_init_context != null) {
+ push_context (class_init_context);
+ } else {
+ push_context (new EmitContext ());
+ }
+
if (f.initializer != null) {
+ f.initializer.emit (this);
+
var init = (CCodeExpression) f.initializer.ccodenode;
if (is_constant_ccode_expression (init)) {
var_decl.initializer = init;
@@ -1095,23 +1112,18 @@ public class Vala.CCodeBaseModule : CodeGenerator {
if (!is_constant_ccode_expression (rhs)) {
if (f.parent_symbol is Class) {
if (f.initializer is InitializerList) {
- var block = new CCodeBlock ();
- var frag = new CCodeFragment ();
+ ccode.open_block ();
var temp_decl = get_temp_variable (f.variable_type);
- var cdecl = new CCodeDeclaration (temp_decl.variable_type.get_cname ());
- var vardecl = new CCodeVariableDeclarator (temp_decl.name, rhs);
- cdecl.add_declarator (vardecl);
- vardecl.init0 = true;
- frag.append (cdecl);
+ var vardecl = new CCodeVariableDeclarator.zero (temp_decl.name, rhs);
+ ccode.add_declaration (temp_decl.variable_type.get_cname (), vardecl);
var tmp = get_variable_cexpression (get_variable_cname (temp_decl.name));
- frag.append (new CCodeExpressionStatement (new CCodeAssignment (lhs, tmp)));
+ ccode.add_expression (new CCodeAssignment (lhs, tmp));
- block.add_statement (frag);
- class_init_fragment.append (block);
+ ccode.close ();
} else {
- class_init_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (lhs, rhs)));
+ ccode.add_expression (new CCodeAssignment (lhs, rhs));
}
if (f.variable_type is ArrayType && !f.no_array_length &&
@@ -1124,12 +1136,9 @@ public class Vala.CCodeBaseModule : CodeGenerator {
for (int dim = 1; dim <= array_type.rank; dim++) {
var array_len_lhs = get_array_length_cexpression (ma, dim);
var size = sizes[dim - 1];
- class_init_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (array_len_lhs, (CCodeExpression) size.ccodenode)));
+ ccode.add_expression (new CCodeAssignment (array_len_lhs, (CCodeExpression) size.ccodenode));
}
}
-
- append_temp_decl (class_init_fragment, temp_vars);
- temp_vars.clear ();
} else {
f.error = true;
Report.error (f.source_reference, "Non-constant field initializers not supported in this context");
@@ -1137,6 +1146,8 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
}
}
+
+ pop_context ();
}
}
@@ -1275,6 +1286,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
generate_type_declaration (acc.value_type, decl_space);
+ CCodeFunction function;
if (acc.readable && !returns_real_struct) {
function = new CCodeFunction (acc.get_cname (), acc.value_type.get_cname ());
} else {
@@ -1531,46 +1543,34 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
}
- var init_fragment = new CCodeFragment ();
+ push_function (function);
if (prop.binding == MemberBinding.INSTANCE && !is_virtual) {
- CCodeStatement check_stmt;
if (!acc.readable || returns_real_struct) {
- check_stmt = create_property_type_check_statement (prop, false, t, true, "self");
+ create_property_type_check_statement (prop, false, t, true, "self");
} else {
- check_stmt = create_property_type_check_statement (prop, true, t, true, "self");
- }
- if (check_stmt != null) {
- init_fragment.append (check_stmt);
+ create_property_type_check_statement (prop, true, t, true, "self");
}
}
+ if (current_method_inner_error) {
+ ccode.add_declaration ("GError *", new CCodeVariableDeclarator.zero ("_inner_error_", new CCodeConstant ("NULL")));
+ }
+
if (acc.readable && !returns_real_struct) {
// do not declare result variable if exit block is known to be unreachable
if (acc.return_block == null || acc.return_block.get_predecessors ().size > 0) {
- var cdecl = new CCodeDeclaration (acc.value_type.get_cname ());
- cdecl.add_declarator (new CCodeVariableDeclarator ("result"));
- init_fragment.append (cdecl);
+ ccode.add_declaration (acc.value_type.get_cname (), new CCodeVariableDeclarator ("result"));
}
}
if (is_virtual) {
- var cdecl = new CCodeDeclaration (this_type.get_cname ());
- cdecl.add_declarator (new CCodeVariableDeclarator ("self", transform_expression (new CCodeIdentifier ("base"), base_type, this_type)));
- init_fragment.append (cdecl);
+ ccode.add_declaration (this_type.get_cname (), new CCodeVariableDeclarator ("self"));
+ ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("self"), transform_expression (new CCodeIdentifier ("base"), base_type, this_type)));
}
acc.body.emit (this);
- function.block = (CCodeBlock) acc.body.ccodenode;
- function.block.prepend_statement (init_fragment);
-
- if (current_method_inner_error) {
- var cdecl = new CCodeDeclaration ("GError *");
- cdecl.add_declarator (new CCodeVariableDeclarator.zero ("_inner_error_", new CCodeConstant ("NULL")));
- function.block.add_statement (cdecl);
- }
-
// notify on property changes
if (is_gobject_property (prop) &&
prop.notify &&
@@ -1578,7 +1578,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var notify_call = new CCodeFunctionCall (new CCodeIdentifier ("g_object_notify"));
notify_call.add_argument (new CCodeCastExpression (new CCodeIdentifier ("self"), "GObject *"));
notify_call.add_argument (prop.get_canonical_cconstant ());
- function.block.add_statement (new CCodeExpressionStatement (notify_call));
+ ccode.add_expression (notify_call);
}
cfile.add_function (function);
@@ -1588,30 +1588,11 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
public override void visit_destructor (Destructor d) {
- bool old_method_inner_error = current_method_inner_error;
- current_method_inner_error = false;
-
- d.body.emit (this);
-
if (d.binding == MemberBinding.STATIC && !in_plugin) {
Report.error (d.source_reference, "static destructors are only supported for dynamic types");
d.error = true;
return;
}
-
- CCodeFragment cfrag = new CCodeFragment ();
-
- if (current_method_inner_error) {
- var cdecl = new CCodeDeclaration ("GError *");
- cdecl.add_declarator (new CCodeVariableDeclarator ("_inner_error_", new CCodeConstant ("NULL")));
- cfrag.append (cdecl);
- }
-
- cfrag.append (d.body.ccodenode);
-
- d.ccodenode = cfrag;
-
- current_method_inner_error = old_method_inner_error;
}
public int get_block_id (Block b) {
@@ -1623,7 +1604,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
return result;
}
- void capture_parameter (FormalParameter param, CCodeStruct data, CCodeBlock cblock, int block_id, CCodeBlock free_block) {
+ void capture_parameter (FormalParameter param, CCodeStruct data, int block_id, CCodeBlock free_block) {
generate_type_declaration (param.variable_type, cfile);
var param_type = param.variable_type.copy ();
@@ -1647,20 +1628,20 @@ public class Vala.CCodeBaseModule : CodeGenerator {
param.captured = true;
}
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_variable_cname (param.name)), cparam)));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_variable_cname (param.name)), cparam));
if (param.variable_type is ArrayType) {
var array_type = (ArrayType) param.variable_type;
for (int dim = 1; dim <= array_type.rank; dim++) {
data.add_field ("gint", get_array_length_cname (get_variable_cname (param.name), dim));
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_array_length_cname (get_variable_cname (param.name), dim)), new CCodeIdentifier (get_array_length_cname (get_variable_cname (param.name), dim)))));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_array_length_cname (get_variable_cname (param.name), dim)), new CCodeIdentifier (get_array_length_cname (get_variable_cname (param.name), dim))));
}
} else if (param.variable_type is DelegateType) {
data.add_field ("gpointer", get_delegate_target_cname (get_variable_cname (param.name)));
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_delegate_target_cname (get_variable_cname (param.name))), new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (param.name))))));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_delegate_target_cname (get_variable_cname (param.name))), new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (param.name)))));
if (param.variable_type.value_owned) {
data.add_field ("GDestroyNotify", get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)));
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_delegate_target_destroy_notify_cname (get_variable_cname (param.name))), new CCodeIdentifier (get_delegate_target_destroy_notify_cname (get_variable_cname (param.name))))));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_delegate_target_destroy_notify_cname (get_variable_cname (param.name))), new CCodeIdentifier (get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)))));
}
}
@@ -1685,16 +1666,11 @@ public class Vala.CCodeBaseModule : CodeGenerator {
public override void visit_block (Block b) {
emit_context.push_symbol (b);
- foreach (Statement stmt in b.get_statements ()) {
- stmt.emit (this);
- }
-
var local_vars = b.get_local_variables ();
- foreach (LocalVariable local in local_vars) {
- local.active = false;
+
+ if (b.parent_node is Block || b.parent_node is SwitchStatement) {
+ ccode.open_block ();
}
-
- var cblock = new CCodeBlock ();
if (b.captured) {
var parent_block = next_closure_block (b.parent_symbol);
@@ -1770,15 +1746,13 @@ public class Vala.CCodeBaseModule : CodeGenerator {
if (current_method != null && current_method.coroutine) {
closure_struct.add_field (struct_name + "*", "_data%d_".printf (block_id));
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (get_variable_cexpression ("_data%d_".printf (block_id)), data_alloc)));
} else {
- var data_decl = new CCodeDeclaration (struct_name + "*");
- data_decl.add_declarator (new CCodeVariableDeclarator ("_data%d_".printf (block_id), data_alloc));
- cblock.add_statement (data_decl);
+ ccode.add_declaration (struct_name + "*", new CCodeVariableDeclarator ("_data%d_".printf (block_id)));
}
+ ccode.add_expression (new CCodeAssignment (get_variable_cexpression ("_data%d_".printf (block_id)), data_alloc));
// initialize ref_count
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), "_ref_count_"), new CCodeIdentifier ("1"))));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), "_ref_count_"), new CCodeIdentifier ("1")));
if (parent_block != null) {
int parent_block_id = get_block_id (parent_block);
@@ -1786,14 +1760,14 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var ref_call = new CCodeFunctionCall (new CCodeIdentifier ("block%d_data_ref".printf (parent_block_id)));
ref_call.add_argument (get_variable_cexpression ("_data%d_".printf (parent_block_id)));
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), "_data%d_".printf (parent_block_id)), ref_call)));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), "_data%d_".printf (parent_block_id)), ref_call));
} else if (in_constructor || (current_method != null && current_method.binding == MemberBinding.INSTANCE &&
(!(current_method is CreationMethod) || current_method.body != b)) ||
(current_property_accessor != null && current_property_accessor.prop.binding == MemberBinding.INSTANCE)) {
var ref_call = new CCodeFunctionCall (get_dup_func_expression (new ObjectType (current_class), b.source_reference));
ref_call.add_argument (get_result_cexpression ("self"));
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), "self"), ref_call)));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), "self"), ref_call));
}
if (b.parent_symbol is Method) {
@@ -1802,7 +1776,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
// parameters are captured with the top-level block of the method
foreach (var param in m.get_parameters ()) {
if (param.captured) {
- capture_parameter (param, data, cblock, block_id, free_block);
+ capture_parameter (param, data, block_id, free_block);
}
}
@@ -1812,24 +1786,14 @@ public class Vala.CCodeBaseModule : CodeGenerator {
// async method is suspended while waiting for callback,
// so we never need to care about memory management of async data
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), "_async_data_"), new CCodeIdentifier ("data"))));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), "_async_data_"), new CCodeIdentifier ("data")));
}
-
- var cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
- temp_vars.clear ();
- cblock.add_statement (cfrag);
} else if (b.parent_symbol is PropertyAccessor) {
var acc = (PropertyAccessor) b.parent_symbol;
if (!acc.readable && acc.value_parameter.captured) {
- capture_parameter (acc.value_parameter, data, cblock, block_id, free_block);
+ capture_parameter (acc.value_parameter, data, block_id, free_block);
}
-
- var cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
- temp_vars.clear ();
- cblock.add_statement (cfrag);
}
var typedef = new CCodeTypeDefinition ("struct _" + struct_name, new CCodeVariableDeclarator (struct_name));
@@ -1867,28 +1831,19 @@ public class Vala.CCodeBaseModule : CodeGenerator {
cfile.add_function (unref_fun);
}
- foreach (CodeNode stmt in b.get_statements ()) {
- if (stmt.error || stmt.unreachable) {
- continue;
- }
-
- if (stmt.ccodenode is CCodeFragment) {
- foreach (CCodeNode cstmt in ((CCodeFragment) stmt.ccodenode).get_children ()) {
- cblock.add_statement (cstmt);
- }
- } else {
- cblock.add_statement (stmt.ccodenode);
- }
+ foreach (Statement stmt in b.get_statements ()) {
+ stmt.emit (this);
}
// free in reverse order
for (int i = local_vars.size - 1; i >= 0; i--) {
var local = local_vars[i];
+ local.active = false;
if (!local.unreachable && !local.floating && !local.captured && requires_destroy (local.variable_type)) {
var ma = new MemberAccess.simple (local.name);
ma.symbol_reference = local;
ma.value_type = local.variable_type.copy ();
- cblock.add_statement (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma)));
+ ccode.add_expression (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma));
}
}
@@ -1899,7 +1854,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var ma = new MemberAccess.simple (param.name);
ma.symbol_reference = param;
ma.value_type = param.variable_type.copy ();
- cblock.add_statement (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (param.name), param.variable_type, ma)));
+ ccode.add_expression (get_unref_expression (get_variable_cexpression (param.name), param.variable_type, ma));
}
}
}
@@ -1909,30 +1864,18 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var data_unref = new CCodeFunctionCall (new CCodeIdentifier ("block%d_data_unref".printf (block_id)));
data_unref.add_argument (get_variable_cexpression ("_data%d_".printf (block_id)));
- cblock.add_statement (new CCodeExpressionStatement (data_unref));
+ ccode.add_expression (data_unref);
}
- b.ccodenode = cblock;
+ if (b.parent_node is Block || b.parent_node is SwitchStatement) {
+ ccode.close ();
+ }
emit_context.pop_symbol ();
}
- public override void visit_empty_statement (EmptyStatement stmt) {
- stmt.ccodenode = new CCodeEmptyStatement ();
- }
-
public override void visit_declaration_statement (DeclarationStatement stmt) {
stmt.declaration.accept (this);
-
- stmt.ccodenode = stmt.declaration.ccodenode;
-
- var local = stmt.declaration as LocalVariable;
- if (local != null && local.initializer != null) {
- create_temp_decl (stmt, local.initializer.temp_vars);
- }
-
- create_temp_decl (stmt, temp_vars);
- temp_vars.clear ();
}
public CCodeExpression get_variable_cexpression (string name) {
@@ -1999,12 +1942,12 @@ public class Vala.CCodeBaseModule : CodeGenerator {
if (!array_type.fixed_length) {
for (int dim = 1; dim <= array_type.rank; dim++) {
var len_var = new LocalVariable (int_type.copy (), get_array_length_cname (get_variable_cname (local.name), dim));
- temp_vars.add (len_var);
+ emit_temp_var (len_var);
}
if (array_type.rank == 1) {
var size_var = new LocalVariable (int_type.copy (), get_array_size_cname (get_variable_cname (local.name)));
- temp_vars.add (size_var);
+ emit_temp_var (size_var);
}
}
} else if (local.variable_type is DelegateType) {
@@ -2013,10 +1956,10 @@ public class Vala.CCodeBaseModule : CodeGenerator {
if (d.has_target) {
// create variable to store delegate target
var target_var = new LocalVariable (new PointerType (new VoidType ()), get_delegate_target_cname (get_variable_cname (local.name)));
- temp_vars.add (target_var);
+ emit_temp_var (target_var);
if (deleg_type.value_owned) {
var target_destroy_notify_var = new LocalVariable (new DelegateType ((Delegate) context.root.scope.lookup ("GLib").scope.lookup ("DestroyNotify")), get_delegate_target_destroy_notify_cname (get_variable_cname (local.name)));
- temp_vars.add (target_destroy_notify_var);
+ emit_temp_var (target_destroy_notify_var);
}
}
}
@@ -2039,7 +1982,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (local.variable_type, true, local, false);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), rhs));
for (int dim = 1; dim <= array_type.rank; dim++) {
@@ -2064,7 +2007,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (local.variable_type, true, local, false);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), rhs));
CCodeExpression lhs_delegate_target_destroy_notify;
@@ -2113,19 +2056,12 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
}
- var cfrag = new CCodeFragment ();
-
- if (pre_statement_fragment != null) {
- cfrag.append (pre_statement_fragment);
- pre_statement_fragment = null;
- }
-
if (local.captured) {
if (local.initializer != null) {
if (has_simple_struct_initializer (local)) {
- cfrag.append (new CCodeExpressionStatement (rhs));
+ ccode.add_expression (rhs);
} else {
- cfrag.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id ((Block) local.parent_symbol))), get_variable_cname (local.name)), rhs)));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id ((Block) local.parent_symbol))), get_variable_cname (local.name)), rhs));
}
}
} else if (current_method != null && current_method.coroutine) {
@@ -2133,15 +2069,15 @@ public class Vala.CCodeBaseModule : CodeGenerator {
if (local.initializer != null) {
if (has_simple_struct_initializer (local)) {
- cfrag.append (new CCodeExpressionStatement (rhs));
+ ccode.add_expression (rhs);
} else {
- cfrag.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_variable_cname (local.name)), rhs)));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_variable_cname (local.name)), rhs));
}
}
} else {
- CCodeStatement post_stmt = null;
+ CCodeExpression post_rhs = null;
if (has_simple_struct_initializer (local)) {
- post_stmt = new CCodeExpressionStatement (rhs);
+ post_rhs = rhs;
rhs = null;
}
@@ -2150,10 +2086,6 @@ public class Vala.CCodeBaseModule : CodeGenerator {
cvar.line = rhs.line;
}
- var cdecl = new CCodeDeclaration (local.variable_type.get_cname ());
- cdecl.add_declarator (cvar);
- cfrag.append (cdecl);
-
// try to initialize uninitialized variables
// initialization not necessary for variables stored in closure
if (cvar.initializer == null) {
@@ -2161,8 +2093,15 @@ public class Vala.CCodeBaseModule : CodeGenerator {
cvar.init0 = true;
}
- if (post_stmt != null) {
- cfrag.append (post_stmt);
+ ccode.add_declaration (local.variable_type.get_cname (), cvar);
+
+ if (cvar.initializer != null && !cvar.init0) {
+ cvar.initializer = null;
+ ccode.add_expression (new CCodeAssignment (get_variable_cexpression (local.name), rhs));
+ }
+
+ if (post_rhs != null) {
+ ccode.add_expression (post_rhs);
}
}
@@ -2182,16 +2121,14 @@ public class Vala.CCodeBaseModule : CodeGenerator {
ccopy.add_argument (get_variable_cexpression (local.name));
ccopy.add_argument ((CCodeExpression) local.initializer.ccodenode);
ccopy.add_argument (size);
- cfrag.append (new CCodeExpressionStatement (ccopy));
+ ccode.add_expression (ccopy);
}
}
if (local.initializer != null && local.initializer.tree_can_fail) {
- add_simple_check (local.initializer, cfrag);
+ add_simple_check (local.initializer);
}
- local.ccodenode = cfrag;
-
local.active = true;
}
@@ -2229,7 +2166,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
} else {
// used as expression
var temp_decl = get_temp_variable (list.target_type, false, list);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
var instance = get_variable_cexpression (get_variable_cname (temp_decl.name));
@@ -3055,25 +2992,6 @@ public class Vala.CCodeBaseModule : CodeGenerator {
* we unref temporary variables at the end of a full
* expression
*/
-
- /* can't automatically deep copy lists yet, so do it
- * manually for now
- * replace with
- * expr.temp_vars = temp_vars;
- * when deep list copying works
- */
- if (temp_vars.size > 0) {
- if (expr.temp_vars == null) {
- expr.temp_vars = new ArrayList<LocalVariable> ();
- } else {
- expr.temp_vars.clear ();
- }
- foreach (LocalVariable local in temp_vars) {
- expr.add_temp_var (local);
- }
- temp_vars.clear ();
- }
-
if (((List<LocalVariable>) temp_ref_vars).size == 0) {
/* nothing to do without temporary variables */
return;
@@ -3093,7 +3011,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
full_expr_var = get_temp_variable (expr_type, true, expr, false);
- expr.add_temp_var (full_expr_var);
+ emit_temp_var (full_expr_var);
expr_list.append_expression (new CCodeAssignment (get_variable_cexpression (full_expr_var.name), (CCodeExpression) expr.ccodenode));
}
@@ -3114,65 +3032,57 @@ public class Vala.CCodeBaseModule : CodeGenerator {
temp_ref_vars.clear ();
}
- public void append_temp_decl (CCodeFragment cfrag, List<LocalVariable>? temp_vars) {
- if (temp_vars == null) {
- return;
- }
- foreach (LocalVariable local in temp_vars) {
- var cdecl = new CCodeDeclaration (local.variable_type.get_cname ());
-
- var vardecl = new CCodeVariableDeclarator (local.name, null, local.variable_type.get_cdeclarator_suffix ());
- // sets #line
- local.ccodenode = vardecl;
- cdecl.add_declarator (vardecl);
-
- var st = local.variable_type.data_type as Struct;
- var array_type = local.variable_type as ArrayType;
-
- if (local.name.has_prefix ("*")) {
- // do not dereference unintialized variable
- // initialization is not needed for these special
- // pointer temp variables
- // used to avoid side-effects in assignments
- } else if (local.no_init) {
- // no initialization necessary for this temp var
- } else if (!local.variable_type.nullable &&
- (st != null && !st.is_simple_type ()) ||
- (array_type != null && array_type.fixed_length)) {
- // 0-initialize struct with struct initializer { 0 }
- // necessary as they will be passed by reference
- var clist = new CCodeInitializerList ();
- clist.append (new CCodeConstant ("0"));
+ public void emit_temp_var (LocalVariable local) {
+ var vardecl = new CCodeVariableDeclarator (local.name, null, local.variable_type.get_cdeclarator_suffix ());
+ // sets #line
+ local.ccodenode = vardecl;
- vardecl.initializer = clist;
- vardecl.init0 = true;
- } else if (local.variable_type.is_reference_type_or_type_parameter () ||
- local.variable_type.nullable ||
- local.variable_type is DelegateType) {
- vardecl.initializer = new CCodeConstant ("NULL");
- vardecl.init0 = true;
- }
+ var st = local.variable_type.data_type as Struct;
+ var array_type = local.variable_type as ArrayType;
+
+ if (local.name.has_prefix ("*")) {
+ // do not dereference unintialized variable
+ // initialization is not needed for these special
+ // pointer temp variables
+ // used to avoid side-effects in assignments
+ } else if (local.no_init) {
+ // no initialization necessary for this temp var
+ } else if (!local.variable_type.nullable &&
+ (st != null && !st.is_simple_type ()) ||
+ (array_type != null && array_type.fixed_length)) {
+ // 0-initialize struct with struct initializer { 0 }
+ // necessary as they will be passed by reference
+ var clist = new CCodeInitializerList ();
+ clist.append (new CCodeConstant ("0"));
- if (current_method != null && current_method.coroutine) {
- closure_struct.add_field (local.variable_type.get_cname (), local.name);
+ vardecl.initializer = clist;
+ vardecl.init0 = true;
+ } else if (local.variable_type.is_reference_type_or_type_parameter () ||
+ local.variable_type.nullable ||
+ local.variable_type is DelegateType) {
+ vardecl.initializer = new CCodeConstant ("NULL");
+ vardecl.init0 = true;
+ }
- // even though closure struct is zerod, we need to initialize temporary variables
- // as they might be used multiple times when declared in a loop
+ if (current_method != null && current_method.coroutine) {
+ closure_struct.add_field (local.variable_type.get_cname (), local.name);
- if (vardecl.initializer is CCodeInitializerList) {
- // C does not support initializer lists in assignments, use memset instead
- cfile.add_include ("string.h");
- var memset_call = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
- memset_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (local.name)));
- memset_call.add_argument (new CCodeConstant ("0"));
- memset_call.add_argument (new CCodeIdentifier ("sizeof (%s)".printf (local.variable_type.get_cname ())));
- cfrag.append (new CCodeExpressionStatement (memset_call));
- } else if (vardecl.initializer != null) {
- cfrag.append (new CCodeExpressionStatement (new CCodeAssignment (get_variable_cexpression (local.name), vardecl.initializer)));
- }
- } else {
- cfrag.append (cdecl);
+ // even though closure struct is zerod, we need to initialize temporary variables
+ // as they might be used multiple times when declared in a loop
+
+ if (vardecl.initializer is CCodeInitializerList) {
+ // C does not support initializer lists in assignments, use memset instead
+ cfile.add_include ("string.h");
+ var memset_call = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
+ memset_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (local.name)));
+ memset_call.add_argument (new CCodeConstant ("0"));
+ memset_call.add_argument (new CCodeIdentifier ("sizeof (%s)".printf (local.variable_type.get_cname ())));
+ ccode.add_expression (memset_call);
+ } else if (vardecl.initializer != null) {
+ ccode.add_expression (new CCodeAssignment (get_variable_cexpression (local.name), vardecl.initializer));
}
+ } else {
+ ccode.add_declaration (local.variable_type.get_cname (), vardecl);
}
}
@@ -3182,62 +3092,26 @@ public class Vala.CCodeBaseModule : CodeGenerator {
return;
}
- stmt.ccodenode = new CCodeExpressionStatement ((CCodeExpression) stmt.expression.ccodenode);
+ ccode.add_expression ((CCodeExpression) stmt.expression.ccodenode);
/* free temporary objects and handle errors */
- if (((List<LocalVariable>) temp_vars).size == 0
- && pre_statement_fragment == null
- && (!stmt.tree_can_fail || !stmt.expression.tree_can_fail)) {
- /* nothing to do without temporary variables and errors */
- return;
- }
-
- var cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
-
- if (pre_statement_fragment != null) {
- cfrag.append (pre_statement_fragment);
- pre_statement_fragment = null;
- }
-
- cfrag.append (stmt.ccodenode);
-
foreach (LocalVariable local in temp_ref_vars) {
var ma = new MemberAccess.simple (local.name);
ma.symbol_reference = local;
ma.value_type = local.variable_type.copy ();
- cfrag.append (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma)));
+ ccode.add_expression (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma));
}
if (stmt.tree_can_fail && stmt.expression.tree_can_fail) {
// simple case, no node breakdown necessary
- add_simple_check (stmt.expression, cfrag);
+ add_simple_check (stmt.expression);
}
- stmt.ccodenode = cfrag;
-
- temp_vars.clear ();
temp_ref_vars.clear ();
}
-
- public void create_temp_decl (Statement stmt, List<LocalVariable>? temp_vars) {
- /* declare temporary variables */
-
- if (temp_vars == null || temp_vars.size == 0) {
- /* nothing to do without temporary variables */
- return;
- }
-
- var cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
-
- cfrag.append (stmt.ccodenode);
-
- stmt.ccodenode = cfrag;
- }
- public virtual void append_local_free (Symbol sym, CCodeFragment cfrag, bool stop_at_loop = false) {
+ public virtual void append_local_free (Symbol sym, bool stop_at_loop = false) {
var b = (Block) sym;
var local_vars = b.get_local_variables ();
@@ -3248,7 +3122,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var ma = new MemberAccess.simple (local.name);
ma.symbol_reference = local;
ma.value_type = local.variable_type.copy ();
- cfrag.append (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma)));
+ ccode.add_expression (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma));
}
}
@@ -3257,7 +3131,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var data_unref = new CCodeFunctionCall (new CCodeIdentifier ("block%d_data_unref".printf (block_id)));
data_unref.add_argument (get_variable_cexpression ("_data%d_".printf (block_id)));
- cfrag.append (new CCodeExpressionStatement (data_unref));
+ ccode.add_expression (data_unref);
}
if (stop_at_loop) {
@@ -3269,13 +3143,13 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
if (sym.parent_symbol is Block) {
- append_local_free (sym.parent_symbol, cfrag, stop_at_loop);
+ append_local_free (sym.parent_symbol, stop_at_loop);
} else if (sym.parent_symbol is Method) {
- append_param_free ((Method) sym.parent_symbol, cfrag);
+ append_param_free ((Method) sym.parent_symbol);
}
}
- public void append_error_free (Symbol sym, CCodeFragment cfrag, TryStatement current_try) {
+ public void append_error_free (Symbol sym, TryStatement current_try) {
var b = (Block) sym;
var local_vars = b.get_local_variables ();
@@ -3285,7 +3159,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
if (!local.unreachable && local.active && !local.floating && !local.captured && requires_destroy (local.variable_type)) {
var ma = new MemberAccess.simple (local.name);
ma.symbol_reference = local;
- cfrag.append (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma)));
+ ccode.add_expression (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma));
}
}
@@ -3294,7 +3168,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var data_unref = new CCodeFunctionCall (new CCodeIdentifier ("block%d_data_unref".printf (block_id)));
data_unref.add_argument (get_variable_cexpression ("_data%d_".printf (block_id)));
- cfrag.append (new CCodeExpressionStatement (data_unref));
+ ccode.add_expression (data_unref);
}
if (sym == current_try.body) {
@@ -3302,32 +3176,23 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
if (sym.parent_symbol is Block) {
- append_error_free (sym.parent_symbol, cfrag, current_try);
+ append_error_free (sym.parent_symbol, current_try);
} else if (sym.parent_symbol is Method) {
- append_param_free ((Method) sym.parent_symbol, cfrag);
+ append_param_free ((Method) sym.parent_symbol);
}
}
- private void append_param_free (Method m, CCodeFragment cfrag) {
+ private void append_param_free (Method m) {
foreach (FormalParameter param in m.get_parameters ()) {
if (!param.ellipsis && requires_destroy (param.variable_type) && param.direction == ParameterDirection.IN) {
var ma = new MemberAccess.simple (param.name);
ma.symbol_reference = param;
ma.value_type = param.variable_type.copy ();
- cfrag.append (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (param.name), param.variable_type, ma)));
+ ccode.add_expression (get_unref_expression (get_variable_cexpression (param.name), param.variable_type, ma));
}
}
}
- public void create_local_free (CodeNode stmt, bool stop_at_loop = false) {
- var cfrag = new CCodeFragment ();
-
- append_local_free (current_symbol, cfrag, stop_at_loop);
-
- cfrag.append (stmt.ccodenode);
- stmt.ccodenode = cfrag;
- }
-
public bool variable_accessible_in_finally (LocalVariable local) {
if (current_try == null) {
return false;
@@ -3386,7 +3251,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
ccomma.append_expression (get_variable_cexpression (return_expr_decl.name));
stmt.return_expression.ccodenode = ccomma;
- stmt.return_expression.add_temp_var (return_expr_decl);
+ emit_temp_var (return_expr_decl);
} else if ((current_method != null || current_property_accessor != null) && current_return_type is DelegateType) {
var delegate_type = (DelegateType) current_return_type;
if (delegate_type.delegate_symbol.has_target) {
@@ -3413,52 +3278,37 @@ public class Vala.CCodeBaseModule : CodeGenerator {
ccomma.append_expression (get_variable_cexpression (return_expr_decl.name));
stmt.return_expression.ccodenode = ccomma;
- stmt.return_expression.add_temp_var (return_expr_decl);
+ emit_temp_var (return_expr_decl);
}
}
- var cfrag = new CCodeFragment ();
-
if (stmt.return_expression != null) {
// assign method result to `result'
CCodeExpression result_lhs = get_result_cexpression ();
if (current_return_type.is_real_non_null_struct_type () && (current_method == null || !current_method.coroutine)) {
result_lhs = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, result_lhs);
}
- cfrag.append (new CCodeExpressionStatement (new CCodeAssignment (result_lhs, (CCodeExpression) stmt.return_expression.ccodenode)));
+ ccode.add_expression (new CCodeAssignment (result_lhs, (CCodeExpression) stmt.return_expression.ccodenode));
}
// free local variables
- append_local_free (current_symbol, cfrag);
+ append_local_free (current_symbol);
if (current_method != null) {
// check postconditions
foreach (Expression postcondition in current_method.get_postconditions ()) {
- cfrag.append (create_postcondition_statement (postcondition));
+ create_postcondition_statement (postcondition);
}
}
- CCodeReturnStatement creturn = null;
if (current_method is CreationMethod) {
- creturn = new CCodeReturnStatement (new CCodeIdentifier ("self"));
- cfrag.append (creturn);
+ ccode.add_return (new CCodeIdentifier ("self"));
} else if (current_method != null && current_method.coroutine) {
} else if (current_return_type is VoidType || current_return_type.is_real_non_null_struct_type ()) {
// structs are returned via out parameter
- creturn = new CCodeReturnStatement ();
- cfrag.append (creturn);
+ ccode.add_return ();
} else {
- creturn = new CCodeReturnStatement (new CCodeIdentifier ("result"));
- cfrag.append (creturn);
- }
-
- stmt.ccodenode = cfrag;
- if (creturn != null) {
- creturn.line = stmt.ccodenode.line;
- }
-
- if (stmt.return_expression != null) {
- create_temp_decl (stmt, stmt.return_expression.temp_vars);
+ ccode.add_return (new CCodeIdentifier ("result"));
}
if (return_expression_symbol != null) {
@@ -3515,9 +3365,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var fc = new CCodeFunctionCall (new CCodeIdentifier (((Method) mutex_type.scope.lookup ("lock")).get_cname ()));
fc.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, l));
- var cn = new CCodeFragment ();
- cn.append (new CCodeExpressionStatement (fc));
- stmt.ccodenode = cn;
+ ccode.add_expression (fc);
}
public override void visit_unlock_statement (UnlockStatement stmt) {
@@ -3526,9 +3374,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var fc = new CCodeFunctionCall (new CCodeIdentifier (((Method) mutex_type.scope.lookup ("unlock")).get_cname ()));
fc.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, l));
- var cn = new CCodeFragment ();
- cn.append (new CCodeExpressionStatement (fc));
- stmt.ccodenode = cn;
+ ccode.add_expression (fc);
}
public override void visit_delete_statement (DeleteStatement stmt) {
@@ -3540,7 +3386,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var ccall = new CCodeFunctionCall (get_destroy_func_expression (type));
ccall.add_argument ((CCodeExpression) stmt.expression.ccodenode);
- stmt.ccodenode = new CCodeExpressionStatement (ccall);
+ ccode.add_expression (ccall);
}
public override void visit_expression (Expression expr) {
@@ -3627,7 +3473,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
var regex_var = get_temp_variable (regex_type, true, expr, false);
- expr.add_temp_var (regex_var);
+ emit_temp_var (regex_var);
var cdecl = new CCodeDeclaration ("GRegex*");
@@ -3715,7 +3561,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
// assign current value to temp variable
var temp_decl = get_temp_variable (prop.property_type, true, expr, false);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_decl.name), (CCodeExpression) expr.inner.ccodenode));
// increment/decrement property
@@ -3826,7 +3672,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
// (copy (&expr, &temp), temp)
var decl = get_temp_variable (expression_type, false, node);
- temp_vars.add (decl);
+ emit_temp_var (decl);
var ctemp = get_variable_cexpression (decl.name);
@@ -3926,7 +3772,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
return ccall;
} else {
var decl = get_temp_variable (expression_type, false, node, false);
- temp_vars.add (decl);
+ emit_temp_var (decl);
var ctemp = get_variable_cexpression (decl.name);
@@ -4149,7 +3995,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
} else {
var temp_decl = get_temp_variable (expr.type_reference, false, expr);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
instance = get_variable_cexpression (get_variable_cname (temp_decl.name));
}
@@ -4457,7 +4303,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (type, true, null, false);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), cexpr));
ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (temp_var.name)));
@@ -4529,7 +4375,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
expr.append_array_size (len_call);
} else if (to is StructValueType) {
var temp_decl = get_temp_variable (to, true, null, true);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
var ctemp = get_variable_cexpression (temp_decl.name);
rv = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeCastExpression (rv, (new PointerType(to)).get_cname ()));
@@ -4577,7 +4423,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
for (int dim = 1; dim <= array_type.rank; dim++) {
var temp_decl = get_temp_variable (int_type, false, expr);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (temp_decl.name)));
cfunc.add_parameter (new CCodeFormalParameter (get_array_length_cname ("result", dim), "int*"));
@@ -4631,7 +4477,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var ccomma = new CCodeCommaExpression ();
var temp_decl = get_temp_variable (expr.inner.value_type, true, expr, false);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
var ctemp = get_variable_cexpression (temp_decl.name);
var cinit = new CCodeAssignment (ctemp, (CCodeExpression) expr.inner.ccodenode);
@@ -4695,7 +4541,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
/* (tmp = var, var = null, tmp) */
var ccomma = new CCodeCommaExpression ();
var temp_decl = get_temp_variable (expr.value_type, true, expr, false);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
var cvar = get_variable_cexpression (temp_decl.name);
ccomma.append_expression (new CCodeAssignment (cvar, (CCodeExpression) expr.inner.ccodenode));
@@ -4713,7 +4559,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var lbe = (BinaryExpression) expr.left;
var temp_decl = get_temp_variable (lbe.right.value_type, true, null, false);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
var cvar = get_variable_cexpression (temp_decl.name);
var ccomma = new CCodeCommaExpression ();
var clbe = (CCodeBinaryExpression) lbe.ccodenode;
@@ -5095,7 +4941,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
// 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, false);
- temp_vars.add (decl);
+ emit_temp_var (decl);
temp_ref_vars.insert (0, decl);
cexpr = new CCodeAssignment (get_variable_cexpression (decl.name), cexpr);
@@ -5105,7 +4951,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
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.add (len_decl);
+ emit_temp_var (len_decl);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (len_decl.name), get_array_length_cexpression (expr, dim)));
}
ccomma.append_expression (get_variable_cexpression (decl.name));
@@ -5115,9 +4961,9 @@ public class Vala.CCodeBaseModule : CodeGenerator {
ccomma.append_expression (cexpr);
var target_decl = new LocalVariable (new PointerType (new VoidType ()), get_delegate_target_cname (decl.name));
- temp_vars.add (target_decl);
+ emit_temp_var (target_decl);
var target_destroy_notify_decl = new LocalVariable (new DelegateType ((Delegate) context.root.scope.lookup ("GLib").scope.lookup ("DestroyNotify")), get_delegate_target_destroy_notify_cname (decl.name));
- temp_vars.add (target_destroy_notify_decl);
+ emit_temp_var (target_destroy_notify_decl);
CCodeExpression target_destroy_notify;
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (target_decl.name), get_delegate_target_cexpression (expr, out target_destroy_notify)));
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (target_destroy_notify_decl.name), target_destroy_notify));
@@ -5136,7 +4982,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
if (gvalue_boxing) {
// implicit conversion to GValue
var decl = get_temp_variable (target_type, true, target_type);
- temp_vars.add (decl);
+ emit_temp_var (decl);
var ccomma = new CCodeCommaExpression ();
@@ -5228,7 +5074,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
cexpr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cexpr);
} else {
var decl = get_temp_variable (expression_type, expression_type.value_owned, expression_type, false);
- temp_vars.add (decl);
+ emit_temp_var (decl);
var ccomma = new CCodeCommaExpression ();
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (decl.name), cexpr));
@@ -5350,7 +5196,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (ma.inner.target_type, true, null, false);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), instance));
ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (temp_var.name)));
@@ -5371,7 +5217,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
CCodeExpression rv;
if (array_type != null && !prop.no_array_length) {
var temp_var = get_temp_variable (prop.property_type, true, null, false);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
var ccomma = new CCodeCommaExpression ();
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), cexpr));
ccall.add_argument (get_variable_cexpression (temp_var.name));
@@ -5437,7 +5283,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
var temp_decl = get_temp_variable (address_of_type, true, null, false);
var ctemp = get_variable_cexpression (temp_decl.name);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
ccomma.append_expression (new CCodeAssignment (ctemp, ce));
ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ctemp));
return ccomma;
@@ -5509,19 +5355,19 @@ public class Vala.CCodeBaseModule : CodeGenerator {
return null;
}
- private CCodeStatement? create_property_type_check_statement (Property prop, bool check_return_type, TypeSymbol t, bool non_null, string var_name) {
+ private void create_property_type_check_statement (Property prop, bool check_return_type, TypeSymbol t, bool non_null, string var_name) {
if (check_return_type) {
- return create_type_check_statement (prop, prop.property_type, t, non_null, var_name);
+ create_type_check_statement (prop, prop.property_type, t, non_null, var_name);
} else {
- return create_type_check_statement (prop, new VoidType (), t, non_null, var_name);
+ create_type_check_statement (prop, new VoidType (), t, non_null, var_name);
}
}
- public CCodeStatement? create_type_check_statement (CodeNode method_node, DataType ret_type, TypeSymbol t, bool non_null, string var_name) {
+ public void create_type_check_statement (CodeNode method_node, DataType ret_type, TypeSymbol t, bool non_null, string var_name) {
var ccheck = new CCodeFunctionCall ();
if (!context.assert) {
- return null;
+ return;
} else if (context.checking && ((t is Class && !((Class) t).is_compact) || t is Interface)) {
var ctype_check = new CCodeFunctionCall (new CCodeIdentifier (get_type_check_function (t)));
ctype_check.add_argument (new CCodeIdentifier (var_name));
@@ -5534,10 +5380,10 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
ccheck.add_argument (cexpr);
} else if (!non_null) {
- return null;
+ return;
} else if (t == glist_type || t == gslist_type) {
// NULL is empty list
- return null;
+ return;
} else {
var cnonnull = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier (var_name), new CCodeConstant ("NULL"));
ccheck.add_argument (cnonnull);
@@ -5557,11 +5403,11 @@ public class Vala.CCodeBaseModule : CodeGenerator {
if (cdefault != null) {
ccheck.add_argument (cdefault);
} else {
- return null;
+ return;
}
}
- return new CCodeExpressionStatement (ccheck);
+ ccode.add_expression (ccheck);
}
public int get_param_pos (double param_pos, bool ellipsis = false) {
@@ -5590,12 +5436,12 @@ public class Vala.CCodeBaseModule : CodeGenerator {
public override void visit_class (Class cl) {
}
- public CCodeStatement create_postcondition_statement (Expression postcondition) {
+ public void create_postcondition_statement (Expression postcondition) {
var cassert = new CCodeFunctionCall (new CCodeIdentifier ("g_warn_if_fail"));
cassert.add_argument ((CCodeExpression) postcondition.ccodenode);
- return new CCodeExpressionStatement (cassert);
+ ccode.add_expression (cassert);
}
public virtual bool is_gobject_property (Property prop) {
@@ -5707,13 +5553,11 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
}
- append_temp_decl (cfrag, temp_vars);
- temp_vars.clear ();
-
pop_context ();
- cfile.add_function_declaration (function);
function.block = cblock;
+
+ cfile.add_function_declaration (function);
cfile.add_function (function);
}
@@ -5789,7 +5633,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
return new CCodeConstant ("");
}
- public virtual void add_simple_check (CodeNode node, CCodeFragment cfrag, bool always_fails = false) {
+ public virtual void add_simple_check (CodeNode node, bool always_fails = false) {
}
}
diff --git a/codegen/valaccodecontrolflowmodule.vala b/codegen/valaccodecontrolflowmodule.vala
index 49d868b..0793d33 100644
--- a/codegen/valaccodecontrolflowmodule.vala
+++ b/codegen/valaccodecontrolflowmodule.vala
@@ -26,24 +26,22 @@ using GLib;
public class Vala.CCodeControlFlowModule : CCodeMethodModule {
public override void visit_if_statement (IfStatement stmt) {
+ ccode.open_if ((CCodeExpression) stmt.condition.ccodenode);
+
stmt.true_statement.emit (this);
+
if (stmt.false_statement != null) {
+ ccode.add_else ();
stmt.false_statement.emit (this);
}
- if (stmt.false_statement != null) {
- stmt.ccodenode = new CCodeIfStatement ((CCodeExpression) stmt.condition.ccodenode, (CCodeStatement) stmt.true_statement.ccodenode, (CCodeStatement) stmt.false_statement.ccodenode);
- } else {
- stmt.ccodenode = new CCodeIfStatement ((CCodeExpression) stmt.condition.ccodenode, (CCodeStatement) stmt.true_statement.ccodenode);
- }
-
- create_temp_decl (stmt, stmt.condition.temp_vars);
+ ccode.close ();
}
void visit_string_switch_statement (SwitchStatement stmt) {
// we need a temporary variable to save the property value
var temp_var = get_temp_variable (stmt.expression.value_type, stmt.expression.value_type.value_owned, stmt, false);
- stmt.expression.add_temp_var (temp_var);
+ emit_temp_var (temp_var);
var ctemp = get_variable_cexpression (temp_var.name);
var cinit = new CCodeAssignment (ctemp, (CCodeExpression) stmt.expression.ccodenode);
@@ -52,9 +50,6 @@ public class Vala.CCodeControlFlowModule : CCodeMethodModule {
var free_call = new CCodeFunctionCall (new CCodeIdentifier ("g_free"));
free_call.add_argument (ctemp);
- var cswitchblock = new CCodeFragment ();
- stmt.ccodenode = cswitchblock;
-
var cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeConstant ("NULL"), ctemp);
var cquark = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_string"));
cquark.add_argument (ctemp);
@@ -62,7 +57,7 @@ public class Vala.CCodeControlFlowModule : CCodeMethodModule {
var ccond = new CCodeConditionalExpression (cisnull, new CCodeConstant ("0"), cquark);
temp_var = get_temp_variable (gquark_type);
- stmt.expression.add_temp_var (temp_var);
+ emit_temp_var (temp_var);
int label_count = 0;
@@ -72,48 +67,43 @@ public class Vala.CCodeControlFlowModule : CCodeMethodModule {
}
foreach (SwitchLabel label in section.get_labels ()) {
+ label.expression.emit (this);
var cexpr = (CCodeExpression) label.expression.ccodenode;
if (is_constant_ccode_expression (cexpr)) {
var cname = "%s_label%d".printf (temp_var.name, label_count++);
- var cdecl = new CCodeDeclaration (gquark_type.get_cname ());
- cdecl.modifiers = CCodeModifiers.STATIC;
- cdecl.add_declarator (new CCodeVariableDeclarator (cname, czero));
-
- cswitchblock.append (cdecl);
+ ccode.add_declaration (gquark_type.get_cname (), new CCodeVariableDeclarator (cname, czero), CCodeModifiers.STATIC);
}
}
}
- cswitchblock.append (new CCodeExpressionStatement (cinit));
+ ccode.add_expression (cinit);
ctemp = get_variable_cexpression (temp_var.name);
cinit = new CCodeAssignment (ctemp, ccond);
- cswitchblock.append (new CCodeExpressionStatement (cinit));
- create_temp_decl (stmt, stmt.expression.temp_vars);
+ ccode.add_expression (cinit);
if (stmt.expression.value_type.value_owned) {
// free owned string
- cswitchblock.append (new CCodeExpressionStatement (free_call));
+ ccode.add_expression (free_call);
}
- List<Statement> default_statements = null;
+ SwitchSection default_section = null;
label_count = 0;
- // generate nested if statements
- CCodeStatement ctopstmt = null;
- CCodeIfStatement coldif = null;
+ int n = 0;
foreach (SwitchSection section in stmt.get_sections ()) {
if (section.has_default_label ()) {
- default_statements = section.get_statements ();
+ default_section = section;
continue;
}
CCodeBinaryExpression cor = null;
foreach (SwitchLabel label in section.get_labels ()) {
+ label.expression.emit (this);
var cexpr = (CCodeExpression) label.expression.ccodenode;
if (is_constant_ccode_expression (cexpr)) {
@@ -140,119 +130,86 @@ public class Vala.CCodeControlFlowModule : CCodeMethodModule {
}
}
- var cblock = new CCodeBlock ();
- foreach (CodeNode body_stmt in section.get_statements ()) {
- if (body_stmt.ccodenode is CCodeFragment) {
- foreach (CCodeNode cstmt in ((CCodeFragment) body_stmt.ccodenode).get_children ()) {
- cblock.add_statement (cstmt);
- }
- } else {
- cblock.add_statement (body_stmt.ccodenode);
- }
+ if (n > 0) {
+ ccode.else_if (cor);
+ } else {
+ ccode.open_if (cor);
}
- var cswitch = new CCodeSwitchStatement (new CCodeConstant ("0"));
- cswitch.add_statement (new CCodeLabel ("default"));
- cswitch.add_statement (cblock);
- var cif = new CCodeIfStatement (cor, cswitch);
+ ccode.open_switch (new CCodeConstant ("0"));
+ ccode.add_default ();
- if (coldif != null) {
- coldif.false_statement = cif;
- } else {
- ctopstmt = cif;
- }
+ section.emit (this);
+
+ ccode.close ();
- coldif = cif;
+ n++;
}
- if (default_statements != null) {
- var cblock = new CCodeBlock ();
- foreach (CodeNode body_stmt in default_statements) {
- cblock.add_statement (body_stmt.ccodenode);
+ if (default_section != null) {
+ if (n > 0) {
+ ccode.add_else ();
}
- var cswitch = new CCodeSwitchStatement (new CCodeConstant ("0"));
- cswitch.add_statement (new CCodeLabel ("default"));
- cswitch.add_statement (cblock);
+ ccode.open_switch (new CCodeConstant ("0"));
+ ccode.add_default ();
- if (coldif == null) {
- // there is only one section and that section
- // contains a default label
- ctopstmt = cswitch;
- } else {
- coldif.false_statement = cswitch;
- }
+ default_section.emit (this);
+
+ ccode.close ();
}
-
- cswitchblock.append (ctopstmt);
+
+ ccode.close ();
}
public override void visit_switch_statement (SwitchStatement stmt) {
- foreach (SwitchSection section in stmt.get_sections ()) {
- section.emit (this);
- }
-
if (stmt.expression.value_type.compatible (string_type)) {
visit_string_switch_statement (stmt);
return;
}
- var cswitch = new CCodeSwitchStatement ((CCodeExpression) stmt.expression.ccodenode);
- stmt.ccodenode = cswitch;
+ ccode.open_switch ((CCodeExpression) stmt.expression.ccodenode);
foreach (SwitchSection section in stmt.get_sections ()) {
if (section.has_default_label ()) {
- cswitch.add_statement (new CCodeLabel ("default"));
- var cdefaultblock = new CCodeBlock ();
- cswitch.add_statement (cdefaultblock);
- foreach (CodeNode default_stmt in section.get_statements ()) {
- cdefaultblock.add_statement (default_stmt.ccodenode);
- }
- continue;
+ ccode.add_default ();
}
-
- foreach (SwitchLabel label in section.get_labels ()) {
- cswitch.add_statement (new CCodeCaseStatement ((CCodeExpression) label.expression.ccodenode));
- }
-
- cswitch.add_statement (section.ccodenode);
+ section.emit (this);
}
-
- create_temp_decl (stmt, stmt.expression.temp_vars);
+
+ ccode.close ();
}
public override void visit_switch_label (SwitchLabel label) {
+ if (((SwitchStatement) label.section.parent_node).expression.value_type.compatible (string_type)) {
+ return;
+ }
+
if (label.expression != null) {
label.expression.emit (this);
visit_end_full_expression (label.expression);
+
+ ccode.add_case ((CCodeExpression) label.expression.ccodenode);
}
}
public override void visit_loop (Loop stmt) {
- stmt.body.emit (this);
-
if (context.profile == Profile.GOBJECT) {
- stmt.ccodenode = new CCodeWhileStatement (new CCodeConstant ("TRUE"), (CCodeStatement) stmt.body.ccodenode);
+ ccode.open_while (new CCodeConstant ("TRUE"));
} else {
cfile.add_include ("stdbool.h");
- stmt.ccodenode = new CCodeWhileStatement (new CCodeConstant ("true"), (CCodeStatement) stmt.body.ccodenode);
+ ccode.open_while (new CCodeConstant ("true"));
}
- }
- public override void visit_foreach_statement (ForeachStatement stmt) {
stmt.body.emit (this);
- visit_block (stmt);
+ ccode.close ();
+ }
- var cblock = new CCodeBlock ();
- // sets #line
- stmt.ccodenode = cblock;
+ public override void visit_foreach_statement (ForeachStatement stmt) {
+ ccode.open_block ();
- var cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, stmt.collection.temp_vars);
- cblock.add_statement (cfrag);
-
var collection_backup = stmt.collection_variable;
var collection_type = collection_backup.variable_type.copy ();
@@ -264,20 +221,15 @@ public class Vala.CCodeControlFlowModule : CCodeMethodModule {
if (current_method != null && current_method.coroutine) {
closure_struct.add_field (collection_type.get_cname (), collection_backup.name);
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (get_variable_cexpression (collection_backup.name), (CCodeExpression) stmt.collection.ccodenode)));
} else {
- var ccoldecl = new CCodeDeclaration (collection_type.get_cname ());
- var ccolvardecl = new CCodeVariableDeclarator (collection_backup.name, (CCodeExpression) stmt.collection.ccodenode);
- ccolvardecl.line = cblock.line;
- ccoldecl.add_declarator (ccolvardecl);
- cblock.add_statement (ccoldecl);
+ var ccolvardecl = new CCodeVariableDeclarator (collection_backup.name);
+ ccode.add_declaration (collection_type.get_cname (), ccolvardecl);
}
+ ccode.add_expression (new CCodeAssignment (get_variable_cexpression (collection_backup.name), (CCodeExpression) stmt.collection.ccodenode));
if (stmt.tree_can_fail && stmt.collection.tree_can_fail) {
// exception handling
- cfrag = new CCodeFragment ();
- add_simple_check (stmt.collection, cfrag);
- cblock.add_statement (cfrag);
+ add_simple_check (stmt.collection);
}
if (stmt.collection.value_type is ArrayType) {
@@ -288,24 +240,24 @@ public class Vala.CCodeControlFlowModule : CCodeMethodModule {
// store array length for use by _vala_array_free
if (current_method != null && current_method.coroutine) {
closure_struct.add_field ("int", get_array_length_cname (collection_backup.name, 1));
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (get_variable_cexpression (get_array_length_cname (collection_backup.name, 1)), array_len)));
} else {
- var clendecl = new CCodeDeclaration ("int");
- clendecl.add_declarator (new CCodeVariableDeclarator (get_array_length_cname (collection_backup.name, 1), array_len));
- cblock.add_statement (clendecl);
+ ccode.add_declaration ("int", new CCodeVariableDeclarator (get_array_length_cname (collection_backup.name, 1)));
}
+ ccode.add_expression (new CCodeAssignment (get_variable_cexpression (get_array_length_cname (collection_backup.name, 1)), array_len));
var it_name = (stmt.variable_name + "_it");
if (current_method != null && current_method.coroutine) {
closure_struct.add_field ("int", it_name);
} else {
- var citdecl = new CCodeDeclaration ("int");
- citdecl.add_declarator (new CCodeVariableDeclarator (it_name));
- cblock.add_statement (citdecl);
+ ccode.add_declaration ("int", new CCodeVariableDeclarator (it_name));
}
-
- var cbody = new CCodeBlock ();
+
+ var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, get_variable_cexpression (it_name), array_len);
+
+ ccode.open_for (new CCodeAssignment (get_variable_cexpression (it_name), new CCodeConstant ("0")),
+ ccond,
+ new CCodeAssignment (get_variable_cexpression (it_name), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, get_variable_cexpression (it_name), new CCodeConstant ("1"))));
CCodeExpression element_expr = new CCodeElementAccess (get_variable_cexpression (collection_backup.name), get_variable_cexpression (it_name));
@@ -313,19 +265,12 @@ public class Vala.CCodeControlFlowModule : CCodeMethodModule {
element_type.value_owned = false;
element_expr = transform_expression (element_expr, element_type, stmt.type_reference);
- cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
- cbody.add_statement (cfrag);
- temp_vars.clear ();
-
if (current_method != null && current_method.coroutine) {
closure_struct.add_field (stmt.type_reference.get_cname (), stmt.variable_name);
- cbody.add_statement (new CCodeExpressionStatement (new CCodeAssignment (get_variable_cexpression (stmt.variable_name), element_expr)));
} else {
- var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
- cdecl.add_declarator (new CCodeVariableDeclarator (stmt.variable_name, element_expr));
- cbody.add_statement (cdecl);
+ ccode.add_declaration (stmt.type_reference.get_cname (), new CCodeVariableDeclarator (stmt.variable_name));
}
+ ccode.add_expression (new CCodeAssignment (get_variable_cexpression (stmt.variable_name), element_expr));
// add array length variable for stacked arrays
if (stmt.type_reference is ArrayType) {
@@ -333,23 +278,16 @@ public class Vala.CCodeControlFlowModule : CCodeMethodModule {
for (int dim = 1; dim <= inner_array_type.rank; dim++) {
if (current_method != null && current_method.coroutine) {
closure_struct.add_field ("int", get_array_length_cname (stmt.variable_name, dim));
- cbody.add_statement (new CCodeExpressionStatement (new CCodeAssignment (get_variable_cexpression (get_array_length_cname (stmt.variable_name, dim)), new CCodeConstant ("-1"))));
+ ccode.add_expression (new CCodeAssignment (get_variable_cexpression (get_array_length_cname (stmt.variable_name, dim)), new CCodeConstant ("-1")));
} else {
- var cdecl = new CCodeDeclaration ("int");
- cdecl.add_declarator (new CCodeVariableDeclarator (get_array_length_cname (stmt.variable_name, dim), new CCodeConstant ("-1")));
- cbody.add_statement (cdecl);
+ ccode.add_declaration ("int", new CCodeVariableDeclarator (get_array_length_cname (stmt.variable_name, dim), new CCodeConstant ("-1")));
}
}
}
- cbody.add_statement (stmt.body.ccodenode);
-
- var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, get_variable_cexpression (it_name), array_len);
+ stmt.body.emit (this);
- var cfor = new CCodeForStatement (ccond, cbody);
- cfor.add_initializer (new CCodeAssignment (get_variable_cexpression (it_name), new CCodeConstant ("0")));
- cfor.add_iterator (new CCodeAssignment (get_variable_cexpression (it_name), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, get_variable_cexpression (it_name), new CCodeConstant ("1"))));
- cblock.add_statement (cfor);
+ ccode.close ();
} else if (stmt.collection.value_type.compatible (new ObjectType (glist_type)) || stmt.collection.value_type.compatible (new ObjectType (gslist_type))) {
// iterating over a GList or GSList
@@ -358,14 +296,14 @@ public class Vala.CCodeControlFlowModule : CCodeMethodModule {
if (current_method != null && current_method.coroutine) {
closure_struct.add_field (collection_type.get_cname (), it_name);
} else {
- var citdecl = new CCodeDeclaration (collection_type.get_cname ());
- var citvardecl = new CCodeVariableDeclarator (it_name);
- citvardecl.line = cblock.line;
- citdecl.add_declarator (citvardecl);
- cblock.add_statement (citdecl);
+ ccode.add_declaration (collection_type.get_cname (), new CCodeVariableDeclarator (it_name));
}
- var cbody = new CCodeBlock ();
+ var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, get_variable_cexpression (it_name), new CCodeConstant ("NULL"));
+
+ ccode.open_for (new CCodeAssignment (get_variable_cexpression (it_name), get_variable_cexpression (collection_backup.name)),
+ ccond,
+ new CCodeAssignment (get_variable_cexpression (it_name), new CCodeMemberAccess.pointer (get_variable_cexpression (it_name), "next")));
CCodeExpression element_expr = new CCodeMemberAccess.pointer (get_variable_cexpression (it_name), "data");
@@ -380,32 +318,16 @@ public class Vala.CCodeControlFlowModule : CCodeMethodModule {
element_expr = convert_from_generic_pointer (element_expr, element_data_type);
element_expr = transform_expression (element_expr, element_data_type, stmt.type_reference);
- cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
- cbody.add_statement (cfrag);
- temp_vars.clear ();
-
if (current_method != null && current_method.coroutine) {
closure_struct.add_field (stmt.type_reference.get_cname (), stmt.variable_name);
- cbody.add_statement (new CCodeExpressionStatement (new CCodeAssignment (get_variable_cexpression (stmt.variable_name), element_expr)));
} else {
- var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
- var cvardecl = new CCodeVariableDeclarator (stmt.variable_name, element_expr);
- cvardecl.line = cblock.line;
- cdecl.add_declarator (cvardecl);
- cbody.add_statement (cdecl);
+ ccode.add_declaration (stmt.type_reference.get_cname (), new CCodeVariableDeclarator (stmt.variable_name));
}
-
- cbody.add_statement (stmt.body.ccodenode);
-
- var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, get_variable_cexpression (it_name), new CCodeConstant ("NULL"));
-
- var cfor = new CCodeForStatement (ccond, cbody);
-
- cfor.add_initializer (new CCodeAssignment (get_variable_cexpression (it_name), get_variable_cexpression (collection_backup.name)));
+ ccode.add_expression (new CCodeAssignment (get_variable_cexpression (stmt.variable_name), element_expr));
- cfor.add_iterator (new CCodeAssignment (get_variable_cexpression (it_name), new CCodeMemberAccess.pointer (get_variable_cexpression (it_name), "next")));
- cblock.add_statement (cfor);
+ stmt.body.emit (this);
+
+ ccode.close ();
} else if (stmt.collection.value_type.compatible (new ObjectType (gvaluearray_type))) {
// iterating over a GValueArray
@@ -414,14 +336,14 @@ public class Vala.CCodeControlFlowModule : CCodeMethodModule {
if (current_method != null && current_method.coroutine) {
closure_struct.add_field (uint_type.get_cname (), arr_index);
} else {
- var citdecl = new CCodeDeclaration (uint_type.get_cname ());
- var citvardecl = new CCodeVariableDeclarator (arr_index);
- citvardecl.line = cblock.line;
- citdecl.add_declarator (citvardecl);
- cblock.add_statement (citdecl);
+ ccode.add_declaration (uint_type.get_cname (), new CCodeVariableDeclarator (arr_index));
}
- var cbody = new CCodeBlock ();
+ var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, get_variable_cexpression (arr_index), new CCodeMemberAccess.pointer (get_variable_cexpression (collection_backup.name), "n_values"));
+
+ ccode.open_for (new CCodeAssignment (get_variable_cexpression (arr_index), new CCodeConstant ("0")),
+ ccond,
+ new CCodeAssignment (get_variable_cexpression (arr_index), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, get_variable_cexpression (arr_index), new CCodeConstant ("1"))));
var get_item = new CCodeFunctionCall (new CCodeIdentifier ("g_value_array_get_nth"));
get_item.add_argument (get_variable_cexpression (collection_backup.name));
@@ -433,56 +355,39 @@ public class Vala.CCodeControlFlowModule : CCodeMethodModule {
element_expr = get_ref_cexpression (stmt.type_reference, element_expr, null, new StructValueType (gvalue_type));
}
- cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
- cbody.add_statement (cfrag);
- temp_vars.clear ();
-
if (current_method != null && current_method.coroutine) {
closure_struct.add_field (stmt.type_reference.get_cname (), stmt.variable_name);
- cbody.add_statement (new CCodeExpressionStatement (new CCodeAssignment (get_variable_cexpression (stmt.variable_name), element_expr)));
} else {
- var cdecl = new CCodeDeclaration (stmt.type_reference.get_cname ());
- var cvardecl = new CCodeVariableDeclarator (stmt.variable_name, element_expr);
- cvardecl.line = cblock.line;
- cdecl.add_declarator (cvardecl);
- cbody.add_statement (cdecl);
+ ccode.add_declaration (stmt.type_reference.get_cname (), new CCodeVariableDeclarator (stmt.variable_name));
}
+ ccode.add_expression (new CCodeAssignment (get_variable_cexpression (stmt.variable_name), element_expr));
- cbody.add_statement (stmt.body.ccodenode);
-
- var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, get_variable_cexpression (arr_index), new CCodeMemberAccess.pointer (get_variable_cexpression (collection_backup.name), "n_values"));
-
- var cfor = new CCodeForStatement (ccond, cbody);
-
- cfor.add_initializer (new CCodeAssignment (get_variable_cexpression (arr_index), new CCodeConstant ("0")));
+ stmt.body.emit (this);
- cfor.add_iterator (new CCodeAssignment (get_variable_cexpression (arr_index), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, get_variable_cexpression (arr_index), new CCodeConstant ("1"))));
-
- cblock.add_statement (cfor);
+ ccode.close ();
}
foreach (LocalVariable local in stmt.get_local_variables ()) {
if (requires_destroy (local.variable_type)) {
var ma = new MemberAccess.simple (local.name);
ma.symbol_reference = local;
- var cunref = new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma));
- cunref.line = cblock.line;
- cblock.add_statement (cunref);
+ ccode.add_expression (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma));
}
}
+
+ ccode.close ();
}
public override void visit_break_statement (BreakStatement stmt) {
- stmt.ccodenode = new CCodeBreakStatement ();
+ append_local_free (current_symbol, true);
- create_local_free (stmt, true);
+ ccode.add_break ();
}
public override void visit_continue_statement (ContinueStatement stmt) {
- stmt.ccodenode = new CCodeContinueStatement ();
+ append_local_free (current_symbol, true);
- create_local_free (stmt, true);
+ ccode.add_continue ();
}
}
diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala
index bbe085f..fbdbbe5 100644
--- a/codegen/valaccodememberaccessmodule.vala
+++ b/codegen/valaccodememberaccessmodule.vala
@@ -69,7 +69,7 @@ public class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
// instance expression has side-effects
// store in temp. variable
var temp_var = get_temp_variable (expr.inner.value_type, true, null, false);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
var ctemp = get_variable_cexpression (temp_var.name);
inst = new CCodeAssignment (ctemp, pub_inst);
expr.inner.ccodenode = ctemp;
@@ -264,7 +264,7 @@ public class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (expr.inner.target_type, true, null, false);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), pub_inst));
ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (temp_var.name)));
@@ -281,7 +281,7 @@ public class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (base_property.get_accessor.value_type);
var ctemp = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ctemp));
ccomma.append_expression (ccall);
ccomma.append_expression (ctemp);
@@ -292,7 +292,7 @@ public class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
for (int dim = 1; dim <= array_type.rank; dim++) {
var temp_var = get_temp_variable (int_type);
var ctemp = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ctemp));
expr.append_array_size (ctemp);
}
@@ -301,7 +301,7 @@ public class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
var temp_var = get_temp_variable (new PointerType (new VoidType ()));
var ctemp = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ctemp));
expr.delegate_target = ctemp;
}
@@ -332,7 +332,7 @@ public class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (expr.value_type);
var ctemp = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ctemp));
ccall.add_argument (new CCodeConstant ("NULL"));
ccomma.append_expression (ccall);
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index 5a01c91..f1dd342 100644
--- a/codegen/valaccodemethodcallmodule.vala
+++ b/codegen/valaccodemethodcallmodule.vala
@@ -200,7 +200,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (ma.inner.target_type, true, null, false);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), instance));
ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (temp_var.name)));
@@ -353,14 +353,14 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
if (param.array_length_type != null) {
if (param.direction == ParameterDirection.OUT) {
var temp_array_length = get_temp_variable (new CType (param.array_length_type));
- temp_vars.add (temp_array_length);
+ emit_temp_var (temp_array_length);
array_length_expr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (temp_array_length.name));
var comma = new CCodeCommaExpression ();
LocalVariable? temp_result = null;
if (!(m.return_type is VoidType)) {
temp_result = get_temp_variable (m.return_type);
- temp_vars.add (temp_result);
+ emit_temp_var (temp_result);
ccall_expr = new CCodeAssignment (get_variable_cexpression (temp_result.name), ccall_expr);
}
@@ -430,7 +430,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
var ccomma = new CCodeCommaExpression ();
var temp_decl = get_temp_variable (arg.value_type, true, null, false);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_decl.name), cexpr));
cexpr = get_variable_cexpression (temp_decl.name);
@@ -451,7 +451,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (param.variable_type, param.variable_type.value_owned);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
cexpr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (temp_var.name));
if (param.direction == ParameterDirection.REF) {
@@ -468,14 +468,14 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
ccomma.append_expression (ccall_expr);
} else {
ret_temp_var = get_temp_variable (itype.get_return_type (), true, null, false);
- temp_vars.add (ret_temp_var);
+ emit_temp_var (ret_temp_var);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (ret_temp_var.name), ccall_expr));
}
var cassign_comma = new CCodeCommaExpression ();
var assign_temp_var = get_temp_variable (unary.inner.value_type, unary.inner.value_type.value_owned, null, false);
- temp_vars.add (assign_temp_var);
+ emit_temp_var (assign_temp_var);
cassign_comma.append_expression (new CCodeAssignment (get_variable_cexpression (assign_temp_var.name), transform_expression (get_variable_cexpression (temp_var.name), param.variable_type, unary.inner.value_type, arg)));
@@ -538,7 +538,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
var temp_var = get_temp_variable (itype.get_return_type (), true, null, false);
var temp_ref = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccall_expr = new CCodeAssignment (temp_ref, ccall_expr);
@@ -557,7 +557,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
}
var temp_ref = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
out_arg_map.set (get_param_pos (m.carray_length_parameter_position + 0.01 * dim), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
@@ -573,7 +573,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
var temp_var = get_temp_variable (new PointerType (new VoidType ()));
var temp_ref = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
out_arg_map.set (get_param_pos (m.cdelegate_target_parameter_position), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
@@ -583,7 +583,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
temp_var = get_temp_variable (new DelegateType ((Delegate) context.root.scope.lookup ("GLib").scope.lookup ("DestroyNotify")));
temp_ref = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
out_arg_map.set (get_param_pos (m.cdelegate_target_parameter_position + 0.01), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
@@ -602,7 +602,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
var temp_var = get_temp_variable (itype.get_return_type (), true, null, false);
var temp_ref = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccall_expr = new CCodeAssignment (temp_ref, ccall_expr);
@@ -615,7 +615,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
var temp_var = get_temp_variable (int_type);
var temp_ref = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
out_arg_map.set (get_param_pos (deleg.carray_length_parameter_position + 0.01 * dim), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
@@ -631,7 +631,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
var temp_var = get_temp_variable (new PointerType (new VoidType ()));
var temp_ref = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
out_arg_map.set (get_param_pos (deleg.cdelegate_target_parameter_position), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
@@ -688,7 +688,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
var temp_var = get_temp_variable (itype.get_return_type ());
var temp_ref = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
out_arg_map.set (get_param_pos (-3), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
@@ -746,20 +746,13 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
}
if (expr.is_yield_expression) {
- if (pre_statement_fragment == null) {
- pre_statement_fragment = new CCodeFragment ();
- }
-
// set state before calling async function to support immediate callbacks
int state = next_coroutine_state++;
- state_switch_statement.add_statement (new CCodeCaseStatement (new CCodeConstant (state.to_string ())));
- state_switch_statement.add_statement (new CCodeGotoStatement ("_state_%d".printf (state)));
-
- pre_statement_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_state_"), new CCodeConstant (state.to_string ()))));
- pre_statement_fragment.append (new CCodeExpressionStatement (async_call));
- pre_statement_fragment.append (new CCodeReturnStatement (new CCodeConstant ("FALSE")));
- pre_statement_fragment.append (new CCodeLabel ("_state_%d".printf (state)));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_state_"), new CCodeConstant (state.to_string ())));
+ ccode.add_expression (async_call);
+ ccode.add_return (new CCodeConstant ("FALSE"));
+ ccode.add_label ("_state_%d".printf (state));
}
if (m is ArrayResizeMethod) {
@@ -771,7 +764,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
var temp_decl = get_temp_variable (int_type);
var temp_ref = get_variable_cexpression (temp_decl.name);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
/* memset needs string.h */
cfile.add_include ("string.h");
diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala
index 4a6e805..89d216f 100644
--- a/codegen/valaccodemethodmodule.vala
+++ b/codegen/valaccodemethodmodule.vala
@@ -129,33 +129,31 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
}
}
- public CCodeStatement complete_async () {
- var complete_block = new CCodeBlock ();
+ public void complete_async () {
+ var state = new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_state_");
+ var zero = new CCodeConstant ("0");
+ var state_is_zero = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, state, zero);
+ ccode.open_if (state_is_zero);
- var direct_block = new CCodeBlock ();
- var direct_call = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_complete"));
var async_result_expr = new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_async_result");
- direct_call.add_argument (async_result_expr);
- direct_block.add_statement (new CCodeExpressionStatement (direct_call));
- var idle_block = new CCodeBlock ();
var idle_call = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_complete_in_idle"));
idle_call.add_argument (async_result_expr);
- idle_block.add_statement (new CCodeExpressionStatement (idle_call));
+ ccode.add_expression (idle_call);
- var state = new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_state_");
- var zero = new CCodeConstant ("0");
- var state_is_zero = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, state, zero);
- var dispatch = new CCodeIfStatement (state_is_zero, idle_block, direct_block);
- complete_block.add_statement (dispatch);
+ ccode.add_else ();
+
+ var direct_call = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_complete"));
+ direct_call.add_argument (async_result_expr);
+ ccode.add_expression (direct_call);
+
+ ccode.close ();
var unref = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
unref.add_argument (async_result_expr);
- complete_block.add_statement (new CCodeExpressionStatement (unref));
-
- complete_block.add_statement (new CCodeReturnStatement (new CCodeConstant ("FALSE")));
+ ccode.add_expression (unref);
- return complete_block;
+ ccode.add_return (new CCodeConstant ("FALSE"));
}
public override void generate_method_declaration (Method m, CCodeFile decl_space) {
@@ -206,34 +204,34 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
}
}
- void register_plugin_types (CCodeFragment module_init_fragment, Symbol sym, Set<Symbol> registered_types) {
+ void register_plugin_types (Symbol sym, Set<Symbol> registered_types) {
var ns = sym as Namespace;
var cl = sym as Class;
var iface = sym as Interface;
if (ns != null) {
foreach (var ns_ns in ns.get_namespaces ()) {
- register_plugin_types (module_init_fragment, ns_ns, registered_types);
+ register_plugin_types (ns_ns, registered_types);
}
foreach (var ns_cl in ns.get_classes ()) {
- register_plugin_types (module_init_fragment, ns_cl, registered_types);
+ register_plugin_types (ns_cl, registered_types);
}
foreach (var ns_iface in ns.get_interfaces ()) {
- register_plugin_types (module_init_fragment, ns_iface, registered_types);
+ register_plugin_types (ns_iface, registered_types);
}
} else if (cl != null) {
- register_plugin_type (module_init_fragment, cl, registered_types);
+ register_plugin_type (cl, registered_types);
foreach (var cl_cl in cl.get_classes ()) {
- register_plugin_types (module_init_fragment, cl_cl, registered_types);
+ register_plugin_types (cl_cl, registered_types);
}
} else if (iface != null) {
- register_plugin_type (module_init_fragment, iface, registered_types);
+ register_plugin_type (iface, registered_types);
foreach (var iface_cl in iface.get_classes ()) {
- register_plugin_types (module_init_fragment, iface_cl, registered_types);
+ register_plugin_types (iface_cl, registered_types);
}
}
}
- void register_plugin_type (CCodeFragment module_init_fragment, ObjectTypeSymbol type_symbol, Set<Symbol> registered_types) {
+ void register_plugin_type (ObjectTypeSymbol type_symbol, Set<Symbol> registered_types) {
if (type_symbol.external_package) {
return;
}
@@ -251,13 +249,13 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
// register base types first
foreach (var base_type in cl.get_base_types ()) {
- register_plugin_type (module_init_fragment, (ObjectTypeSymbol) base_type.data_type, registered_types);
+ register_plugin_type ((ObjectTypeSymbol) base_type.data_type, registered_types);
}
}
var register_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_register_type".printf (type_symbol.get_lower_case_cname (null))));
register_call.add_argument (new CCodeIdentifier (module_init_param_name));
- module_init_fragment.append (new CCodeExpressionStatement (register_call));
+ ccode.add_expression (register_call);
}
public override void visit_method (Method m) {
@@ -280,13 +278,8 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
}
if (m.coroutine) {
- state_switch_statement = new CCodeSwitchStatement (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_state_"));
-
- // initial coroutine state
- state_switch_statement.add_statement (new CCodeCaseStatement (new CCodeConstant ("0")));
- state_switch_statement.add_statement (new CCodeGotoStatement ("_state_0"));
+ next_coroutine_state = 1;
}
- var current_state_switch = state_switch_statement;
var creturn_type = m.return_type;
if (m.return_type.is_real_non_null_struct_type ()) {
@@ -328,13 +321,8 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
}
}
- if (m.comment != null) {
- cfile.add_type_member_definition (new CCodeComment (m.comment.content));
- }
-
CCodeFunction function;
function = new CCodeFunction (m.get_real_cname ());
- m.ccodenode = function;
if (m.is_inline) {
function.modifiers |= CCodeModifiers.INLINE;
@@ -361,8 +349,6 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
// generate *_real_* functions for virtual methods
// also generate them for abstract methods of classes to prevent faulty subclassing
if (!m.is_abstract || (m.is_abstract && current_type_symbol is Class)) {
- /* Methods imported from a plain C file don't
- * have a body, e.g. Vala.Parser.parse_file () */
if (m.body != null) {
if (m.coroutine) {
function = new CCodeFunction (m.get_real_cname () + "_co", "gboolean");
@@ -376,22 +362,37 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
}
}
- var cinit = new CCodeFragment ();
+ if (m.comment != null) {
+ cfile.add_type_member_definition (new CCodeComment (m.comment.content));
+ }
+
+ push_function (function);
// generate *_real_* functions for virtual methods
// also generate them for abstract methods of classes to prevent faulty subclassing
if (!m.is_abstract || (m.is_abstract && current_type_symbol is Class)) {
- /* Methods imported from a plain C file don't
- * have a body, e.g. Vala.Parser.parse_file () */
if (m.body != null) {
if (m.coroutine) {
+ ccode.open_switch (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_state_"));
+
+ // initial coroutine state
+ ccode.add_case (new CCodeConstant ("0"));
+ ccode.add_goto ("_state_0");
+
+ for (int state = 1; state <= m.yield_count; state++) {
+ ccode.add_case (new CCodeConstant (state.to_string ()));
+ ccode.add_goto ("_state_%d".printf (state));
+ }
+
+
// let gcc know that this can't happen
- current_state_switch.add_statement (new CCodeLabel ("default"));
- current_state_switch.add_statement (new CCodeExpressionStatement (new CCodeFunctionCall (new CCodeIdentifier ("g_assert_not_reached"))));
+ ccode.add_default ();
+ ccode.add_expression (new CCodeFunctionCall (new CCodeIdentifier ("g_assert_not_reached")));
- cinit.append (current_state_switch);
+ ccode.close ();
- cinit.append (new CCodeLabel ("_state_0"));
+ // coroutine body
+ ccode.add_label ("_state_0");
}
if (m.closure) {
@@ -407,10 +408,8 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
int parent_block_id = get_block_id (parent_closure_block);
var parent_data = new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), "_data%d_".printf (parent_block_id));
- var cdecl = new CCodeDeclaration ("Block%dData*".printf (parent_block_id));
- cdecl.add_declarator (new CCodeVariableDeclarator ("_data%d_".printf (parent_block_id), parent_data));
-
- cinit.append (cdecl);
+ ccode.add_declaration ("Block%dData*".printf (parent_block_id), new CCodeVariableDeclarator ("_data%d_".printf (parent_block_id)));
+ ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("_data%d_".printf (parent_block_id)), parent_data));
closure_block = parent_closure_block;
block_id = parent_block_id;
@@ -420,10 +419,8 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
// as closures have block data parameter
if (m.binding == MemberBinding.INSTANCE) {
var cself = new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), "self");
- var cdecl = new CCodeDeclaration ("%s *".printf (current_class.get_cname ()));
- cdecl.add_declarator (new CCodeVariableDeclarator ("self", cself));
-
- cinit.append (cdecl);
+ ccode.add_declaration ("%s *".printf (current_class.get_cname ()), new CCodeVariableDeclarator ("self"));
+ ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("self"), cself));
}
} else if (m.parent_symbol is Class && !m.coroutine) {
var cl = (Class) m.parent_symbol;
@@ -440,19 +437,14 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
var self_target_type = new ObjectType (cl);
CCodeExpression cself = 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 ("self", cself));
-
- cinit.append (cdecl);
+ ccode.add_declaration ("%s *".printf (cl.get_cname ()), new CCodeVariableDeclarator ("self"));
+ ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("self"), cself));
} else if (m.binding == MemberBinding.INSTANCE
- && !(m is CreationMethod)) {
- var ccheckstmt = create_method_type_check_statement (m, creturn_type, cl, true, "self");
- if (ccheckstmt != null) {
- ccheckstmt.line = function.line;
- cinit.append (ccheckstmt);
- }
+ && !(m is CreationMethod)) {
+ create_method_type_check_statement (m, creturn_type, cl, true, "self");
}
}
+
foreach (FormalParameter param in m.get_parameters ()) {
if (param.ellipsis) {
break;
@@ -461,11 +453,7 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
if (param.direction != ParameterDirection.OUT) {
var t = param.variable_type.data_type;
if (t != null && t.is_reference_type ()) {
- var type_check = create_method_type_check_statement (m, creturn_type, t, !param.variable_type.nullable, get_variable_cname (param.name));
- if (type_check != null) {
- type_check.line = function.line;
- cinit.append (type_check);
- }
+ create_method_type_check_statement (m, creturn_type, t, !param.variable_type.nullable, get_variable_cname (param.name));
}
} else if (!m.coroutine) {
var t = param.variable_type.data_type;
@@ -477,36 +465,28 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
var condition = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, get_variable_cexpression (param.name), new CCodeConstant ("NULL"));
var if_statement = new CCodeIfStatement (condition, cblock);
- cinit.append (if_statement);
+ ccode.add_statement (if_statement);
}
}
}
if (!(m.return_type is VoidType) && !m.return_type.is_real_non_null_struct_type () && !m.coroutine) {
- var cdecl = new CCodeDeclaration (m.return_type.get_cname ());
var vardecl = new CCodeVariableDeclarator ("result", default_value_for_type (m.return_type, true));
vardecl.init0 = true;
- cdecl.add_declarator (vardecl);
- cinit.append (cdecl);
+ ccode.add_declaration (m.return_type.get_cname (), vardecl);
}
if (m is CreationMethod) {
if (in_gobject_creation_method) {
- var cdeclaration = new CCodeDeclaration ("%s *".printf (((Class) current_type_symbol).get_cname ()));
- cdeclaration.add_declarator (new CCodeVariableDeclarator ("self"));
-
- cinit.append (cdeclaration);
+ ccode.add_declaration ("%s *".printf (((Class) current_type_symbol).get_cname ()), new CCodeVariableDeclarator ("self"));
} else if (is_gtypeinstance_creation_method (m)) {
var cl = (Class) m.parent_symbol;
- var cdeclaration = new CCodeDeclaration (cl.get_cname () + "*");
- var cdecl = new CCodeVariableDeclarator ("self");
- cdeclaration.add_declarator (cdecl);
- cinit.append (cdeclaration);
+ ccode.add_declaration (cl.get_cname () + "*", new CCodeVariableDeclarator ("self"));
if (cl.is_fundamental ()) {
var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_create_instance"));
ccall.add_argument (new CCodeIdentifier ("object_type"));
- cdecl.initializer = new CCodeCastExpression (ccall, cl.get_cname () + "*");
+ ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("self"), new CCodeCastExpression (ccall, cl.get_cname () + "*")));
/* type, dup func, and destroy func fields for generic types */
foreach (TypeParameter type_param in current_class.get_type_parameters ()) {
@@ -517,36 +497,33 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
param_name = new CCodeIdentifier ("%s_type".printf (type_param.name.down ()));
assign = new CCodeAssignment (new CCodeMemberAccess.pointer (priv_access, param_name.name), param_name);
- cinit.append (new CCodeExpressionStatement (assign));
+ ccode.add_expression (assign);
param_name = new CCodeIdentifier ("%s_dup_func".printf (type_param.name.down ()));
assign = new CCodeAssignment (new CCodeMemberAccess.pointer (priv_access, param_name.name), param_name);
- cinit.append (new CCodeExpressionStatement (assign));
+ ccode.add_expression (assign);
param_name = new CCodeIdentifier ("%s_destroy_func".printf (type_param.name.down ()));
assign = new CCodeAssignment (new CCodeMemberAccess.pointer (priv_access, param_name.name), param_name);
- cinit.append (new CCodeExpressionStatement (assign));
+ ccode.add_expression (assign);
}
}
} else if (current_type_symbol is Class) {
var cl = (Class) m.parent_symbol;
- var cdeclaration = new CCodeDeclaration (cl.get_cname () + "*");
- var cdecl = new CCodeVariableDeclarator ("self");
- cdeclaration.add_declarator (cdecl);
- cinit.append (cdeclaration);
+ ccode.add_declaration (cl.get_cname () + "*", new CCodeVariableDeclarator ("self"));
if (!((CreationMethod) m).chain_up) {
// TODO implicitly chain up to base class as in add_object_creation
var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_new0"));
ccall.add_argument (new CCodeIdentifier (cl.get_cname ()));
- cdecl.initializer = ccall;
+ ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("self"), ccall));
}
if (cl.base_class == null) {
// derived compact classes do not have fields
var cinitcall = new CCodeFunctionCall (new CCodeIdentifier ("%s_instance_init".printf (cl.get_lower_case_cname (null))));
cinitcall.add_argument (new CCodeIdentifier ("self"));
- cinit.append (new CCodeExpressionStatement (cinitcall));
+ ccode.add_expression (cinitcall);
}
} else {
var st = (Struct) m.parent_symbol;
@@ -557,20 +534,17 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
czero.add_argument (new CCodeIdentifier ("self"));
czero.add_argument (new CCodeConstant ("0"));
czero.add_argument (new CCodeIdentifier ("sizeof (%s)".printf (st.get_cname ())));
- cinit.append (new CCodeExpressionStatement (czero));
+ ccode.add_expression (czero);
}
}
if (context.module_init_method == m && in_plugin) {
// GTypeModule-based plug-in, register types
- register_plugin_types (cinit, context.root, new HashSet<Symbol> ());
+ register_plugin_types (context.root, new HashSet<Symbol> ());
}
foreach (Expression precondition in m.get_preconditions ()) {
- var check_stmt = create_precondition_statement (m, creturn_type, precondition);
- if (check_stmt != null) {
- cinit.append (check_stmt);
- }
+ create_precondition_statement (m, creturn_type, precondition);
}
}
}
@@ -585,11 +559,6 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
/* Methods imported from a plain C file don't
* have a body, e.g. Vala.Parser.parse_file () */
if (m.body != null) {
- function.block = (CCodeBlock) m.body.ccodenode;
- function.block.line = function.line;
-
- function.block.prepend_statement (cinit);
-
if (current_method_inner_error) {
/* always separate error parameter and inner_error local variable
* as error may be set to NULL but we're always interested in inner errors
@@ -599,61 +568,90 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
// no initialization necessary, closure struct is zeroed
} else {
- var cdecl = new CCodeDeclaration ("GError *");
- cdecl.add_declarator (new CCodeVariableDeclarator.zero ("_inner_error_", new CCodeConstant ("NULL")));
- function.block.add_statement (cdecl);
+ ccode.add_declaration ("GError *", new CCodeVariableDeclarator.zero ("_inner_error_", new CCodeConstant ("NULL")));
}
}
if (m.coroutine) {
// epilogue
- function.block.add_statement (complete_async ());
+ complete_async ();
}
if (!(m.return_type is VoidType) && !m.return_type.is_real_non_null_struct_type () && !m.coroutine) {
// add dummy return if exit block is known to be unreachable to silence C compiler
if (m.return_block != null && m.return_block.get_predecessors ().size == 0) {
- function.block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
+ ccode.add_return (new CCodeIdentifier ("result"));
}
}
- cfile.add_function (function);
- } else if (m.is_abstract) {
- // generate helpful error message if a sublcass does not implement an abstract method.
- // This is only meaningful for subclasses implemented in C since the vala compiler would
- // complain during compile time of such en error.
+ if (m is CreationMethod) {
+ if (current_type_symbol is Class) {
+ creturn_type = new ObjectType (current_class);
+ } else {
+ creturn_type = new VoidType ();
+ }
+
- var cblock = new CCodeBlock ();
+ if (current_type_symbol is Class && gobject_type != null && current_class.is_subtype_of (gobject_type)
+ && current_class.get_type_parameters ().size > 0
+ && !((CreationMethod) m).chain_up) {
+ var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.GREATER_THAN, new CCodeIdentifier ("__params_it"), new CCodeIdentifier ("__params"));
+ var cdofreeparam = new CCodeBlock ();
+ cdofreeparam.add_statement (new CCodeExpressionStatement (new CCodeUnaryExpression (CCodeUnaryOperator.PREFIX_DECREMENT, new CCodeIdentifier ("__params_it"))));
+ var cunsetcall = new CCodeFunctionCall (new CCodeIdentifier ("g_value_unset"));
+ cunsetcall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeMemberAccess.pointer (new CCodeIdentifier ("__params_it"), "value")));
+ cdofreeparam.add_statement (new CCodeExpressionStatement (cunsetcall));
+ ccode.add_statement (new CCodeWhileStatement (ccond, cdofreeparam));
+
+ var cfreeparams = new CCodeFunctionCall (new CCodeIdentifier ("g_free"));
+ cfreeparams.add_argument (new CCodeIdentifier ("__params"));
+ ccode.add_expression (cfreeparams);
+ }
+
+ if (current_type_symbol is Class) {
+ CCodeExpression cresult = new CCodeIdentifier ("self");
+ if (get_custom_creturn_type (m) != null) {
+ cresult = new CCodeCastExpression (cresult, get_custom_creturn_type (m));
+ }
- // add a typecheck statement for "self"
- var check_stmt = create_method_type_check_statement (m, creturn_type, current_type_symbol, true, "self");
- if (check_stmt != null) {
- cblock.add_statement (check_stmt);
+ ccode.add_return (cresult);
+ }
}
- // add critical warning that this method should not have been called
- var type_from_instance_call = new CCodeFunctionCall (new CCodeIdentifier ("G_TYPE_FROM_INSTANCE"));
- type_from_instance_call.add_argument (new CCodeIdentifier ("self"));
-
- var type_name_call = new CCodeFunctionCall (new CCodeIdentifier ("g_type_name"));
- type_name_call.add_argument (type_from_instance_call);
+ cfile.add_function (ccode);
+ }
+ }
- var error_string = "\"Type `%%s' does not implement abstract method `%s'\"".printf (m.get_cname ());
+ if (m.is_abstract) {
+ // generate helpful error message if a sublcass does not implement an abstract method.
+ // This is only meaningful for subclasses implemented in C since the vala compiler would
+ // complain during compile time of such en error.
- var cerrorcall = new CCodeFunctionCall (new CCodeIdentifier ("g_critical"));
- cerrorcall.add_argument (new CCodeConstant (error_string));
- cerrorcall.add_argument (type_name_call);
+ // add a typecheck statement for "self"
+ create_method_type_check_statement (m, creturn_type, current_type_symbol, true, "self");
- cblock.add_statement (new CCodeExpressionStatement (cerrorcall));
+ // add critical warning that this method should not have been called
+ var type_from_instance_call = new CCodeFunctionCall (new CCodeIdentifier ("G_TYPE_FROM_INSTANCE"));
+ type_from_instance_call.add_argument (new CCodeIdentifier ("self"));
- // add return statement
- cblock.add_statement (new CCodeReturnStatement (default_value_for_type (creturn_type, false)));
+ var type_name_call = new CCodeFunctionCall (new CCodeIdentifier ("g_type_name"));
+ type_name_call.add_argument (type_from_instance_call);
- function.block = cblock;
- cfile.add_function (function);
- }
+ var error_string = "\"Type `%%s' does not implement abstract method `%s'\"".printf (m.get_cname ());
+
+ var cerrorcall = new CCodeFunctionCall (new CCodeIdentifier ("g_critical"));
+ cerrorcall.add_argument (new CCodeConstant (error_string));
+ cerrorcall.add_argument (type_name_call);
+
+ ccode.add_expression (cerrorcall);
+
+ // add return statement
+ ccode.add_return (default_value_for_type (creturn_type, false));
+
+ cfile.add_function (ccode);
}
+
in_static_or_class_context = false;
pop_context ();
@@ -885,23 +883,13 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
}
public void generate_vfunc (Method m, DataType return_type, Map<int,CCodeFormalParameter> cparam_map, Map<int,CCodeExpression> carg_map, string suffix = "", int direction = 3) {
+ push_context (new EmitContext ());
+
string cname = m.get_cname ();
if (suffix == "_finish" && cname.has_suffix ("_async")) {
cname = cname.substring (0, cname.length - "_async".length);
}
var vfunc = new CCodeFunction (cname + suffix);
- if (function != null) {
- vfunc.line = function.line;
- }
-
- var vblock = new CCodeBlock ();
-
- foreach (Expression precondition in m.get_preconditions ()) {
- var check_stmt = create_precondition_statement (m, return_type, precondition);
- if (check_stmt != null) {
- vblock.add_statement (check_stmt);
- }
- }
CCodeFunctionCall vcast = null;
if (m.parent_symbol is Interface) {
@@ -924,47 +912,45 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
generate_cparameters (m, cfile, cparam_map, vfunc, null, carg_map, vcall, direction);
- CCodeStatement cstmt;
+ push_function (vfunc);
+
+ foreach (Expression precondition in m.get_preconditions ()) {
+ create_precondition_statement (m, return_type, precondition);
+ }
+
if (return_type is VoidType || return_type.is_real_non_null_struct_type ()) {
- cstmt = new CCodeExpressionStatement (vcall);
+ ccode.add_expression (vcall);
} else if (m.get_postconditions ().size == 0) {
/* pass method return value */
- cstmt = new CCodeReturnStatement (vcall);
+ ccode.add_return (vcall);
} else {
/* store method return value for postconditions */
- var cdecl = new CCodeDeclaration (get_creturn_type (m, return_type.get_cname ()));
- cdecl.add_declarator (new CCodeVariableDeclarator ("result", vcall));
- cstmt = cdecl;
+ ccode.add_declaration (get_creturn_type (m, return_type.get_cname ()), new CCodeVariableDeclarator ("result"));
+ ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("result"), vcall));
}
- cstmt.line = vfunc.line;
- vblock.add_statement (cstmt);
if (m.get_postconditions ().size > 0) {
foreach (Expression postcondition in m.get_postconditions ()) {
- vblock.add_statement (create_postcondition_statement (postcondition));
+ create_postcondition_statement (postcondition);
}
if (!(return_type is VoidType)) {
- var cret_stmt = new CCodeReturnStatement (new CCodeIdentifier ("result"));
- cret_stmt.line = vfunc.line;
- vblock.add_statement (cret_stmt);
+ ccode.add_return (new CCodeIdentifier ("result"));
}
}
- vfunc.block = vblock;
-
cfile.add_function (vfunc);
+
+ pop_context ();
}
- private CCodeStatement? create_method_type_check_statement (Method m, DataType return_type, TypeSymbol t, bool non_null, string var_name) {
- if (m.coroutine) {
- return null;
- } else {
- return create_type_check_statement (m, return_type, t, non_null, var_name);
+ private void create_method_type_check_statement (Method m, DataType return_type, TypeSymbol t, bool non_null, string var_name) {
+ if (!m.coroutine) {
+ create_type_check_statement (m, return_type, t, non_null, var_name);
}
}
- private CCodeStatement? create_precondition_statement (CodeNode method_node, DataType ret_type, Expression precondition) {
+ private void create_precondition_statement (CodeNode method_node, DataType ret_type, Expression precondition) {
var ccheck = new CCodeFunctionCall ();
ccheck.add_argument ((CCodeExpression) precondition.ccodenode);
@@ -986,11 +972,11 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
if (cdefault != null) {
ccheck.add_argument (cdefault);
} else {
- return null;
+ return;
}
}
- return new CCodeExpressionStatement (ccheck);
+ ccode.add_expression (ccheck);
}
private TypeSymbol? find_parent_type (Symbol sym) {
@@ -1012,19 +998,9 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
return;
}
- function = (CCodeFunction) m.ccodenode;
-
- DataType creturn_type;
- if (current_type_symbol is Class) {
- creturn_type = new ObjectType (current_class);
- } else {
- creturn_type = new VoidType ();
- }
-
// do not generate _new functions for creation methods of abstract classes
if (current_type_symbol is Class && !current_class.is_compact && !current_class.is_abstract) {
var vfunc = new CCodeFunction (m.get_cname ());
- vfunc.line = function.line;
var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
var carg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
@@ -1047,17 +1023,6 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
cfile.add_function (vfunc);
}
-
- if (current_type_symbol is Class) {
- CCodeExpression cresult = new CCodeIdentifier ("self");
- if (get_custom_creturn_type (m) != null) {
- cresult = new CCodeCastExpression (cresult, get_custom_creturn_type (m));
- }
-
- var creturn = new CCodeReturnStatement ();
- creturn.return_expression = cresult;
- function.block.add_statement (creturn);
- }
}
}
diff --git a/codegen/valaccodestructmodule.vala b/codegen/valaccodestructmodule.vala
index 04b831c..51e5d7f 100644
--- a/codegen/valaccodestructmodule.vala
+++ b/codegen/valaccodestructmodule.vala
@@ -142,8 +142,8 @@ public class Vala.CCodeStructModule : CCodeBaseModule {
public override void visit_struct (Struct st) {
push_context (new EmitContext (st));
- var old_instance_finalize_fragment = instance_finalize_fragment;
- instance_finalize_fragment = new CCodeFragment ();
+ var old_instance_finalize_context = instance_finalize_context;
+ instance_finalize_context = new EmitContext ();
generate_struct_declaration (st, cfile);
@@ -154,6 +154,8 @@ public class Vala.CCodeStructModule : CCodeBaseModule {
generate_struct_declaration (st, internal_header_file);
}
+ begin_struct_destroy_function (st);
+
st.accept_children (this);
if (context.profile == Profile.GOBJECT && !st.is_boolean_type () && !st.is_integer_type () && !st.is_floating_type ()) {
@@ -166,7 +168,7 @@ public class Vala.CCodeStructModule : CCodeBaseModule {
add_struct_free_function (st);
}
- instance_finalize_fragment = old_instance_finalize_fragment;
+ instance_finalize_context = old_instance_finalize_context;
pop_context ();
}
@@ -294,15 +296,14 @@ public class Vala.CCodeStructModule : CCodeBaseModule {
}
}
- append_temp_decl (cfrag, temp_vars);
- temp_vars.clear ();
-
function.block = cblock;
cfile.add_function (function);
}
- void add_struct_destroy_function (Struct st) {
+ void begin_struct_destroy_function (Struct st) {
+ push_context (instance_finalize_context);
+
var function = new CCodeFunction (st.get_destroy_function (), "void");
if (st.access == SymbolAccessibility.PRIVATE) {
function.modifiers = CCodeModifiers.STATIC;
@@ -310,13 +311,13 @@ public class Vala.CCodeStructModule : CCodeBaseModule {
function.add_parameter (new CCodeFormalParameter ("self", st.get_cname () + "*"));
- var cblock = new CCodeBlock ();
-
- cblock.add_statement (instance_finalize_fragment);
+ push_function (function);
- function.block = cblock;
+ pop_context ();
+ }
- cfile.add_function (function);
+ void add_struct_destroy_function (Struct st) {
+ cfile.add_function (instance_finalize_context.ccode);
}
}
diff --git a/codegen/valadovaarraymodule.vala b/codegen/valadovaarraymodule.vala
index 93978f1..182ffce 100644
--- a/codegen/valadovaarraymodule.vala
+++ b/codegen/valadovaarraymodule.vala
@@ -38,7 +38,7 @@ public class Vala.DovaArrayModule : DovaMethodCallModule {
var name_cnode = new CCodeIdentifier (temp_var.name);
int i = 0;
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
append_initializer_list (ce, name_cnode, expr.initializer_list, ref i);
diff --git a/codegen/valadovaassignmentmodule.vala b/codegen/valadovaassignmentmodule.vala
index 3d21f33..1219a44 100644
--- a/codegen/valadovaassignmentmodule.vala
+++ b/codegen/valadovaassignmentmodule.vala
@@ -102,13 +102,13 @@ public class Vala.DovaAssignmentModule : DovaMemberAccessModule {
var lhs_value_type = assignment.left.value_type.copy ();
string lhs_temp_name = "_tmp%d_".printf (next_temp_var_id++);
var lhs_temp = new LocalVariable (lhs_value_type, "*" + lhs_temp_name);
- temp_vars.add (lhs_temp);
+ emit_temp_var (lhs_temp);
outer_ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (lhs_temp_name), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, lhs)));
lhs = new CCodeParenthesizedExpression (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, get_variable_cexpression (lhs_temp_name)));
}
var temp_decl = get_temp_variable (assignment.left.value_type);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_decl.name), rhs));
if (unref_old) {
/* unref old value */
diff --git a/codegen/valadovabasemodule.vala b/codegen/valadovabasemodule.vala
index 28aaeff..8c5fe91 100644
--- a/codegen/valadovabasemodule.vala
+++ b/codegen/valadovabasemodule.vala
@@ -30,7 +30,8 @@ public class Vala.DovaBaseModule : CodeGenerator {
public Symbol? current_symbol;
public ArrayList<Symbol> symbol_stack = new ArrayList<Symbol> ();
public TryStatement current_try;
- public ArrayList<LocalVariable> temp_vars = new ArrayList<LocalVariable> ();
+ public CCodeFunction ccode;
+ public ArrayList<CCodeFunction> ccode_stack = new ArrayList<CCodeFunction> ();
public ArrayList<LocalVariable> temp_ref_vars = new ArrayList<LocalVariable> ();
public int next_temp_var_id;
public Map<string,string> variable_name_map = new HashMap<string,string> (str_hash, str_equal);
@@ -150,21 +151,15 @@ public class Vala.DovaBaseModule : CodeGenerator {
string? csource_filename;
- public CCodeFragment module_init_fragment;
- public CCodeFragment instance_init_fragment;
- public CCodeFragment instance_finalize_fragment;
+ public CCodeFunction ccode { get { return emit_context.ccode; } }
- // code nodes to be inserted before the current statement
- // used by async method calls in coroutines
- public CCodeFragment pre_statement_fragment;
-
- /* all temporary variables */
- public ArrayList<LocalVariable> temp_vars { get { return emit_context.temp_vars; } }
/* temporary variables that own their content */
public ArrayList<LocalVariable> temp_ref_vars { get { return emit_context.temp_ref_vars; } }
/* (constant) hash table with all reserved identifiers in the generated code */
Set<string> reserved_identifiers;
+ public List<Field> static_fields = new ArrayList<Field> ();
+
public int next_temp_var_id {
get { return emit_context.next_temp_var_id; }
set { emit_context.next_temp_var_id = value; }
@@ -276,7 +271,6 @@ public class Vala.DovaBaseModule : CodeGenerator {
header_file.is_header = true;
cfile = new CCodeFile ();
- module_init_fragment = new CCodeFragment ();
if (context.nostdpkg) {
header_file.add_include ("dova-types.h");
@@ -331,6 +325,16 @@ public class Vala.DovaBaseModule : CodeGenerator {
}
}
+ public void push_function (CCodeFunction func) {
+ emit_context.ccode_stack.add (ccode);
+ emit_context.ccode = func;
+ }
+
+ public void pop_function () {
+ emit_context.ccode = emit_context.ccode_stack[emit_context.ccode_stack.size - 1];
+ emit_context.ccode_stack.remove_at (emit_context.ccode_stack.size - 1);
+ }
+
public bool add_symbol_declaration (CCodeFile decl_space, Symbol sym, string name) {
if (decl_space.add_declaration (name)) {
return true;
@@ -458,71 +462,23 @@ public class Vala.DovaBaseModule : CodeGenerator {
}
public override void visit_field (Field f) {
- if (f.initializer != null) {
- f.initializer.emit (this);
- }
-
- var cl = f.parent_symbol as Class;
-
- CCodeExpression lhs = null;
-
- string field_ctype = f.variable_type.get_cname ();
- if (f.is_volatile) {
- field_ctype = "volatile " + field_ctype;
- }
-
- if (f.binding == MemberBinding.INSTANCE) {
- if (cl != null && f.is_internal_symbol ()) {
- var priv_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_PRIVATE".printf (cl.get_upper_case_cname (null))));
- priv_call.add_argument (new CCodeIdentifier ("this"));
- lhs = new CCodeMemberAccess.pointer (priv_call, f.get_cname ());
- } else {
- lhs = new CCodeMemberAccess.pointer (new CCodeIdentifier ("this"), f.get_cname ());
- }
-
- if (f.initializer != null) {
- var rhs = (CCodeExpression) f.initializer.ccodenode;
-
- instance_init_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (lhs, rhs)));
-
- append_temp_decl (instance_init_fragment, temp_vars);
- temp_vars.clear ();
- }
-
- if (requires_destroy (f.variable_type) && instance_finalize_fragment != null) {
- var this_access = new MemberAccess.simple ("this");
- this_access.value_type = get_data_type_for_symbol ((TypeSymbol) f.parent_symbol);
-
- var field_st = f.parent_symbol as Struct;
- if (field_st != null && !field_st.is_simple_type ()) {
- this_access.ccodenode = new CCodeIdentifier ("(*this)");
- } else {
- this_access.ccodenode = new CCodeIdentifier ("this");
- }
-
- var ma = new MemberAccess (this_access, f.name);
- ma.symbol_reference = f;
- instance_finalize_fragment.append (new CCodeExpressionStatement (get_unref_expression (lhs, f.variable_type, ma)));
- }
- } else {
+ if (f.binding == MemberBinding.STATIC) {
generate_field_declaration (f, cfile);
if (!f.is_internal_symbol ()) {
generate_field_declaration (f, header_file);
}
- lhs = new CCodeIdentifier (f.get_cname ());
-
var var_decl = new CCodeVariableDeclarator (f.get_cname ());
var_decl.initializer = default_value_for_type (f.variable_type, true);
if (f.initializer != null) {
- var rhs = (CCodeExpression) f.initializer.ccodenode;
-
- module_init_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (lhs, rhs)));
+ static_fields.add (f);
+ }
- append_temp_decl (module_init_fragment, temp_vars);
- temp_vars.clear ();
+ string field_ctype = f.variable_type.get_cname ();
+ if (f.is_volatile) {
+ field_ctype = "volatile " + field_ctype;
}
var var_def = new CCodeDeclaration (field_ctype);
@@ -644,16 +600,6 @@ public class Vala.DovaBaseModule : CodeGenerator {
public virtual void generate_property_accessor_declaration (PropertyAccessor acc, CCodeFile decl_space) {
}
- public override void visit_destructor (Destructor d) {
- d.body.emit (this);
-
- CCodeFragment cfrag = new CCodeFragment ();
-
- cfrag.append (d.body.ccodenode);
-
- d.ccodenode = cfrag;
- }
-
public int get_block_id (Block b) {
int result = block_map[b];
if (result == 0) {
@@ -663,7 +609,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
return result;
}
- void capture_parameter (FormalParameter param, CCodeStruct data, CCodeBlock cblock, int block_id, CCodeBlock free_block) {
+ void capture_parameter (FormalParameter param, CCodeStruct data, int block_id, CCodeBlock free_block) {
generate_type_declaration (param.variable_type, cfile);
var param_type = param.variable_type.copy ();
@@ -682,7 +628,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
param.captured = true;
}
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_variable_cname (param.name)), cparam)));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_variable_cname (param.name)), cparam));
if (requires_destroy (param_type)) {
var ma = new MemberAccess.simple (param.name);
@@ -695,17 +641,11 @@ public class Vala.DovaBaseModule : CodeGenerator {
public override void visit_block (Block b) {
emit_context.push_symbol (b);
- foreach (Statement stmt in b.get_statements ()) {
- stmt.emit (this);
- }
-
var local_vars = b.get_local_variables ();
- foreach (LocalVariable local in local_vars) {
- local.active = false;
- }
-
- var cblock = new CCodeBlock ();
+ if (b.parent_node is Block || b.parent_node is SwitchStatement) {
+ ccode.open_block ();
+ }
if (b.captured) {
var parent_block = next_closure_block (b.parent_symbol);
@@ -759,7 +699,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
var data_decl = new CCodeDeclaration (struct_name + "*");
data_decl.add_declarator (new CCodeVariableDeclarator ("_data%d_".printf (block_id), data_alloc));
- cblock.add_statement (data_decl);
+ ccode.add_statement (data_decl);
if (parent_block != null) {
int parent_block_id = get_block_id (parent_block);
@@ -767,13 +707,13 @@ public class Vala.DovaBaseModule : CodeGenerator {
var ref_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_ref"));
ref_call.add_argument (get_variable_cexpression ("_data%d_".printf (parent_block_id)));
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), "_data%d_".printf (parent_block_id)), ref_call)));
+ ccode.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), "_data%d_".printf (parent_block_id)), ref_call)));
} else if ((current_method != null && current_method.binding == MemberBinding.INSTANCE) ||
(current_property_accessor != null && current_property_accessor.prop.binding == MemberBinding.INSTANCE)) {
var ref_call = new CCodeFunctionCall (get_dup_func_expression (new ObjectType (current_class), b.source_reference));
ref_call.add_argument (new CCodeIdentifier ("this"));
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), "this"), ref_call)));
+ ccode.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), "this"), ref_call)));
}
if (b.parent_symbol is Method) {
@@ -782,25 +722,15 @@ public class Vala.DovaBaseModule : CodeGenerator {
// parameters are captured with the top-level block of the method
foreach (var param in m.get_parameters ()) {
if (param.captured) {
- capture_parameter (param, data, cblock, block_id, free_block);
+ capture_parameter (param, data, block_id, free_block);
}
}
-
- var cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
- temp_vars.clear ();
- cblock.add_statement (cfrag);
} else if (b.parent_symbol is PropertyAccessor) {
var acc = (PropertyAccessor) b.parent_symbol;
if (!acc.readable && acc.value_parameter.captured) {
- capture_parameter (acc.value_parameter, data, cblock, block_id, free_block);
+ capture_parameter (acc.value_parameter, data, block_id, free_block);
}
-
- var cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
- temp_vars.clear ();
- cblock.add_statement (cfrag);
}
var typedef = new CCodeTypeDefinition ("struct _" + struct_name, new CCodeVariableDeclarator (struct_name));
@@ -858,18 +788,8 @@ public class Vala.DovaBaseModule : CodeGenerator {
cfile.add_function (unref_fun);
}
- foreach (CodeNode stmt in b.get_statements ()) {
- if (stmt.error) {
- continue;
- }
-
- if (stmt.ccodenode is CCodeFragment) {
- foreach (CCodeNode cstmt in ((CCodeFragment) stmt.ccodenode).get_children ()) {
- cblock.add_statement (cstmt);
- }
- } else {
- cblock.add_statement (stmt.ccodenode);
- }
+ foreach (Statement stmt in b.get_statements ()) {
+ stmt.emit (this);
}
// free in reverse order
@@ -878,7 +798,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
if (!local.floating && !local.captured && requires_destroy (local.variable_type)) {
var ma = new MemberAccess.simple (local.name);
ma.symbol_reference = local;
- cblock.add_statement (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma)));
+ ccode.add_statement (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma)));
}
}
@@ -888,7 +808,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
if (!param.captured && requires_destroy (param.variable_type) && param.direction == ParameterDirection.IN) {
var ma = new MemberAccess.simple (param.name);
ma.symbol_reference = param;
- cblock.add_statement (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (param.name), param.variable_type, ma)));
+ ccode.add_statement (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (param.name), param.variable_type, ma)));
}
}
}
@@ -898,30 +818,18 @@ public class Vala.DovaBaseModule : CodeGenerator {
var data_unref = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_unref"));
data_unref.add_argument (get_variable_cexpression ("_data%d_".printf (block_id)));
- cblock.add_statement (new CCodeExpressionStatement (data_unref));
+ ccode.add_statement (new CCodeExpressionStatement (data_unref));
}
- b.ccodenode = cblock;
+ if (b.parent_node is Block || b.parent_node is SwitchStatement) {
+ ccode.close ();
+ }
emit_context.pop_symbol ();
}
- public override void visit_empty_statement (EmptyStatement stmt) {
- stmt.ccodenode = new CCodeEmptyStatement ();
- }
-
public override void visit_declaration_statement (DeclarationStatement stmt) {
stmt.declaration.accept (this);
-
- stmt.ccodenode = stmt.declaration.ccodenode;
-
- var local = stmt.declaration as LocalVariable;
- if (local != null && local.initializer != null) {
- create_temp_decl (stmt, local.initializer.temp_vars);
- }
-
- create_temp_decl (stmt, temp_vars);
- temp_vars.clear ();
}
public CCodeExpression get_variable_cexpression (string name) {
@@ -957,23 +865,16 @@ public class Vala.DovaBaseModule : CodeGenerator {
rhs = (CCodeExpression) local.initializer.ccodenode;
}
- var cfrag = new CCodeFragment ();
-
- if (pre_statement_fragment != null) {
- cfrag.append (pre_statement_fragment);
- pre_statement_fragment = null;
- }
-
if (local.captured) {
if (local.initializer != null) {
- cfrag.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id ((Block) local.parent_symbol))), get_variable_cname (local.name)), rhs)));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id ((Block) local.parent_symbol))), get_variable_cname (local.name)), rhs));
}
} else {
var cvar = new CCodeVariableDeclarator (get_variable_cname (local.name), rhs, local.variable_type.get_cdeclarator_suffix ());
var cdecl = new CCodeDeclaration (local.variable_type.get_cname ());
cdecl.add_declarator (cvar);
- cfrag.append (cdecl);
+ ccode.add_statement (cdecl);
// try to initialize uninitialized variables
// initialization not necessary for variables stored in closure
@@ -984,11 +885,9 @@ public class Vala.DovaBaseModule : CodeGenerator {
}
if (local.initializer != null && local.initializer.tree_can_fail) {
- add_simple_check (local.initializer, cfrag);
+ add_simple_check (local.initializer);
}
- local.ccodenode = cfrag;
-
local.active = true;
}
@@ -1209,24 +1108,6 @@ public class Vala.DovaBaseModule : CodeGenerator {
* expression
*/
- /* can't automatically deep copy lists yet, so do it
- * manually for now
- * replace with
- * expr.temp_vars = temp_vars;
- * when deep list copying works
- */
- if (temp_vars.size > 0) {
- if (expr.temp_vars == null) {
- expr.temp_vars = new ArrayList<LocalVariable> ();
- } else {
- expr.temp_vars.clear ();
- }
- foreach (LocalVariable local in temp_vars) {
- expr.temp_vars.add (local);
- }
- temp_vars.clear ();
- }
-
if (((List<LocalVariable>) temp_ref_vars).size == 0) {
/* nothing to do without temporary variables */
return;
@@ -1238,7 +1119,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
}
var full_expr_var = get_temp_variable (expr_type, true, expr);
- expr.add_temp_var (full_expr_var);
+ emit_temp_var (full_expr_var);
var expr_list = new CCodeCommaExpression ();
expr_list.append_expression (new CCodeAssignment (get_variable_cexpression (full_expr_var.name), (CCodeExpression) expr.ccodenode));
@@ -1256,58 +1137,53 @@ public class Vala.DovaBaseModule : CodeGenerator {
temp_ref_vars.clear ();
}
- public void append_temp_decl (CCodeFragment cfrag, List<LocalVariable>? temp_vars) {
- if (temp_vars == null) {
- return;
- }
- foreach (LocalVariable local in temp_vars) {
- var cdecl = new CCodeDeclaration (local.variable_type.get_cname ());
+ public void emit_temp_var (LocalVariable local) {
+ var cdecl = new CCodeDeclaration (local.variable_type.get_cname ());
- var vardecl = new CCodeVariableDeclarator (local.name, null, local.variable_type.get_cdeclarator_suffix ());
- // sets #line
- local.ccodenode = vardecl;
- cdecl.add_declarator (vardecl);
+ var vardecl = new CCodeVariableDeclarator (local.name, null, local.variable_type.get_cdeclarator_suffix ());
+ // sets #line
+ local.ccodenode = vardecl;
+ cdecl.add_declarator (vardecl);
- var st = local.variable_type.data_type as Struct;
- var array_type = local.variable_type as ArrayType;
+ var st = local.variable_type.data_type as Struct;
+ var array_type = local.variable_type as ArrayType;
- if (local.name.has_prefix ("*")) {
- // do not dereference unintialized variable
- // initialization is not needed for these special
- // pointer temp variables
- // used to avoid side-effects in assignments
- } else if (local.variable_type is GenericType) {
- var value_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_get_value_size"));
- value_size.add_argument (get_type_id_expression (local.variable_type));
-
- var alloca_call = new CCodeFunctionCall (new CCodeIdentifier ("alloca"));
- alloca_call.add_argument (value_size);
+ if (local.name.has_prefix ("*")) {
+ // do not dereference unintialized variable
+ // initialization is not needed for these special
+ // pointer temp variables
+ // used to avoid side-effects in assignments
+ } else if (local.variable_type is GenericType) {
+ var value_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_get_value_size"));
+ value_size.add_argument (get_type_id_expression (local.variable_type));
- var memset_call = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
- memset_call.add_argument (alloca_call);
- memset_call.add_argument (new CCodeConstant ("0"));
- memset_call.add_argument (value_size);
+ var alloca_call = new CCodeFunctionCall (new CCodeIdentifier ("alloca"));
+ alloca_call.add_argument (value_size);
- vardecl.initializer = memset_call;
- vardecl.init0 = true;
- } else if (!local.variable_type.nullable &&
- (st != null && st.get_fields ().size > 0) ||
- (array_type != null && array_type.fixed_length)) {
- // 0-initialize struct with struct initializer { 0 }
- // necessary as they will be passed by reference
- var clist = new CCodeInitializerList ();
- clist.append (new CCodeConstant ("0"));
+ var memset_call = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
+ memset_call.add_argument (alloca_call);
+ memset_call.add_argument (new CCodeConstant ("0"));
+ memset_call.add_argument (value_size);
- vardecl.initializer = clist;
- vardecl.init0 = true;
- } else if (local.variable_type.is_reference_type_or_type_parameter () ||
- local.variable_type.nullable) {
- vardecl.initializer = new CCodeConstant ("NULL");
- vardecl.init0 = true;
- }
+ vardecl.initializer = memset_call;
+ vardecl.init0 = true;
+ } else if (!local.variable_type.nullable &&
+ (st != null && st.get_fields ().size > 0) ||
+ (array_type != null && array_type.fixed_length)) {
+ // 0-initialize struct with struct initializer { 0 }
+ // necessary as they will be passed by reference
+ var clist = new CCodeInitializerList ();
+ clist.append (new CCodeConstant ("0"));
- cfrag.append (cdecl);
+ vardecl.initializer = clist;
+ vardecl.init0 = true;
+ } else if (local.variable_type.is_reference_type_or_type_parameter () ||
+ local.variable_type.nullable) {
+ vardecl.initializer = new CCodeConstant ("NULL");
+ vardecl.init0 = true;
}
+
+ ccode.add_statement (cdecl);
}
public override void visit_expression_statement (ExpressionStatement stmt) {
@@ -1316,67 +1192,25 @@ public class Vala.DovaBaseModule : CodeGenerator {
return;
}
- stmt.ccodenode = new CCodeExpressionStatement ((CCodeExpression) stmt.expression.ccodenode);
-
- if (stmt.tree_can_fail && stmt.expression.tree_can_fail) {
- // simple case, no node breakdown necessary
-
- var cfrag = new CCodeFragment ();
-
- cfrag.append (stmt.ccodenode);
-
- add_simple_check (stmt.expression, cfrag);
-
- stmt.ccodenode = cfrag;
- }
-
- /* free temporary objects */
-
- if (((List<LocalVariable>) temp_vars).size == 0
- && pre_statement_fragment == null) {
- /* nothing to do without temporary variables */
- return;
- }
-
- var cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
-
- if (pre_statement_fragment != null) {
- cfrag.append (pre_statement_fragment);
- pre_statement_fragment = null;
- }
-
- cfrag.append (stmt.ccodenode);
+ ccode.add_expression ((CCodeExpression) stmt.expression.ccodenode);
+ /* free temporary objects and handle errors */
foreach (LocalVariable local in temp_ref_vars) {
var ma = new MemberAccess.simple (local.name);
ma.symbol_reference = local;
- cfrag.append (new CCodeExpressionStatement (get_unref_expression (new CCodeIdentifier (local.name), local.variable_type, ma)));
+ ma.value_type = local.variable_type.copy ();
+ ccode.add_expression (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma));
}
- stmt.ccodenode = cfrag;
-
- temp_vars.clear ();
- temp_ref_vars.clear ();
- }
-
- public void create_temp_decl (Statement stmt, List<LocalVariable>? temp_vars) {
- /* declare temporary variables */
-
- if (temp_vars == null || temp_vars.size == 0) {
- /* nothing to do without temporary variables */
- return;
+ if (stmt.tree_can_fail && stmt.expression.tree_can_fail) {
+ // simple case, no node breakdown necessary
+ add_simple_check (stmt.expression);
}
- var cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
-
- cfrag.append (stmt.ccodenode);
-
- stmt.ccodenode = cfrag;
+ temp_ref_vars.clear ();
}
- public virtual void append_local_free (Symbol sym, CCodeFragment cfrag, bool stop_at_loop = false) {
+ public virtual void append_local_free (Symbol sym, bool stop_at_loop = false) {
var b = (Block) sym;
var local_vars = b.get_local_variables ();
@@ -1386,7 +1220,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
if (local.active && !local.floating && !local.captured && requires_destroy (local.variable_type)) {
var ma = new MemberAccess.simple (local.name);
ma.symbol_reference = local;
- cfrag.append (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma)));
+ ccode.add_expression (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma));
}
}
@@ -1395,7 +1229,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
var data_unref = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_unref"));
data_unref.add_argument (get_variable_cexpression ("_data%d_".printf (block_id)));
- cfrag.append (new CCodeExpressionStatement (data_unref));
+ ccode.add_expression (data_unref);
}
if (stop_at_loop) {
@@ -1407,13 +1241,13 @@ public class Vala.DovaBaseModule : CodeGenerator {
}
if (sym.parent_symbol is Block) {
- append_local_free (sym.parent_symbol, cfrag, stop_at_loop);
+ append_local_free (sym.parent_symbol, stop_at_loop);
} else if (sym.parent_symbol is Method) {
- append_param_free ((Method) sym.parent_symbol, cfrag);
+ append_param_free ((Method) sym.parent_symbol);
}
}
- public void append_error_free (Symbol sym, CCodeFragment cfrag, TryStatement current_try) {
+ public void append_error_free (Symbol sym, TryStatement current_try) {
var b = (Block) sym;
var local_vars = b.get_local_variables ();
@@ -1423,7 +1257,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
if (local.active && !local.floating && !local.captured && requires_destroy (local.variable_type)) {
var ma = new MemberAccess.simple (local.name);
ma.symbol_reference = local;
- cfrag.append (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma)));
+ ccode.add_expression (get_unref_expression (get_variable_cexpression (local.name), local.variable_type, ma));
}
}
@@ -1432,7 +1266,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
var data_unref = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_unref"));
data_unref.add_argument (get_variable_cexpression ("_data%d_".printf (block_id)));
- cfrag.append (new CCodeExpressionStatement (data_unref));
+ ccode.add_expression (data_unref);
}
if (sym == current_try.body) {
@@ -1440,40 +1274,27 @@ public class Vala.DovaBaseModule : CodeGenerator {
}
if (sym.parent_symbol is Block) {
- append_error_free (sym.parent_symbol, cfrag, current_try);
+ append_error_free (sym.parent_symbol, current_try);
} else if (sym.parent_symbol is Method) {
- append_param_free ((Method) sym.parent_symbol, cfrag);
+ append_param_free ((Method) sym.parent_symbol);
}
}
- private void append_param_free (Method m, CCodeFragment cfrag) {
+ private void append_param_free (Method m) {
foreach (FormalParameter param in m.get_parameters ()) {
if (requires_destroy (param.variable_type) && param.direction == ParameterDirection.IN) {
var ma = new MemberAccess.simple (param.name);
ma.symbol_reference = param;
- cfrag.append (new CCodeExpressionStatement (get_unref_expression (get_variable_cexpression (param.name), param.variable_type, ma)));
+ ccode.add_expression (get_unref_expression (get_variable_cexpression (param.name), param.variable_type, ma));
}
}
}
- public void create_local_free (CodeNode stmt, bool stop_at_loop = false) {
- var cfrag = new CCodeFragment ();
-
- append_local_free (current_symbol, cfrag, stop_at_loop);
-
- cfrag.append (stmt.ccodenode);
- stmt.ccodenode = cfrag;
- }
-
public override void visit_return_statement (ReturnStatement stmt) {
- var cfrag = new CCodeFragment ();
-
// free local variables
- append_local_free (current_symbol, cfrag);
-
- cfrag.append (new CCodeReturnStatement ((current_return_type is VoidType) ? null : new CCodeIdentifier ("result")));
+ append_local_free (current_symbol);
- stmt.ccodenode = cfrag;
+ ccode.add_return ((current_return_type is VoidType) ? null : new CCodeIdentifier ("result"));
}
public override void visit_delete_statement (DeleteStatement stmt) {
@@ -1485,7 +1306,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
var ccall = new CCodeFunctionCall (get_destroy_func_expression (type));
ccall.add_argument ((CCodeExpression) stmt.expression.ccodenode);
- stmt.ccodenode = new CCodeExpressionStatement (ccall);
+ ccode.add_expression (ccall);
}
public override void visit_expression (Expression expr) {
@@ -1555,7 +1376,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
// assign current value to temp variable
var temp_decl = get_temp_variable (prop.property_type, true, expr);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_decl.name), (CCodeExpression) expr.inner.ccodenode));
// increment/decrement property
@@ -1647,7 +1468,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
// (copy (&temp, 0, &expr, 0), temp)
var decl = get_temp_variable (expression_type, false, node);
- temp_vars.add (decl);
+ emit_temp_var (decl);
var ctemp = get_variable_cexpression (decl.name);
@@ -1691,7 +1512,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
return ccall;
} else {
var decl = get_temp_variable (expression_type, false, node);
- temp_vars.add (decl);
+ emit_temp_var (decl);
var ctemp = get_variable_cexpression (decl.name);
@@ -1752,7 +1573,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
if (struct_by_ref || expr.get_object_initializer ().size > 0) {
// value-type initialization or object creation expression with object initializer
var temp_decl = get_temp_variable (expr.type_reference, false, expr);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
instance = get_variable_cexpression (get_variable_cname (temp_decl.name));
}
@@ -1914,7 +1735,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (arg.target_type);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), cexpr));
ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (temp_var.name)));
@@ -1970,7 +1791,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
if (expr.type_reference.data_type != null && expr.type_reference.data_type.get_full_name () == "Dova.Value") {
// box value
var temp_decl = get_temp_variable (expr.inner.value_type, true, expr);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
var cvar = get_variable_cexpression (temp_decl.name);
var ccomma = new CCodeCommaExpression ();
@@ -1987,7 +1808,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
} else if (expr.inner.value_type.data_type != null && expr.inner.value_type.data_type.get_full_name () == "Dova.Value") {
// unbox value
var temp_decl = get_temp_variable (expr.type_reference, true, expr);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
var cvar = get_variable_cexpression (temp_decl.name);
var ccomma = new CCodeCommaExpression ();
@@ -2030,7 +1851,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
/* (tmp = var, var = null, tmp) */
var ccomma = new CCodeCommaExpression ();
var temp_decl = get_temp_variable (expr.value_type, true, expr);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
var cvar = get_variable_cexpression (temp_decl.name);
ccomma.append_expression (new CCodeAssignment (cvar, (CCodeExpression) expr.inner.ccodenode));
@@ -2178,7 +1999,7 @@ public class Vala.DovaBaseModule : CodeGenerator {
// 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.add (decl);
+ emit_temp_var (decl);
temp_ref_vars.insert (0, decl);
cexpr = new CCodeAssignment (get_variable_cexpression (decl.name), cexpr);
}
@@ -2442,6 +2263,6 @@ public class Vala.DovaBaseModule : CodeGenerator {
return false;
}
- public virtual void add_simple_check (CodeNode node, CCodeFragment cfrag, bool always_fails = false) {
+ public virtual void add_simple_check (CodeNode node, bool always_fails = false) {
}
}
diff --git a/codegen/valadovacontrolflowmodule.vala b/codegen/valadovacontrolflowmodule.vala
index 0fddf3f..93894ed 100644
--- a/codegen/valadovacontrolflowmodule.vala
+++ b/codegen/valadovacontrolflowmodule.vala
@@ -22,51 +22,29 @@
public class Vala.DovaControlFlowModule : DovaMethodModule {
public override void visit_if_statement (IfStatement stmt) {
+ ccode.open_if ((CCodeExpression) stmt.condition.ccodenode);
+
stmt.true_statement.emit (this);
- if (stmt.false_statement != null) {
- stmt.false_statement.emit (this);
- }
if (stmt.false_statement != null) {
- stmt.ccodenode = new CCodeIfStatement ((CCodeExpression) stmt.condition.ccodenode, (CCodeStatement) stmt.true_statement.ccodenode, (CCodeStatement) stmt.false_statement.ccodenode);
- } else {
- stmt.ccodenode = new CCodeIfStatement ((CCodeExpression) stmt.condition.ccodenode, (CCodeStatement) stmt.true_statement.ccodenode);
+ ccode.add_else ();
+ stmt.false_statement.emit (this);
}
- create_temp_decl (stmt, stmt.condition.temp_vars);
+ ccode.close ();
}
public override void visit_switch_statement (SwitchStatement stmt) {
- foreach (SwitchSection section in stmt.get_sections ()) {
- section.emit (this);
- }
-
- var cswitch = new CCodeSwitchStatement ((CCodeExpression) stmt.expression.ccodenode);
- stmt.ccodenode = cswitch;
+ ccode.open_switch ((CCodeExpression) stmt.expression.ccodenode);
foreach (SwitchSection section in stmt.get_sections ()) {
if (section.has_default_label ()) {
- cswitch.add_statement (new CCodeLabel ("default"));
- var cdefaultblock = new CCodeBlock ();
- cswitch.add_statement (cdefaultblock);
- foreach (CodeNode default_stmt in section.get_statements ()) {
- cdefaultblock.add_statement (default_stmt.ccodenode);
- }
- continue;
- }
-
- foreach (SwitchLabel label in section.get_labels ()) {
- cswitch.add_statement (new CCodeCaseStatement ((CCodeExpression) label.expression.ccodenode));
- }
-
- var cblock = new CCodeBlock ();
- cswitch.add_statement (cblock);
- foreach (CodeNode body_stmt in section.get_statements ()) {
- cblock.add_statement (body_stmt.ccodenode);
+ ccode.add_default ();
}
+ section.emit (this);
}
- create_temp_decl (stmt, stmt.expression.temp_vars);
+ ccode.close ();
}
public override void visit_switch_label (SwitchLabel label) {
@@ -74,25 +52,29 @@ public class Vala.DovaControlFlowModule : DovaMethodModule {
label.expression.emit (this);
visit_end_full_expression (label.expression);
+
+ ccode.add_case ((CCodeExpression) label.expression.ccodenode);
}
}
public override void visit_loop (Loop stmt) {
+ ccode.open_while (new CCodeConstant ("true"));
+
stmt.body.emit (this);
- stmt.ccodenode = new CCodeWhileStatement (new CCodeConstant ("true"), (CCodeStatement) stmt.body.ccodenode);
+ ccode.close ();
}
public override void visit_break_statement (BreakStatement stmt) {
- stmt.ccodenode = new CCodeBreakStatement ();
+ append_local_free (current_symbol, true);
- create_local_free (stmt, true);
+ ccode.add_break ();
}
public override void visit_continue_statement (ContinueStatement stmt) {
- stmt.ccodenode = new CCodeContinueStatement ();
+ append_local_free (current_symbol, true);
- create_local_free (stmt, true);
+ ccode.add_continue ();
}
}
diff --git a/codegen/valadovaerrormodule.vala b/codegen/valadovaerrormodule.vala
index f38bafd..be2fcaf 100644
--- a/codegen/valadovaerrormodule.vala
+++ b/codegen/valadovaerrormodule.vala
@@ -27,67 +27,44 @@ public class Vala.DovaErrorModule : DovaDelegateModule {
private bool is_in_catch = false;
public override void visit_throw_statement (ThrowStatement stmt) {
- var cfrag = new CCodeFragment ();
+ ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("dova_error"), (CCodeExpression) stmt.error_expression.ccodenode));
- // method will fail
- var cassign = new CCodeAssignment (new CCodeIdentifier ("dova_error"), (CCodeExpression) stmt.error_expression.ccodenode);
- cfrag.append (new CCodeExpressionStatement (cassign));
-
- add_simple_check (stmt, cfrag, true);
-
- stmt.ccodenode = cfrag;
-
- create_temp_decl (stmt, stmt.error_expression.temp_vars);
+ add_simple_check (stmt, true);
}
- public virtual CCodeStatement return_with_exception () {
- var cerror_block = new CCodeBlock ();
-
+ public void return_with_exception () {
// propagate error
// nothing to do
// free local variables
- var free_frag = new CCodeFragment ();
- append_local_free (current_symbol, free_frag, false);
- cerror_block.add_statement (free_frag);
+ append_local_free (current_symbol, false);
if (current_method is CreationMethod && current_method.parent_symbol is Class) {
var cl = current_method.parent_symbol as Class;
var unref_call = new CCodeFunctionCall (new CCodeIdentifier (cl.get_unref_function ()));
unref_call.add_argument (new CCodeIdentifier ("this"));
- cerror_block.add_statement (new CCodeExpressionStatement (unref_call));
- cerror_block.add_statement (new CCodeReturnStatement ());
+ ccode.add_expression (unref_call);
+ ccode.add_return ();
} else if (current_return_type is VoidType) {
- cerror_block.add_statement (new CCodeReturnStatement ());
+ ccode.add_return ();
} else {
- cerror_block.add_statement (new CCodeReturnStatement (default_value_for_type (current_return_type, false)));
+ ccode.add_return (default_value_for_type (current_return_type, false));
}
-
- return cerror_block;
}
- CCodeStatement uncaught_error_statement (CCodeBlock? block = null, bool unexpected = false) {
- var cerror_block = block;
- if (cerror_block == null) {
- cerror_block = new CCodeBlock ();
- }
-
+ void uncaught_error_statement () {
// free local variables
- var free_frag = new CCodeFragment ();
- append_local_free (current_symbol, free_frag, false);
- cerror_block.add_statement (free_frag);
+ append_local_free (current_symbol, false);
// TODO log uncaught error as critical warning
if (current_method is CreationMethod) {
- cerror_block.add_statement (new CCodeReturnStatement ());
+ ccode.add_return ();
} else if (current_return_type is VoidType) {
- cerror_block.add_statement (new CCodeReturnStatement ());
+ ccode.add_return ();
} else if (current_return_type != null) {
- cerror_block.add_statement (new CCodeReturnStatement (default_value_for_type (current_return_type, false)));
+ ccode.add_return (default_value_for_type (current_return_type, false));
}
-
- return cerror_block;
}
bool in_finally_block (CodeNode node) {
@@ -102,17 +79,20 @@ public class Vala.DovaErrorModule : DovaDelegateModule {
return false;
}
- public override void add_simple_check (CodeNode node, CCodeFragment cfrag, bool always_fails = false) {
- CCodeStatement cerror_handler = null;
+ public override void add_simple_check (CodeNode node, bool always_fails = false) {
+ if (always_fails) {
+ // inner_error is always set, avoid unnecessary if statement
+ // eliminates C warnings
+ } else {
+ var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier ("dova_error"), new CCodeConstant ("NULL"));
+ ccode.open_if (ccond);
+ }
if (current_try != null) {
// surrounding try found
- var cerror_block = new CCodeBlock ();
// free local variables
- var free_frag = new CCodeFragment ();
- append_error_free (current_symbol, free_frag, current_try);
- cerror_block.add_statement (free_frag);
+ append_error_free (current_symbol, current_try);
var error_types = new ArrayList<DataType> ();
foreach (DataType node_error_type in node.get_error_types ()) {
@@ -135,24 +115,23 @@ public class Vala.DovaErrorModule : DovaDelegateModule {
}
handled_error_types.clear ();
- // go to catch clause if error domain matches
- var cgoto_stmt = new CCodeGotoStatement (clause.clabel_name);
-
if (clause.error_type.equals (new ObjectType (error_class))) {
// general catch clause, this should be the last one
has_general_catch_clause = true;
- cerror_block.add_statement (cgoto_stmt);
+ ccode.add_goto (clause.clabel_name);
break;
} else {
var catch_type = clause.error_type as ObjectType;
- var cgoto_block = new CCodeBlock ();
- cgoto_block.add_statement (cgoto_stmt);
var type_check = new CCodeFunctionCall (new CCodeIdentifier ("any_is_a"));
type_check.add_argument (new CCodeIdentifier ("dova_error"));
type_check.add_argument (new CCodeFunctionCall (new CCodeIdentifier ("%s_type_get".printf (catch_type.type_symbol.get_lower_case_cname ()))));
- cerror_block.add_statement (new CCodeIfStatement (type_check, cgoto_block));
+ ccode.open_if (type_check);
+
+ // go to catch clause if error domain matches
+ ccode.add_goto (clause.clabel_name);
+ ccode.close ();
}
}
}
@@ -164,16 +143,13 @@ public class Vala.DovaErrorModule : DovaDelegateModule {
} else if (error_types.size > 0) {
// go to finally clause if no catch clause matches
// and there are still unhandled error types
- cerror_block.add_statement (new CCodeGotoStatement ("__finally%d".printf (current_try_id)));
+ ccode.add_goto ("__finally%d".printf (current_try_id));
} else if (in_finally_block (node)) {
// do not check unexpected errors happening within finally blocks
// as jump out of finally block is not supported
} else {
- // should never happen with correct bindings
- uncaught_error_statement (cerror_block, true);
+ assert_not_reached ();
}
-
- cerror_handler = cerror_block;
} else if (current_method != null && current_method.get_error_types ().size > 0) {
// current method can fail, propagate error
CCodeExpression ccond = null;
@@ -197,25 +173,20 @@ public class Vala.DovaErrorModule : DovaDelegateModule {
}
if (ccond == null) {
- cerror_handler = return_with_exception ();
+ return_with_exception ();
} else {
- var cerror_block = new CCodeBlock ();
- cerror_block.add_statement (new CCodeIfStatement (ccond,
- return_with_exception (),
- uncaught_error_statement ()));
- cerror_handler = cerror_block;
+ ccode.open_if (ccond);
+ return_with_exception ();
+ ccode.add_else ();
+ uncaught_error_statement ();
+ ccode.close ();
}
} else {
- cerror_handler = uncaught_error_statement ();
+ uncaught_error_statement ();
}
- if (always_fails) {
- // inner_error is always set, avoid unnecessary if statement
- // eliminates C warnings
- cfrag.append (cerror_handler);
- } else {
- var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier ("dova_error"), new CCodeConstant ("NULL"));
- cfrag.append (new CCodeIfStatement (ccond, cerror_handler));
+ if (!always_fails) {
+ ccode.close ();
}
}
@@ -233,15 +204,12 @@ public class Vala.DovaErrorModule : DovaDelegateModule {
clause.clabel_name = "__catch%d_%s".printf (this_try_id, clause.error_type.get_lower_case_cname ());
}
- if (stmt.finally_body != null) {
- stmt.finally_body.emit (this);
- }
-
is_in_catch = false;
stmt.body.emit (this);
is_in_catch = true;
foreach (CatchClause clause in stmt.get_catch_clauses ()) {
+ ccode.add_goto ("__finally%d".printf (this_try_id));
clause.emit (this);
}
@@ -249,35 +217,22 @@ public class Vala.DovaErrorModule : DovaDelegateModule {
current_try_id = old_try_id;
is_in_catch = old_is_in_catch;
- var cfrag = new CCodeFragment ();
- cfrag.append (stmt.body.ccodenode);
-
- foreach (CatchClause clause in stmt.get_catch_clauses ()) {
- cfrag.append (new CCodeGotoStatement ("__finally%d".printf (this_try_id)));
- cfrag.append (clause.ccodenode);
- }
-
- cfrag.append (new CCodeLabel ("__finally%d".printf (this_try_id)));
+ ccode.add_label ("__finally%d".printf (this_try_id));
if (stmt.finally_body != null) {
- cfrag.append (stmt.finally_body.ccodenode);
+ stmt.finally_body.emit (this);
}
// check for errors not handled by this try statement
// may be handled by outer try statements or propagated
- add_simple_check (stmt, cfrag, !stmt.after_try_block_reachable);
-
- stmt.ccodenode = cfrag;
+ add_simple_check (stmt, !stmt.after_try_block_reachable);
}
public override void visit_catch_clause (CatchClause clause) {
generate_type_declaration (clause.error_type, cfile);
- clause.body.emit (this);
-
- var cfrag = new CCodeFragment ();
- cfrag.append (new CCodeLabel (clause.clabel_name));
+ ccode.add_label (clause.clabel_name);
- var cblock = new CCodeBlock ();
+ ccode.open_block ();
string variable_name;
if (clause.variable_name != null) {
@@ -289,23 +244,21 @@ public class Vala.DovaErrorModule : DovaDelegateModule {
if (clause.variable_name != null) {
var cdecl = new CCodeDeclaration (clause.error_type.get_cname ());
cdecl.add_declarator (new CCodeVariableDeclarator (variable_name, new CCodeIdentifier ("dova_error")));
- cblock.add_statement (cdecl);
+ ccode.add_statement (cdecl);
} else {
// error object is not used within catch statement, clear it
var cclear = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_unref"));
cclear.add_argument (new CCodeIdentifier ("dova_error"));
- cblock.add_statement (new CCodeExpressionStatement (cclear));
+ ccode.add_statement (new CCodeExpressionStatement (cclear));
}
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("dova_error"), new CCodeConstant ("NULL"))));
+ ccode.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("dova_error"), new CCodeConstant ("NULL"))));
- cblock.add_statement (clause.body.ccodenode);
-
- cfrag.append (cblock);
+ clause.body.emit (this);
- clause.ccodenode = cfrag;
+ ccode.close ();
}
- public override void append_local_free (Symbol sym, CCodeFragment cfrag, bool stop_at_loop = false) {
+ public override void append_local_free (Symbol sym, bool stop_at_loop = false) {
var finally_block = (Block) null;
if (sym.parent_node is TryStatement) {
finally_block = (sym.parent_node as TryStatement).finally_body;
@@ -314,10 +267,10 @@ public class Vala.DovaErrorModule : DovaDelegateModule {
}
if (finally_block != null) {
- cfrag.append (finally_block.ccodenode);
+ finally_block.emit (this);
}
- base.append_local_free (sym, cfrag, stop_at_loop);
+ base.append_local_free (sym, stop_at_loop);
}
}
diff --git a/codegen/valadovamemberaccessmodule.vala b/codegen/valadovamemberaccessmodule.vala
index 3e7b102..3e87b05 100644
--- a/codegen/valadovamemberaccessmodule.vala
+++ b/codegen/valadovamemberaccessmodule.vala
@@ -71,7 +71,7 @@ public class Vala.DovaMemberAccessModule : DovaControlFlowModule {
// instance expression has side-effects
// store in temp. variable
var temp_var = get_temp_variable (expr.inner.value_type);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
var ctemp = new CCodeIdentifier (temp_var.name);
inst = new CCodeAssignment (ctemp, pub_inst);
expr.inner.ccodenode = ctemp;
diff --git a/codegen/valadovamethodcallmodule.vala b/codegen/valadovamethodcallmodule.vala
index 7a245b0..958aa26 100644
--- a/codegen/valadovamethodcallmodule.vala
+++ b/codegen/valadovamethodcallmodule.vala
@@ -81,7 +81,7 @@ public class Vala.DovaMethodCallModule : DovaAssignmentModule {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (ma.inner.target_type);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), instance));
ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (temp_var.name)));
@@ -135,7 +135,7 @@ public class Vala.DovaMethodCallModule : DovaAssignmentModule {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (param.variable_type, param.variable_type.value_owned);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
cexpr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (temp_var.name));
if (param.direction == ParameterDirection.REF) {
@@ -151,14 +151,14 @@ public class Vala.DovaMethodCallModule : DovaAssignmentModule {
ccomma.append_expression (ccall_expr);
} else {
ret_temp_var = get_temp_variable (itype.get_return_type ());
- temp_vars.add (ret_temp_var);
+ emit_temp_var (ret_temp_var);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (ret_temp_var.name), ccall_expr));
}
var cassign_comma = new CCodeCommaExpression ();
var assign_temp_var = get_temp_variable (unary.inner.value_type, unary.inner.value_type.value_owned);
- temp_vars.add (assign_temp_var);
+ emit_temp_var (assign_temp_var);
cassign_comma.append_expression (new CCodeAssignment (get_variable_cexpression (assign_temp_var.name), transform_expression (get_variable_cexpression (temp_var.name), param.variable_type, unary.inner.value_type, arg)));
@@ -203,7 +203,7 @@ public class Vala.DovaMethodCallModule : DovaAssignmentModule {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (expr.value_type);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
if (expr.value_type is GenericType) {
ccall.add_argument (get_variable_cexpression (temp_var.name));
} else {
diff --git a/codegen/valadovaobjectmodule.vala b/codegen/valadovaobjectmodule.vala
index fca759d..4d65c26 100644
--- a/codegen/valadovaobjectmodule.vala
+++ b/codegen/valadovaobjectmodule.vala
@@ -758,16 +758,42 @@ public class Vala.DovaObjectModule : DovaArrayModule {
function.add_parameter (new CCodeFormalParameter ("this", cl.get_cname () + "*"));
- cfile.add_function_declaration (function);
-
+ push_function (function);
- var cblock = new CCodeBlock ();
+ cfile.add_function_declaration (function);
if (cl.destructor != null) {
- cblock.add_statement (cl.destructor.ccodenode);
+ cl.destructor.body.emit (this);
}
- cblock.add_statement (instance_finalize_fragment);
+ foreach (var f in cl.get_fields ()) {
+ if (f.binding == MemberBinding.INSTANCE) {
+ CCodeExpression lhs = null;
+ if (f.is_internal_symbol ()) {
+ var priv_call = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_PRIVATE".printf (cl.get_upper_case_cname (null))));
+ priv_call.add_argument (new CCodeIdentifier ("this"));
+ lhs = new CCodeMemberAccess.pointer (priv_call, f.get_cname ());
+ } else {
+ lhs = new CCodeMemberAccess.pointer (new CCodeIdentifier ("this"), f.get_cname ());
+ }
+
+ if (requires_destroy (f.variable_type)) {
+ var this_access = new MemberAccess.simple ("this");
+ this_access.value_type = get_data_type_for_symbol ((TypeSymbol) f.parent_symbol);
+
+ var field_st = f.parent_symbol as Struct;
+ if (field_st != null && !field_st.is_simple_type ()) {
+ this_access.ccodenode = new CCodeIdentifier ("(*this)");
+ } else {
+ this_access.ccodenode = new CCodeIdentifier ("this");
+ }
+
+ var ma = new MemberAccess (this_access, f.name);
+ ma.symbol_reference = f;
+ ccode.add_expression (get_unref_expression (lhs, f.variable_type, ma));
+ }
+ }
+ }
// chain up to finalize function of the base class
foreach (DataType base_type in cl.get_base_types ()) {
@@ -780,12 +806,11 @@ public class Vala.DovaObjectModule : DovaArrayModule {
}
ccall.add_argument (type_get_call);
ccall.add_argument (new CCodeIdentifier ("this"));
- cblock.add_statement (new CCodeExpressionStatement (ccall));
+ ccode.add_statement (new CCodeExpressionStatement (ccall));
}
}
-
- function.block = cblock;
+ pop_function ();
cfile.add_function (function);
}
@@ -793,9 +818,6 @@ public class Vala.DovaObjectModule : DovaArrayModule {
public override void visit_class (Class cl) {
push_context (new EmitContext (cl));
- var old_instance_finalize_fragment = instance_finalize_fragment;
- instance_finalize_fragment = new CCodeFragment ();
-
generate_class_declaration (cl, cfile);
generate_class_private_declaration (cl, cfile);
@@ -969,8 +991,6 @@ public class Vala.DovaObjectModule : DovaArrayModule {
cfile.add_function (create_set_value_from_any_function ());
}
- instance_finalize_fragment = old_instance_finalize_fragment;
-
pop_context ();
}
@@ -1148,14 +1168,6 @@ public class Vala.DovaObjectModule : DovaArrayModule {
var prop = (Property) acc.prop;
- if (acc.result_var != null) {
- acc.result_var.accept (this);
- }
-
- if (acc.body != null) {
- acc.body.emit (this);
- }
-
// do not declare overriding properties and interface implementations
if (prop.is_abstract || prop.is_virtual
|| (prop.base_property == null && prop.base_interface_property == null)) {
@@ -1256,7 +1268,13 @@ public class Vala.DovaObjectModule : DovaArrayModule {
function.modifiers |= CCodeModifiers.STATIC;
}
- function.block = (CCodeBlock) acc.body.ccodenode;
+ push_function (function);
+
+ if (acc.result_var != null) {
+ acc.result_var.accept (this);
+ }
+
+ acc.body.emit (this);
if (acc.readable) {
var cdecl = new CCodeDeclaration (acc.value_type.get_cname ());
@@ -1386,10 +1404,6 @@ public class Vala.DovaObjectModule : DovaArrayModule {
param.accept (this);
}
- if (m.result_var != null) {
- m.result_var.accept (this);
- }
-
foreach (Expression precondition in m.get_preconditions ()) {
precondition.emit (this);
}
@@ -1398,12 +1412,6 @@ public class Vala.DovaObjectModule : DovaArrayModule {
postcondition.emit (this);
}
- if (m.body != null) {
- m.body.emit (this);
- }
-
-
- pop_context ();
generate_method_declaration (m, cfile);
@@ -1412,7 +1420,6 @@ public class Vala.DovaObjectModule : DovaArrayModule {
}
var function = new CCodeFunction (m.get_real_cname ());
- m.ccodenode = function;
generate_cparameters (m, cfile, function);
@@ -1427,14 +1434,10 @@ public class Vala.DovaObjectModule : DovaArrayModule {
}
if (m.body != null) {
- function.block = (CCodeBlock) m.body.ccodenode;
- function.block.line = function.line;
-
- var cinit = new CCodeFragment ();
- function.block.prepend_statement (cinit);
+ push_function (function);
if (context.module_init_method == m) {
- cinit.append (module_init_fragment);
+ add_module_init ();
}
if (m.closure) {
@@ -1453,7 +1456,7 @@ public class Vala.DovaObjectModule : DovaArrayModule {
var cdecl = new CCodeDeclaration ("Block%dData*".printf (parent_block_id));
cdecl.add_declarator (new CCodeVariableDeclarator ("_data%d_".printf (parent_block_id), parent_data));
- cinit.append (cdecl);
+ ccode.add_statement (cdecl);
closure_block = parent_closure_block;
block_id = parent_block_id;
@@ -1466,7 +1469,7 @@ public class Vala.DovaObjectModule : DovaArrayModule {
var cdecl = new CCodeDeclaration ("%s *".printf (current_class.get_cname ()));
cdecl.add_declarator (new CCodeVariableDeclarator ("this", cself));
- cinit.append (cdecl);
+ ccode.add_statement (cdecl);
}
}
foreach (FormalParameter param in m.get_parameters ()) {
@@ -1484,26 +1487,32 @@ public class Vala.DovaObjectModule : DovaArrayModule {
var condition = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier (param.name), new CCodeConstant ("NULL"));
var if_statement = new CCodeIfStatement (condition, cblock);
- cinit.append (if_statement);
+ ccode.add_statement (if_statement);
}
}
}
+ if (m.result_var != null) {
+ m.result_var.accept (this);
+ }
+
+ m.body.emit (this);
+
if (!(m.return_type is VoidType) && !(m.return_type is GenericType)) {
var cdecl = new CCodeDeclaration (m.return_type.get_cname ());
cdecl.add_declarator (new CCodeVariableDeclarator.zero ("result", default_value_for_type (m.return_type, true)));
- cinit.append (cdecl);
+ ccode.add_statement (cdecl);
- function.block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
+ ccode.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
}
var st = m.parent_symbol as Struct;
if (m is CreationMethod && st != null && (st.is_boolean_type () || st.is_integer_type () || st.is_floating_type ())) {
var cdecl = new CCodeDeclaration (st.get_cname ());
cdecl.add_declarator (new CCodeVariableDeclarator ("this", new CCodeConstant ("0")));
- cinit.append (cdecl);
+ ccode.add_statement (cdecl);
- function.block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("this")));
+ ccode.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("this")));
}
cfile.add_function (function);
@@ -1639,6 +1648,8 @@ public class Vala.DovaObjectModule : DovaArrayModule {
cfile.add_function (override_func);
}
+ pop_context ();
+
if (m.entry_point) {
generate_type_declaration (new ObjectType (array_class), cfile);
@@ -1647,18 +1658,19 @@ public class Vala.DovaObjectModule : DovaArrayModule {
cmain.line = function.line;
cmain.add_parameter (new CCodeFormalParameter ("argc", "int"));
cmain.add_parameter (new CCodeFormalParameter ("argv", "char **"));
- var main_block = new CCodeBlock ();
+
+ push_function (cmain);
var dova_init_call = new CCodeFunctionCall (new CCodeIdentifier ("dova_init"));
dova_init_call.add_argument (new CCodeIdentifier ("argc"));
dova_init_call.add_argument (new CCodeIdentifier ("argv"));
- main_block.add_statement (new CCodeExpressionStatement (dova_init_call));
+ ccode.add_statement (new CCodeExpressionStatement (dova_init_call));
- main_block.add_statement (module_init_fragment);
+ add_module_init ();
var cdecl = new CCodeDeclaration ("int");
cdecl.add_declarator (new CCodeVariableDeclarator ("result", new CCodeConstant ("0")));
- main_block.add_statement (cdecl);
+ ccode.add_statement (cdecl);
var main_call = new CCodeFunctionCall (new CCodeIdentifier (function.name));
@@ -1671,18 +1683,18 @@ public class Vala.DovaObjectModule : DovaArrayModule {
cdecl = new CCodeDeclaration ("DovaArray*");
cdecl.add_declarator (new CCodeVariableDeclarator ("args", array_creation));
- main_block.add_statement (cdecl);
+ ccode.add_statement (cdecl);
var array_data = new CCodeFunctionCall (new CCodeIdentifier ("dova_array_get_data"));
array_data.add_argument (new CCodeIdentifier ("args"));
cdecl = new CCodeDeclaration ("string_t*");
cdecl.add_declarator (new CCodeVariableDeclarator ("args_data", array_data));
- main_block.add_statement (cdecl);
+ ccode.add_statement (cdecl);
cdecl = new CCodeDeclaration ("int");
cdecl.add_declarator (new CCodeVariableDeclarator ("argi"));
- main_block.add_statement (cdecl);
+ ccode.add_statement (cdecl);
var string_creation = new CCodeFunctionCall (new CCodeIdentifier ("string_create_from_cstring"));
string_creation.add_argument (new CCodeElementAccess (new CCodeIdentifier ("argv"), new CCodeIdentifier ("argi")));
@@ -1693,7 +1705,7 @@ public class Vala.DovaObjectModule : DovaArrayModule {
var for_stmt = new CCodeForStatement (new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier ("argi"), new CCodeIdentifier ("argc")), loop_block);
for_stmt.add_initializer (new CCodeAssignment (new CCodeIdentifier ("argi"), new CCodeConstant ("0")));
for_stmt.add_iterator (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier ("argi")));
- main_block.add_statement (for_stmt);
+ ccode.add_statement (for_stmt);
main_call.add_argument (new CCodeIdentifier ("args"));
}
@@ -1702,25 +1714,26 @@ public class Vala.DovaObjectModule : DovaArrayModule {
// method returns void, always use 0 as exit code
var main_stmt = new CCodeExpressionStatement (main_call);
main_stmt.line = cmain.line;
- main_block.add_statement (main_stmt);
+ ccode.add_statement (main_stmt);
} else {
var main_stmt = new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("result"), main_call));
main_stmt.line = cmain.line;
- main_block.add_statement (main_stmt);
+ ccode.add_statement (main_stmt);
}
if (m.get_parameters ().size == 1) {
// destroy Dova array
var unref = new CCodeFunctionCall (new CCodeIdentifier ("dova_object_unref"));
unref.add_argument (new CCodeIdentifier ("args"));
- main_block.add_statement (new CCodeExpressionStatement (unref));
+ ccode.add_statement (new CCodeExpressionStatement (unref));
}
var ret_stmt = new CCodeReturnStatement (new CCodeIdentifier ("result"));
ret_stmt.line = cmain.line;
- main_block.add_statement (ret_stmt);
+ ccode.add_statement (ret_stmt);
+
+ pop_function ();
- cmain.block = main_block;
cfile.add_function (cmain);
}
}
@@ -1955,4 +1968,15 @@ public class Vala.DovaObjectModule : DovaArrayModule {
base.visit_element_access (expr);
}
}
+
+ void add_module_init () {
+ foreach (var field in static_fields) {
+ field.initializer.emit (this);
+
+ var lhs = new CCodeIdentifier (field.get_cname ());
+ var rhs = (CCodeExpression) field.initializer.ccodenode;
+
+ ccode.add_expression (new CCodeAssignment (lhs, rhs));
+ }
+ }
}
diff --git a/codegen/valadovastructmodule.vala b/codegen/valadovastructmodule.vala
index b7a99cd..2c6cdf2 100644
--- a/codegen/valadovastructmodule.vala
+++ b/codegen/valadovastructmodule.vala
@@ -72,9 +72,6 @@ public class Vala.DovaStructModule : DovaBaseModule {
public override void visit_struct (Struct st) {
push_context (new EmitContext (st));
- var old_instance_finalize_fragment = instance_finalize_fragment;
- instance_finalize_fragment = new CCodeFragment ();
-
generate_struct_declaration (st, cfile);
if (!st.is_internal_symbol ()) {
@@ -83,8 +80,6 @@ public class Vala.DovaStructModule : DovaBaseModule {
st.accept_children (this);
- instance_finalize_fragment = old_instance_finalize_fragment;
-
pop_context ();
}
}
diff --git a/codegen/valadovavaluemodule.vala b/codegen/valadovavaluemodule.vala
index e876869..9436925 100644
--- a/codegen/valadovavaluemodule.vala
+++ b/codegen/valadovavaluemodule.vala
@@ -362,9 +362,6 @@ public class Vala.DovaValueModule : DovaObjectModule {
cblock.add_statement (new CCodeIfStatement (new CCodeIdentifier ("src"), copy_block));
- append_temp_decl (cfrag, temp_vars);
- temp_vars.clear ();
-
function.block = cblock;
cfile.add_function (function);
@@ -549,7 +546,7 @@ public class Vala.DovaValueModule : DovaObjectModule {
var temp_var = get_temp_variable (array_type, true, expr);
var name_cnode = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
int i = 0;
foreach (Expression e in expr.get_expressions ()) {
@@ -583,7 +580,7 @@ public class Vala.DovaValueModule : DovaObjectModule {
var temp_var = get_temp_variable (array_type, true, expr);
var name_cnode = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
int i = 0;
foreach (Expression e in expr.get_expressions ()) {
@@ -619,7 +616,7 @@ public class Vala.DovaValueModule : DovaObjectModule {
var key_temp_var = get_temp_variable (key_array_type, true, expr);
var key_name_cnode = get_variable_cexpression (key_temp_var.name);
- temp_vars.add (key_temp_var);
+ emit_temp_var (key_temp_var);
var value_array_type = new ArrayType (expr.map_value_type, 1, expr.source_reference);
value_array_type.inline_allocated = true;
@@ -629,7 +626,7 @@ public class Vala.DovaValueModule : DovaObjectModule {
var value_temp_var = get_temp_variable (value_array_type, true, expr);
var value_name_cnode = get_variable_cexpression (value_temp_var.name);
- temp_vars.add (value_temp_var);
+ emit_temp_var (value_temp_var);
for (int i = 0; i < length; i++) {
key_ce.append_expression (new CCodeAssignment (new CCodeElementAccess (key_name_cnode, new CCodeConstant (i.to_string ())), (CCodeExpression) expr.get_keys ().get (i).ccodenode));
@@ -658,7 +655,7 @@ public class Vala.DovaValueModule : DovaObjectModule {
var type_temp_var = get_temp_variable (type_array_type, true, tuple);
var type_name_cnode = get_variable_cexpression (type_temp_var.name);
- temp_vars.add (type_temp_var);
+ emit_temp_var (type_temp_var);
var array_type = new ArrayType (new PointerType (new VoidType ()), 1, tuple.source_reference);
array_type.inline_allocated = true;
@@ -667,7 +664,7 @@ public class Vala.DovaValueModule : DovaObjectModule {
var temp_var = get_temp_variable (array_type, true, tuple);
var name_cnode = get_variable_cexpression (temp_var.name);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
var type_ce = new CCodeCommaExpression ();
var ce = new CCodeCommaExpression ();
@@ -691,7 +688,7 @@ public class Vala.DovaValueModule : DovaObjectModule {
// tmp = expr, &tmp
var element_temp_var = get_temp_variable (element_type);
- temp_vars.add (element_temp_var);
+ emit_temp_var (element_temp_var);
ce.append_expression (new CCodeAssignment (get_variable_cexpression (element_temp_var.name), cexpr));
cexpr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (element_temp_var.name));
}
diff --git a/codegen/valagasyncmodule.vala b/codegen/valagasyncmodule.vala
index a62167d..02846d2 100644
--- a/codegen/valagasyncmodule.vala
+++ b/codegen/valagasyncmodule.vala
@@ -138,8 +138,27 @@ public class Vala.GAsyncModule : GSignalModule {
return freefunc;
}
- CCodeFunction generate_async_function (Method m) {
- var asyncblock = new CCodeBlock ();
+ void generate_async_function (Method m) {
+ push_context (new EmitContext ());
+
+ var dataname = Symbol.lower_case_to_camel_case (m.get_cname ()) + "Data";
+ var asyncfunc = new CCodeFunction (m.get_real_cname (), "void");
+ var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
+
+ cparam_map.set (get_param_pos (-1), new CCodeFormalParameter ("_callback_", "GAsyncReadyCallback"));
+ cparam_map.set (get_param_pos (-0.9), new CCodeFormalParameter ("_user_data_", "gpointer"));
+
+ generate_cparameters (m, cfile, cparam_map, asyncfunc, null, null, null, 1);
+
+ if (m.base_method != null || m.base_interface_method != null) {
+ // declare *_real_* function
+ asyncfunc.modifiers |= CCodeModifiers.STATIC;
+ cfile.add_function_declaration (asyncfunc);
+ } else if (m.is_private_symbol ()) {
+ asyncfunc.modifiers |= CCodeModifiers.STATIC;
+ }
+
+ push_function (asyncfunc);
// logic copied from valaccodemethodmodule
if (m.overrides || (m.base_interface_method != null && !m.is_abstract && !m.is_virtual)) {
@@ -156,24 +175,17 @@ public class Vala.GAsyncModule : GSignalModule {
var self_target_type = new ObjectType (type_symbol);
var cself = transform_expression (new CCodeIdentifier ("base"), base_expression_type, self_target_type);
- var cdecl = new CCodeDeclaration ("%s *".printf (type_symbol.get_cname ()));
- cdecl.add_declarator (new CCodeVariableDeclarator ("self", cself));
- asyncblock.add_statement (cdecl);
+ ccode.add_declaration ("%s *".printf (type_symbol.get_cname ()), new CCodeVariableDeclarator ("self"));
+ ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("self"), cself));
}
- var dataname = Symbol.lower_case_to_camel_case (m.get_cname ()) + "Data";
- var asyncfunc = new CCodeFunction (m.get_real_cname (), "void");
- var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
-
var dataalloc = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_new0"));
dataalloc.add_argument (new CCodeIdentifier (dataname));
var data_var = new CCodeIdentifier ("_data_");
- var datadecl = new CCodeDeclaration (dataname + "*");
- datadecl.add_declarator (new CCodeVariableDeclarator ("_data_"));
- asyncblock.add_statement (datadecl);
- asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (data_var, dataalloc)));
+ ccode.add_declaration (dataname + "*", new CCodeVariableDeclarator ("_data_"));
+ ccode.add_expression (new CCodeAssignment (data_var, dataalloc));
var create_result = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_new"));
@@ -201,13 +213,13 @@ public class Vala.GAsyncModule : GSignalModule {
create_result.add_argument (new CCodeIdentifier ("_user_data_"));
create_result.add_argument (new CCodeIdentifier (m.get_real_cname ()));
- asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, "_async_result"), create_result)));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, "_async_result"), create_result));
var set_op_res_call = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_set_op_res_gpointer"));
set_op_res_call.add_argument (new CCodeMemberAccess.pointer (data_var, "_async_result"));
set_op_res_call.add_argument (data_var);
set_op_res_call.add_argument (new CCodeIdentifier (m.get_real_cname () + "_data_free"));
- asyncblock.add_statement (new CCodeExpressionStatement (set_op_res_call));
+ ccode.add_expression (set_op_res_call);
if (m.binding == MemberBinding.INSTANCE) {
CCodeExpression self_expr = new CCodeIdentifier ("self");
@@ -219,7 +231,7 @@ public class Vala.GAsyncModule : GSignalModule {
self_expr = refcall;
}
- asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, "self"), self_expr)));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, "self"), self_expr));
}
foreach (FormalParameter param in m.get_parameters ()) {
@@ -228,7 +240,7 @@ public class Vala.GAsyncModule : GSignalModule {
param_type.value_owned = true;
// create copy if necessary as variables in async methods may need to be kept alive
- CCodeExpression cparam = get_variable_cexpression (param.name);
+ CCodeExpression cparam = new CCodeIdentifier (get_variable_cname (param.name));
if (param.variable_type.is_real_non_null_struct_type ()) {
cparam = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, cparam);
}
@@ -238,51 +250,33 @@ public class Vala.GAsyncModule : GSignalModule {
cparam = get_ref_cexpression (param.variable_type, cparam, ma, param);
}
- asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, get_variable_cname (param.name)), cparam)));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, get_variable_cname (param.name)), cparam));
if (param.variable_type is ArrayType) {
var array_type = (ArrayType) param.variable_type;
if (!param.no_array_length) {
for (int dim = 1; dim <= array_type.rank; dim++) {
- asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, get_array_length_cname (get_variable_cname (param.name), dim)), new CCodeIdentifier (get_array_length_cname (get_variable_cname (param.name), dim)))));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, get_array_length_cname (get_variable_cname (param.name), dim)), new CCodeIdentifier (get_array_length_cname (get_variable_cname (param.name), dim))));
}
}
} else if (param.variable_type is DelegateType) {
var deleg_type = (DelegateType) param.variable_type;
if (deleg_type.delegate_symbol.has_target) {
- asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, get_delegate_target_cname (get_variable_cname (param.name))), new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (param.name))))));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, get_delegate_target_cname (get_variable_cname (param.name))), new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (param.name)))));
if (deleg_type.value_owned) {
- asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, get_delegate_target_destroy_notify_cname (get_variable_cname (param.name))), new CCodeIdentifier (get_delegate_target_destroy_notify_cname (get_variable_cname (param.name))))));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, get_delegate_target_destroy_notify_cname (get_variable_cname (param.name))), new CCodeIdentifier (get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)))));
}
}
}
}
}
- var cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
- temp_vars.clear ();
- asyncblock.add_statement (cfrag);
-
var ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_real_cname () + "_co"));
ccall.add_argument (data_var);
- asyncblock.add_statement (new CCodeExpressionStatement (ccall));
-
- cparam_map.set (get_param_pos (-1), new CCodeFormalParameter ("_callback_", "GAsyncReadyCallback"));
- cparam_map.set (get_param_pos (-0.9), new CCodeFormalParameter ("_user_data_", "gpointer"));
-
- generate_cparameters (m, cfile, cparam_map, asyncfunc, null, null, null, 1);
-
- if (m.base_method != null || m.base_interface_method != null) {
- // declare *_real_* function
- asyncfunc.modifiers |= CCodeModifiers.STATIC;
- cfile.add_function_declaration (asyncfunc);
- } else if (m.is_private_symbol ()) {
- asyncfunc.modifiers |= CCodeModifiers.STATIC;
- }
+ ccode.add_expression (ccall);
- asyncfunc.block = asyncblock;
+ cfile.add_function (asyncfunc);
- return asyncfunc;
+ pop_context ();
}
void append_struct (CCodeStruct structure) {
@@ -293,12 +287,7 @@ public class Vala.GAsyncModule : GSignalModule {
}
void append_function (CCodeFunction function) {
- var block = function.block;
- function.block = null;
-
cfile.add_function_declaration (function);
-
- function.block = block;
cfile.add_function (function);
}
@@ -347,13 +336,14 @@ public class Vala.GAsyncModule : GSignalModule {
if (!m.is_abstract && m.body != null) {
var data = generate_data_struct (m);
+ closure_struct = data;
+
append_function (generate_free_function (m));
- cfile.add_function (generate_async_function (m));
- cfile.add_function (generate_finish_function (m));
+ generate_async_function (m);
+ generate_finish_function (m);
append_function (generate_ready_function (m));
// append the _co function
- closure_struct = data;
base.visit_method (m);
closure_struct = null;
@@ -387,27 +377,33 @@ public class Vala.GAsyncModule : GSignalModule {
}
- CCodeFunction generate_finish_function (Method m) {
+ void generate_finish_function (Method m) {
+ push_context (new EmitContext ());
+
string dataname = Symbol.lower_case_to_camel_case (m.get_cname ()) + "Data";
var finishfunc = new CCodeFunction (m.get_finish_real_cname ());
var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
- var finishblock = new CCodeBlock ();
+ cparam_map.set (get_param_pos (0.1), new CCodeFormalParameter ("_res_", "GAsyncResult*"));
+
+ generate_cparameters (m, cfile, cparam_map, finishfunc, null, null, null, 2);
+
+ if (m.is_private_symbol () || m.base_method != null || m.base_interface_method != null) {
+ finishfunc.modifiers |= CCodeModifiers.STATIC;
+ }
+
+ push_function (finishfunc);
var return_type = m.return_type;
if (!(return_type is VoidType) && !return_type.is_real_non_null_struct_type ()) {
- var cdecl = new CCodeDeclaration (m.return_type.get_cname ());
- cdecl.add_declarator (new CCodeVariableDeclarator ("result"));
- finishblock.add_statement (cdecl);
+ ccode.add_declaration (m.return_type.get_cname (), new CCodeVariableDeclarator ("result"));
}
var data_var = new CCodeIdentifier ("_data_");
- var datadecl = new CCodeDeclaration (dataname + "*");
- datadecl.add_declarator (new CCodeVariableDeclarator ("_data_"));
- finishblock.add_statement (datadecl);
+ ccode.add_declaration (dataname + "*", new CCodeVariableDeclarator ("_data_"));
var simple_async_result_cast = new CCodeFunctionCall (new CCodeIdentifier ("G_SIMPLE_ASYNC_RESULT"));
simple_async_result_cast.add_argument (new CCodeIdentifier ("_res_"));
@@ -417,24 +413,25 @@ public class Vala.GAsyncModule : GSignalModule {
var propagate_error = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_propagate_error"));
propagate_error.add_argument (simple_async_result_cast);
propagate_error.add_argument (new CCodeIdentifier ("error"));
- var errorblock = new CCodeBlock ();
+
+ ccode.open_if (propagate_error);
if (return_type is VoidType || return_type.is_real_non_null_struct_type ()) {
- errorblock.add_statement (new CCodeReturnStatement ());
+ ccode.add_return ();
} else {
- errorblock.add_statement (new CCodeReturnStatement (default_value_for_type (return_type, false)));
+ ccode.add_return (default_value_for_type (return_type, false));
}
- finishblock.add_statement (new CCodeIfStatement (propagate_error, errorblock));
+ ccode.close ();
}
var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_get_op_res_gpointer"));
ccall.add_argument (simple_async_result_cast);
- finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (data_var, ccall)));
+ ccode.add_expression (new CCodeAssignment (data_var, ccall));
foreach (FormalParameter param in m.get_parameters ()) {
if (param.direction != ParameterDirection.IN) {
- finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (param.name)), new CCodeMemberAccess.pointer (data_var, get_variable_cname (param.name)))));
+ ccode.add_expression (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (param.name)), new CCodeMemberAccess.pointer (data_var, get_variable_cname (param.name))));
if (!(param.variable_type is ValueType) || param.variable_type.nullable) {
- finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, get_variable_cname (param.name)), new CCodeConstant ("NULL"))));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, get_variable_cname (param.name)), new CCodeConstant ("NULL")));
}
}
}
@@ -445,41 +442,30 @@ public class Vala.GAsyncModule : GSignalModule {
if (requires_copy (return_type)) {
cexpr = get_ref_cexpression (return_type, cexpr, null, return_type);
}
- finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result")), cexpr)));
+ ccode.add_expression (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result")), cexpr));
} else if (!(return_type is VoidType)) {
- finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("result"), new CCodeMemberAccess.pointer (data_var, "result"))));
+ ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("result"), new CCodeMemberAccess.pointer (data_var, "result")));
if (return_type is ArrayType) {
var array_type = (ArrayType) return_type;
if (!m.no_array_length) {
for (int dim = 1; dim <= array_type.rank; dim++) {
- finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (get_array_length_cname ("result", dim))), new CCodeMemberAccess.pointer (data_var, get_array_length_cname ("result", dim)))));
+ ccode.add_expression (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (get_array_length_cname ("result", dim))), new CCodeMemberAccess.pointer (data_var, get_array_length_cname ("result", dim))));
}
}
} else if (return_type is DelegateType && ((DelegateType) return_type).delegate_symbol.has_target) {
- finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (get_delegate_target_cname ("result"))), new CCodeMemberAccess.pointer (data_var, get_delegate_target_cname ("result")))));
+ ccode.add_expression (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (get_delegate_target_cname ("result"))), new CCodeMemberAccess.pointer (data_var, get_delegate_target_cname ("result"))));
}
if (!(return_type is ValueType) || return_type.nullable) {
- finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, "result"), new CCodeConstant ("NULL"))));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, "result"), new CCodeConstant ("NULL")));
}
- finishblock.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
+ ccode.add_return (new CCodeIdentifier ("result"));
}
- var cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
- temp_vars.clear ();
- finishblock.add_statement (cfrag);
-
- cparam_map.set (get_param_pos (0.1), new CCodeFormalParameter ("_res_", "GAsyncResult*"));
+ pop_function ();
- generate_cparameters (m, cfile, cparam_map, finishfunc, null, null, null, 2);
+ cfile.add_function (finishfunc);
- if (m.is_private_symbol () || m.base_method != null || m.base_interface_method != null) {
- finishfunc.modifiers |= CCodeModifiers.STATIC;
- }
-
- finishfunc.block = finishblock;
-
- return finishfunc;
+ pop_context ();
}
CCodeFunction generate_ready_function (Method m) {
@@ -550,23 +536,16 @@ public class Vala.GAsyncModule : GSignalModule {
public override void visit_yield_statement (YieldStatement stmt) {
if (current_method == null || !current_method.coroutine) {
- stmt.ccodenode = new CCodeEmptyStatement ();
return;
}
if (stmt.yield_expression == null) {
- var cfrag = new CCodeFragment ();
- stmt.ccodenode = cfrag;
-
int state = next_coroutine_state++;
- state_switch_statement.add_statement (new CCodeCaseStatement (new CCodeConstant (state.to_string ())));
- state_switch_statement.add_statement (new CCodeGotoStatement ("_state_%d".printf (state)));
-
- cfrag.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_state_"), new CCodeConstant (state.to_string ()))));
- cfrag.append (new CCodeReturnStatement (new CCodeConstant ("FALSE")));
- cfrag.append (new CCodeLabel ("_state_%d".printf (state)));
- cfrag.append (new CCodeEmptyStatement ());
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_state_"), new CCodeConstant (state.to_string ())));
+ ccode.add_return (new CCodeConstant ("FALSE"));
+ ccode.add_label ("_state_%d".printf (state));
+ ccode.add_statement (new CCodeEmptyStatement ());
return;
}
@@ -576,68 +555,44 @@ public class Vala.GAsyncModule : GSignalModule {
return;
}
- stmt.ccodenode = new CCodeExpressionStatement ((CCodeExpression) stmt.yield_expression.ccodenode);
+ ccode.add_expression ((CCodeExpression) stmt.yield_expression.ccodenode);
if (stmt.tree_can_fail && stmt.yield_expression.tree_can_fail) {
// simple case, no node breakdown necessary
- var cfrag = new CCodeFragment ();
-
- cfrag.append (stmt.ccodenode);
-
- add_simple_check (stmt.yield_expression, cfrag);
-
- stmt.ccodenode = cfrag;
+ add_simple_check (stmt.yield_expression);
}
/* free temporary objects */
- if (((List<LocalVariable>) temp_vars).size == 0) {
- /* nothing to do without temporary variables */
- return;
- }
-
- var cfrag = new CCodeFragment ();
- append_temp_decl (cfrag, temp_vars);
-
- cfrag.append (stmt.ccodenode);
-
foreach (LocalVariable local in temp_ref_vars) {
var ma = new MemberAccess.simple (local.name);
ma.symbol_reference = local;
- cfrag.append (new CCodeExpressionStatement (get_unref_expression (new CCodeIdentifier (local.name), local.variable_type, ma)));
+ ccode.add_expression (get_unref_expression (new CCodeIdentifier (local.name), local.variable_type, ma));
}
-
- stmt.ccodenode = cfrag;
-
- temp_vars.clear ();
+
temp_ref_vars.clear ();
}
- public override CCodeStatement return_with_exception (CCodeExpression error_expr)
+ public override void return_with_exception (CCodeExpression error_expr)
{
if (!current_method.coroutine) {
- return base.return_with_exception (error_expr);
+ base.return_with_exception (error_expr);
+ return;
}
- var block = new CCodeBlock ();
-
var set_error = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_set_from_error"));
set_error.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_async_result"));
set_error.add_argument (error_expr);
- block.add_statement (new CCodeExpressionStatement (set_error));
+ ccode.add_expression (set_error);
var free_error = new CCodeFunctionCall (new CCodeIdentifier ("g_error_free"));
free_error.add_argument (error_expr);
- block.add_statement (new CCodeExpressionStatement (free_error));
+ ccode.add_expression (free_error);
- var free_locals = new CCodeFragment ();
- append_local_free (current_symbol, free_locals, false);
- block.add_statement (free_locals);
+ append_local_free (current_symbol, false);
- block.add_statement (complete_async ());
-
- return block;
+ complete_async ();
}
public override void visit_return_statement (ReturnStatement stmt) {
@@ -647,9 +602,7 @@ public class Vala.GAsyncModule : GSignalModule {
return;
}
- var cfrag = (CCodeFragment) stmt.ccodenode;
-
- cfrag.append (complete_async ());
+ complete_async ();
}
public override void generate_cparameters (Method m, CCodeFile decl_space, Map<int,CCodeFormalParameter> cparam_map, CCodeFunction func, CCodeFunctionDeclarator? vdeclarator = null, Map<int,CCodeExpression>? carg_map = null, CCodeFunctionCall? vcall = null, int direction = 3) {
diff --git a/codegen/valagerrormodule.vala b/codegen/valagerrormodule.vala
index 19db146..ae406e1 100644
--- a/codegen/valagerrormodule.vala
+++ b/codegen/valagerrormodule.vala
@@ -81,60 +81,40 @@ public class Vala.GErrorModule : CCodeDelegateModule {
}
public override void visit_throw_statement (ThrowStatement stmt) {
- var cfrag = new CCodeFragment ();
-
// method will fail
current_method_inner_error = true;
- var cassign = new CCodeAssignment (get_variable_cexpression ("_inner_error_"), (CCodeExpression) stmt.error_expression.ccodenode);
- cfrag.append (new CCodeExpressionStatement (cassign));
-
- add_simple_check (stmt, cfrag, true);
-
- stmt.ccodenode = cfrag;
+ ccode.add_expression (new CCodeAssignment (get_variable_cexpression ("_inner_error_"), (CCodeExpression) stmt.error_expression.ccodenode));
- create_temp_decl (stmt, stmt.error_expression.temp_vars);
+ add_simple_check (stmt, true);
}
- public virtual CCodeStatement return_with_exception (CCodeExpression error_expr)
- {
+ public virtual void return_with_exception (CCodeExpression error_expr) {
var cpropagate = new CCodeFunctionCall (new CCodeIdentifier ("g_propagate_error"));
cpropagate.add_argument (new CCodeIdentifier ("error"));
cpropagate.add_argument (error_expr);
- var cerror_block = new CCodeBlock ();
- cerror_block.add_statement (new CCodeExpressionStatement (cpropagate));
+ ccode.add_expression (cpropagate);
// free local variables
- var free_frag = new CCodeFragment ();
- append_local_free (current_symbol, free_frag, false);
- cerror_block.add_statement (free_frag);
+ append_local_free (current_symbol, false);
if (current_method is CreationMethod) {
var cl = current_method.parent_symbol as Class;
var unref_call = get_unref_expression (new CCodeIdentifier ("self"), new ObjectType (cl), null);
- cerror_block.add_statement (new CCodeExpressionStatement (unref_call));
- cerror_block.add_statement (new CCodeReturnStatement (new CCodeConstant ("NULL")));
+ ccode.add_expression (unref_call);
+ ccode.add_return (new CCodeConstant ("NULL"));
} else if (current_method != null && current_method.coroutine) {
- cerror_block.add_statement (new CCodeReturnStatement (new CCodeConstant ("FALSE")));
+ ccode.add_return (new CCodeConstant ("FALSE"));
} else if (current_return_type is VoidType) {
- cerror_block.add_statement (new CCodeReturnStatement ());
+ ccode.add_return ();
} else {
- cerror_block.add_statement (new CCodeReturnStatement (default_value_for_type (current_return_type, false)));
+ ccode.add_return (default_value_for_type (current_return_type, false));
}
-
- return cerror_block;
}
- CCodeStatement uncaught_error_statement (CCodeExpression inner_error, CCodeBlock? block = null, bool unexpected = false) {
- var cerror_block = block;
- if (cerror_block == null) {
- cerror_block = new CCodeBlock ();
- }
-
+ void uncaught_error_statement (CCodeExpression inner_error, bool unexpected = false) {
// free local variables
- var free_frag = new CCodeFragment ();
- append_local_free (current_symbol, free_frag, false);
- cerror_block.add_statement (free_frag);
+ append_local_free (current_symbol, false);
var ccritical = new CCodeFunctionCall (new CCodeIdentifier ("g_critical"));
ccritical.add_argument (new CCodeConstant (unexpected ? "\"file %s: line %d: unexpected error: %s (%s, %d)\"" : "\"file %s: line %d: uncaught error: %s (%s, %d)\""));
@@ -149,24 +129,19 @@ public class Vala.GErrorModule : CCodeDelegateModule {
var cclear = new CCodeFunctionCall (new CCodeIdentifier ("g_clear_error"));
cclear.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, inner_error));
- var cprint_frag = new CCodeFragment ();
- cprint_frag.append (new CCodeExpressionStatement (ccritical));
- cprint_frag.append (new CCodeExpressionStatement (cclear));
-
// print critical message
- cerror_block.add_statement (cprint_frag);
+ ccode.add_expression (ccritical);
+ ccode.add_expression (cclear);
if (current_method is CreationMethod) {
- cerror_block.add_statement (new CCodeReturnStatement (new CCodeConstant ("NULL")));
+ ccode.add_return (new CCodeConstant ("NULL"));
} else if (current_method != null && current_method.coroutine) {
- cerror_block.add_statement (new CCodeReturnStatement (new CCodeConstant ("FALSE")));
+ ccode.add_return (new CCodeConstant ("FALSE"));
} else if (current_return_type is VoidType) {
- cerror_block.add_statement (new CCodeReturnStatement ());
+ ccode.add_return ();
} else if (current_return_type != null) {
- cerror_block.add_statement (new CCodeReturnStatement (default_value_for_type (current_return_type, false)));
+ ccode.add_return (default_value_for_type (current_return_type, false));
}
-
- return cerror_block;
}
bool in_finally_block (CodeNode node) {
@@ -181,21 +156,24 @@ public class Vala.GErrorModule : CCodeDelegateModule {
return false;
}
- public override void add_simple_check (CodeNode node, CCodeFragment cfrag, bool always_fails = false) {
+ public override void add_simple_check (CodeNode node, bool always_fails = false) {
current_method_inner_error = true;
var inner_error = get_variable_cexpression ("_inner_error_");
- CCodeStatement cerror_handler = null;
+ if (always_fails) {
+ // inner_error is always set, avoid unnecessary if statement
+ // eliminates C warnings
+ } else {
+ var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, inner_error, new CCodeConstant ("NULL"));
+ ccode.open_if (ccond);
+ }
if (current_try != null) {
// surrounding try found
- var cerror_block = new CCodeBlock ();
// free local variables
- var free_frag = new CCodeFragment ();
- append_error_free (current_symbol, free_frag, current_try);
- cerror_block.add_statement (free_frag);
+ append_error_free (current_symbol, current_try);
var error_types = new ArrayList<DataType> ();
foreach (DataType node_error_type in node.get_error_types ()) {
@@ -218,18 +196,13 @@ public class Vala.GErrorModule : CCodeDelegateModule {
}
handled_error_types.clear ();
- // go to catch clause if error domain matches
- var cgoto_stmt = new CCodeGotoStatement (clause.clabel_name);
-
if (clause.error_type.equals (gerror_type)) {
// general catch clause, this should be the last one
has_general_catch_clause = true;
- cerror_block.add_statement (cgoto_stmt);
+ ccode.add_goto (clause.clabel_name);
break;
} else {
var catch_type = clause.error_type as ErrorType;
- var cgoto_block = new CCodeBlock ();
- cgoto_block.add_statement (cgoto_stmt);
if (catch_type.error_code != null) {
/* catch clause specifies a specific error code */
@@ -238,15 +211,19 @@ public class Vala.GErrorModule : CCodeDelegateModule {
error_match.add_argument (new CCodeIdentifier (catch_type.data_type.get_upper_case_cname ()));
error_match.add_argument (new CCodeIdentifier (catch_type.error_code.get_cname ()));
- cerror_block.add_statement (new CCodeIfStatement (error_match, cgoto_block));
+ ccode.open_if (error_match);
} else {
/* catch clause specifies a full error domain */
var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY,
new CCodeMemberAccess.pointer (inner_error, "domain"), new CCodeIdentifier
(clause.error_type.data_type.get_upper_case_cname ()));
- cerror_block.add_statement (new CCodeIfStatement (ccond, cgoto_block));
+ ccode.open_if (ccond);
}
+
+ // go to catch clause if error domain matches
+ ccode.add_goto (clause.clabel_name);
+ ccode.close ();
}
}
}
@@ -258,16 +235,14 @@ public class Vala.GErrorModule : CCodeDelegateModule {
} else if (error_types.size > 0) {
// go to finally clause if no catch clause matches
// and there are still unhandled error types
- cerror_block.add_statement (new CCodeGotoStatement ("__finally%d".printf (current_try_id)));
+ ccode.add_goto ("__finally%d".printf (current_try_id));
} else if (in_finally_block (node)) {
// do not check unexpected errors happening within finally blocks
// as jump out of finally block is not supported
} else {
// should never happen with correct bindings
- uncaught_error_statement (inner_error, cerror_block, true);
+ uncaught_error_statement (inner_error, true);
}
-
- cerror_handler = cerror_block;
} else if (current_method != null && current_method.get_error_types ().size > 0) {
// current method can fail, propagate error
CCodeBinaryExpression ccond = null;
@@ -289,26 +264,22 @@ public class Vala.GErrorModule : CCodeDelegateModule {
}
}
- if (ccond == null) {
- cerror_handler = return_with_exception (inner_error);
+ if (ccond != null) {
+ ccode.open_if (ccond);
+ return_with_exception (inner_error);
+
+ ccode.add_else ();
+ uncaught_error_statement (inner_error);
+ ccode.close ();
} else {
- var cerror_block = new CCodeBlock ();
- cerror_block.add_statement (new CCodeIfStatement (ccond,
- return_with_exception (inner_error),
- uncaught_error_statement (inner_error)));
- cerror_handler = cerror_block;
+ return_with_exception (inner_error);
}
} else {
- cerror_handler = uncaught_error_statement (inner_error);
+ uncaught_error_statement (inner_error);
}
- if (always_fails) {
- // inner_error is always set, avoid unnecessary if statement
- // eliminates C warnings
- cfrag.append (cerror_handler);
- } else {
- var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, inner_error, new CCodeConstant ("NULL"));
- cfrag.append (new CCodeIfStatement (ccond, cerror_handler));
+ if (!always_fails) {
+ ccode.close ();
}
}
@@ -326,15 +297,12 @@ public class Vala.GErrorModule : CCodeDelegateModule {
clause.clabel_name = "__catch%d_%s".printf (this_try_id, clause.error_type.get_lower_case_cname ());
}
- if (stmt.finally_body != null) {
- stmt.finally_body.emit (this);
- }
-
is_in_catch = false;
stmt.body.emit (this);
is_in_catch = true;
foreach (CatchClause clause in stmt.get_catch_clauses ()) {
+ ccode.add_goto ("__finally%d".printf (this_try_id));
clause.emit (this);
}
@@ -342,24 +310,14 @@ public class Vala.GErrorModule : CCodeDelegateModule {
current_try_id = old_try_id;
is_in_catch = old_is_in_catch;
- var cfrag = new CCodeFragment ();
- cfrag.append (stmt.body.ccodenode);
-
- foreach (CatchClause clause in stmt.get_catch_clauses ()) {
- cfrag.append (new CCodeGotoStatement ("__finally%d".printf (this_try_id)));
- cfrag.append (clause.ccodenode);
- }
-
- cfrag.append (new CCodeLabel ("__finally%d".printf (this_try_id)));
+ ccode.add_label ("__finally%d".printf (this_try_id));
if (stmt.finally_body != null) {
- cfrag.append (stmt.finally_body.ccodenode);
+ stmt.finally_body.emit (this);
}
// check for errors not handled by this try statement
// may be handled by outer try statements or propagated
- add_simple_check (stmt, cfrag, !stmt.after_try_block_reachable);
-
- stmt.ccodenode = cfrag;
+ add_simple_check (stmt, !stmt.after_try_block_reachable);
}
public override void visit_catch_clause (CatchClause clause) {
@@ -370,12 +328,9 @@ public class Vala.GErrorModule : CCodeDelegateModule {
generate_error_domain_declaration (error_type.error_domain, cfile);
}
- clause.body.emit (this);
-
- var cfrag = new CCodeFragment ();
- cfrag.append (new CCodeLabel (clause.clabel_name));
+ ccode.add_label (clause.clabel_name);
- var cblock = new CCodeBlock ();
+ ccode.open_block ();
string variable_name;
if (clause.variable_name != null) {
@@ -384,31 +339,27 @@ public class Vala.GErrorModule : CCodeDelegateModule {
variable_name = "__err";
}
- if (current_method != null && current_method.coroutine) {
- closure_struct.add_field ("GError *", variable_name);
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (get_variable_cexpression (variable_name), get_variable_cexpression ("_inner_error_"))));
- } else {
- if (clause.variable_name != null) {
- var cdecl = new CCodeDeclaration ("GError *");
- cdecl.add_declarator (new CCodeVariableDeclarator (variable_name, get_variable_cexpression ("_inner_error_")));
- cblock.add_statement (cdecl);
+ if (clause.variable_name != null) {
+ if (current_method != null && current_method.coroutine) {
+ closure_struct.add_field ("GError *", variable_name);
} else {
- // error object is not used within catch statement, clear it
- var cclear = new CCodeFunctionCall (new CCodeIdentifier ("g_clear_error"));
- cclear.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression ("_inner_error_")));
- cblock.add_statement (new CCodeExpressionStatement (cclear));
+ ccode.add_declaration ("GError *", new CCodeVariableDeclarator (variable_name));
}
+ ccode.add_expression (new CCodeAssignment (get_variable_cexpression (variable_name), get_variable_cexpression ("_inner_error_")));
+ } else {
+ // error object is not used within catch statement, clear it
+ var cclear = new CCodeFunctionCall (new CCodeIdentifier ("g_clear_error"));
+ cclear.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression ("_inner_error_")));
+ ccode.add_expression (cclear);
}
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (get_variable_cexpression ("_inner_error_"), new CCodeConstant ("NULL"))));
+ ccode.add_expression (new CCodeAssignment (get_variable_cexpression ("_inner_error_"), new CCodeConstant ("NULL")));
- cblock.add_statement (clause.body.ccodenode);
-
- cfrag.append (cblock);
+ clause.body.emit (this);
- clause.ccodenode = cfrag;
+ ccode.close ();
}
- public override void append_local_free (Symbol sym, CCodeFragment cfrag, bool stop_at_loop = false) {
+ public override void append_local_free (Symbol sym, bool stop_at_loop = false) {
var finally_block = (Block) null;
if (sym.parent_node is TryStatement) {
finally_block = (sym.parent_node as TryStatement).finally_body;
@@ -417,10 +368,10 @@ public class Vala.GErrorModule : CCodeDelegateModule {
}
if (finally_block != null) {
- cfrag.append (finally_block.ccodenode);
+ finally_block.emit (this);
}
- base.append_local_free (sym, cfrag, stop_at_loop);
+ base.append_local_free (sym, stop_at_loop);
}
}
diff --git a/codegen/valagobjectmodule.vala b/codegen/valagobjectmodule.vala
index ef7e11f..d181108 100644
--- a/codegen/valagobjectmodule.vala
+++ b/codegen/valagobjectmodule.vala
@@ -42,7 +42,7 @@ public class Vala.GObjectModule : GTypeModule {
}
}
- public override void generate_class_init (Class cl, CCodeBlock init_block) {
+ public override void generate_class_init (Class cl) {
if (!cl.is_subtype_of (gobject_type)) {
return;
}
@@ -51,24 +51,24 @@ public class Vala.GObjectModule : GTypeModule {
var ccall = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
ccall.add_argument (new CCodeIdentifier ("klass"));
if (class_has_readable_properties (cl) || cl.get_type_parameters ().size > 0) {
- init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "get_property"), new CCodeIdentifier ("_vala_%s_get_property".printf (cl.get_lower_case_cname (null))))));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "get_property"), new CCodeIdentifier ("_vala_%s_get_property".printf (cl.get_lower_case_cname (null)))));
}
if (class_has_writable_properties (cl) || cl.get_type_parameters ().size > 0) {
- init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "set_property"), new CCodeIdentifier ("_vala_%s_set_property".printf (cl.get_lower_case_cname (null))))));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "set_property"), new CCodeIdentifier ("_vala_%s_set_property".printf (cl.get_lower_case_cname (null)))));
}
/* set constructor */
if (cl.constructor != null) {
var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
ccast.add_argument (new CCodeIdentifier ("klass"));
- init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "constructor"), new CCodeIdentifier ("%s_constructor".printf (cl.get_lower_case_cname (null))))));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "constructor"), new CCodeIdentifier ("%s_constructor".printf (cl.get_lower_case_cname (null)))));
}
/* set finalize function */
if (cl.get_fields ().size > 0 || cl.destructor != null) {
var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
ccast.add_argument (new CCodeIdentifier ("klass"));
- init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "finalize"), new CCodeIdentifier ("%s_finalize".printf (cl.get_lower_case_cname (null))))));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "finalize"), new CCodeIdentifier ("%s_finalize".printf (cl.get_lower_case_cname (null)))));
}
/* create type, dup_func, and destroy_func properties for generic types */
@@ -90,7 +90,7 @@ public class Vala.GObjectModule : GTypeModule {
cspec.add_argument (new CCodeIdentifier ("G_TYPE_NONE"));
cspec.add_argument (new CCodeConstant ("G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY"));
cinst.add_argument (cspec);
- init_block.add_statement (new CCodeExpressionStatement (cinst));
+ ccode.add_expression (cinst);
prop_enum.add_value (new CCodeEnumValue (enum_value));
@@ -106,7 +106,7 @@ public class Vala.GObjectModule : GTypeModule {
cspec.add_argument (new CCodeConstant ("\"dup func\""));
cspec.add_argument (new CCodeConstant ("G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY"));
cinst.add_argument (cspec);
- init_block.add_statement (new CCodeExpressionStatement (cinst));
+ ccode.add_expression (cinst);
prop_enum.add_value (new CCodeEnumValue (enum_value));
@@ -122,7 +122,7 @@ public class Vala.GObjectModule : GTypeModule {
cspec.add_argument (new CCodeConstant ("\"destroy func\""));
cspec.add_argument (new CCodeConstant ("G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY"));
cinst.add_argument (cspec);
- init_block.add_statement (new CCodeExpressionStatement (cinst));
+ ccode.add_expression (cinst);
prop_enum.add_value (new CCodeEnumValue (enum_value));
}
@@ -134,7 +134,7 @@ public class Vala.GObjectModule : GTypeModule {
}
if (prop.comment != null) {
- init_block.add_statement (new CCodeComment (prop.comment.content));
+ ccode.add_statement (new CCodeComment (prop.comment.content));
}
if (prop.overrides || prop.base_interface_property != null) {
@@ -143,14 +143,14 @@ public class Vala.GObjectModule : GTypeModule {
cinst.add_argument (new CCodeConstant (prop.get_upper_case_cname ()));
cinst.add_argument (prop.get_canonical_cconstant ());
- init_block.add_statement (new CCodeExpressionStatement (cinst));
+ ccode.add_expression (cinst);
} else {
var cinst = new CCodeFunctionCall (new CCodeIdentifier ("g_object_class_install_property"));
cinst.add_argument (ccall);
cinst.add_argument (new CCodeConstant (prop.get_upper_case_cname ()));
cinst.add_argument (get_param_spec (prop));
- init_block.add_statement (new CCodeExpressionStatement (cinst));
+ ccode.add_expression (cinst);
}
}
}
@@ -412,18 +412,11 @@ public class Vala.GObjectModule : GTypeModule {
}
public override void visit_constructor (Constructor c) {
- bool old_method_inner_error = current_method_inner_error;
- current_method_inner_error = false;
-
if (c.binding == MemberBinding.CLASS || c.binding == MemberBinding.STATIC) {
in_static_or_class_context = true;
} else {
in_constructor = true;
}
- c.body.emit (this);
- in_static_or_class_context = false;
-
- in_constructor = false;
var cl = (Class) c.parent_symbol;
@@ -434,7 +427,9 @@ public class Vala.GObjectModule : GTypeModule {
return;
}
- function = new CCodeFunction ("%s_constructor".printf (cl.get_lower_case_cname (null)), "GObject *");
+ push_context (new EmitContext (c));
+
+ var function = new CCodeFunction ("%s_constructor".printf (cl.get_lower_case_cname (null)), "GObject *");
function.modifiers = CCodeModifiers.STATIC;
function.add_parameter (new CCodeFormalParameter ("type", "GType"));
@@ -443,52 +438,43 @@ public class Vala.GObjectModule : GTypeModule {
cfile.add_function_declaration (function);
+ push_function (function);
- var cblock = new CCodeBlock ();
- var cdecl = new CCodeDeclaration ("GObject *");
- cdecl.add_declarator (new CCodeVariableDeclarator ("obj"));
- cblock.add_statement (cdecl);
-
- cdecl = new CCodeDeclaration ("GObjectClass *");
- cdecl.add_declarator (new CCodeVariableDeclarator ("parent_class"));
- cblock.add_statement (cdecl);
-
+ ccode.add_declaration ("GObject *", new CCodeVariableDeclarator ("obj"));
+ ccode.add_declaration ("GObjectClass *", new CCodeVariableDeclarator ("parent_class"));
var ccast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
ccast.add_argument (new CCodeIdentifier ("%s_parent_class".printf (cl.get_lower_case_cname (null))));
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("parent_class"), ccast)));
+ ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("parent_class"), ccast));
-
var ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (new CCodeIdentifier ("parent_class"), "constructor"));
ccall.add_argument (new CCodeIdentifier ("type"));
ccall.add_argument (new CCodeIdentifier ("n_construct_properties"));
ccall.add_argument (new CCodeIdentifier ("construct_properties"));
- cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("obj"), ccall)));
+ ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("obj"), ccall));
ccall = generate_instance_cast (new CCodeIdentifier ("obj"), cl);
- cdecl = new CCodeDeclaration ("%s *".printf (cl.get_cname ()));
- cdecl.add_declarator (new CCodeVariableDeclarator ("self", ccall));
- cblock.add_statement (cdecl);
+ ccode.add_declaration ("%s *".printf (cl.get_cname ()), new CCodeVariableDeclarator ("self"));
+ ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("self"), ccall));
if (current_method_inner_error) {
/* always separate error parameter and inner_error local variable
* as error may be set to NULL but we're always interested in inner errors
*/
- cdecl = new CCodeDeclaration ("GError *");
- cdecl.add_declarator (new CCodeVariableDeclarator ("_inner_error_", new CCodeConstant ("NULL")));
- cblock.add_statement (cdecl);
+ ccode.add_declaration ("GError *", new CCodeVariableDeclarator.zero ("_inner_error_", new CCodeConstant ("NULL")));
}
- cblock.add_statement (c.body.ccodenode);
-
- cblock.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("obj")));
+ c.body.emit (this);
- function.block = cblock;
+ ccode.add_return (new CCodeIdentifier ("obj"));
+ pop_function ();
cfile.add_function (function);
+
+ pop_context ();
} else if (c.binding == MemberBinding.CLASS) {
// class constructor
@@ -498,16 +484,18 @@ public class Vala.GObjectModule : GTypeModule {
return;
}
+ push_context (base_init_context);
+
+ c.body.emit (this);
+
if (current_method_inner_error) {
/* always separate error parameter and inner_error local variable
* as error may be set to NULL but we're always interested in inner errors
*/
- var cdecl = new CCodeDeclaration ("GError *");
- cdecl.add_declarator (new CCodeVariableDeclarator ("_inner_error_", new CCodeConstant ("NULL")));
- base_init_fragment.append (cdecl);
+ ccode.add_declaration ("GError *", new CCodeVariableDeclarator.zero ("_inner_error_", new CCodeConstant ("NULL")));
}
- base_init_fragment.append (c.body.ccodenode);
+ pop_context ();
} else if (c.binding == MemberBinding.STATIC) {
// static class constructor
// add to class_init
@@ -518,21 +506,25 @@ public class Vala.GObjectModule : GTypeModule {
return;
}
+ push_context (class_init_context);
+
+ c.body.emit (this);
+
if (current_method_inner_error) {
/* always separate error parameter and inner_error local variable
* as error may be set to NULL but we're always interested in inner errors
*/
- var cdecl = new CCodeDeclaration ("GError *");
- cdecl.add_declarator (new CCodeVariableDeclarator ("_inner_error_", new CCodeConstant ("NULL")));
- class_init_fragment.append (cdecl);
+ ccode.add_declaration ("GError *", new CCodeVariableDeclarator ("_inner_error_", new CCodeConstant ("NULL")));
}
- class_init_fragment.append (c.body.ccodenode);
+ pop_context ();
} else {
Report.error (c.source_reference, "internal error: constructors must have instance, class, or static binding");
}
- current_method_inner_error = old_method_inner_error;
+ in_static_or_class_context = false;
+
+ in_constructor = false;
}
public override string get_dynamic_property_getter_cname (DynamicProperty prop) {
@@ -756,7 +748,7 @@ public class Vala.GObjectModule : GTypeModule {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (expr.value_type, false, expr, false);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), (CCodeExpression) expr.ccodenode));
var initiallyunowned_ccall = new CCodeFunctionCall (new CCodeIdentifier ("G_IS_INITIALLY_UNOWNED"));
diff --git a/codegen/valagsignalmodule.vala b/codegen/valagsignalmodule.vala
index e2b0de8..8b90ef4 100644
--- a/codegen/valagsignalmodule.vala
+++ b/codegen/valagsignalmodule.vala
@@ -164,7 +164,7 @@ public class Vala.GSignalModule : GObjectModule {
}
var detail_decl = get_temp_variable (detail_expr.value_type, true, node);
- temp_vars.insert (0, detail_decl);
+ emit_temp_var (detail_decl);
temp_ref_vars.insert (0, detail_decl);
var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_strconcat"));
@@ -679,7 +679,7 @@ public class Vala.GSignalModule : GObjectModule {
// get signal id
ccomma = new CCodeCommaExpression ();
var temp_decl = get_temp_variable (uint_type);
- temp_vars.add (temp_decl);
+ emit_temp_var (temp_decl);
var parse_call = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_parse_name"));
parse_call.add_argument (signal_name_cexpr);
var decl_type = (TypeSymbol) sig.parent_symbol;
@@ -691,7 +691,7 @@ public class Vala.GSignalModule : GObjectModule {
parse_call.add_argument (new CCodeConstant ("FALSE"));
} else {
detail_temp_decl = get_temp_variable (gquark_type);
- temp_vars.add (detail_temp_decl);
+ emit_temp_var (detail_temp_decl);
parse_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (detail_temp_decl.name)));
parse_call.add_argument (new CCodeConstant ("TRUE"));
}
diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala
index a6c1ebd..d6da086 100644
--- a/codegen/valagtypemodule.vala
+++ b/codegen/valagtypemodule.vala
@@ -516,12 +516,12 @@ public class Vala.GTypeModule : GErrorModule {
var old_param_spec_struct = param_spec_struct;
var old_prop_enum = prop_enum;
- var old_class_init_fragment = class_init_fragment;
- var old_base_init_fragment = base_init_fragment;
- var old_class_finalize_fragment = class_finalize_fragment;
- var old_base_finalize_fragment = base_finalize_fragment;
- var old_instance_init_fragment = instance_init_fragment;
- var old_instance_finalize_fragment = instance_finalize_fragment;
+ var old_class_init_context = class_init_context;
+ var old_base_init_context = base_init_context;
+ var old_class_finalize_context = class_finalize_context;
+ var old_base_finalize_context = base_finalize_context;
+ var old_instance_init_context = instance_init_context;
+ var old_instance_finalize_context = instance_finalize_context;
bool is_gtypeinstance = !cl.is_compact;
bool is_fundamental = is_gtypeinstance && cl.base_class == null;
@@ -534,12 +534,12 @@ public class Vala.GTypeModule : GErrorModule {
prop_enum = new CCodeEnum ();
prop_enum.add_value (new CCodeEnumValue ("%s_DUMMY_PROPERTY".printf (cl.get_upper_case_cname (null))));
- class_init_fragment = new CCodeFragment ();
- base_init_fragment = new CCodeFragment ();
- class_finalize_fragment = new CCodeFragment ();
- base_finalize_fragment = new CCodeFragment ();
- instance_init_fragment = new CCodeFragment ();
- instance_finalize_fragment = new CCodeFragment ();
+ class_init_context = new EmitContext (cl);
+ base_init_context = new EmitContext (cl);
+ class_finalize_context = new EmitContext (cl);
+ base_finalize_context = new EmitContext (cl);
+ instance_init_context = new EmitContext (cl);
+ instance_finalize_context = new EmitContext (cl);
generate_class_struct_declaration (cl, cfile);
@@ -552,6 +552,21 @@ public class Vala.GTypeModule : GErrorModule {
generate_class_struct_declaration (cl, internal_header_file);
}
+ if (is_gtypeinstance) {
+ begin_base_init_function (cl);
+ begin_class_init_function (cl);
+ begin_instance_init_function (cl);
+
+ begin_base_finalize_function (cl);
+ begin_class_finalize_function (cl);
+ begin_finalize_function (cl);
+ } else {
+ if (cl.base_class == null) {
+ begin_instance_init_function (cl);
+ begin_finalize_function (cl);
+ }
+ }
+
cl.accept_children (this);
if (is_gtypeinstance) {
@@ -577,7 +592,7 @@ public class Vala.GTypeModule : GErrorModule {
add_g_value_take_function (cl);
var ref_count = new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "ref_count"), new CCodeConstant ("1"));
- instance_init_fragment.append (new CCodeExpressionStatement (ref_count));
+ instance_init_context.ccode.add_expression (ref_count);
}
@@ -672,41 +687,18 @@ public class Vala.GTypeModule : GErrorModule {
if (cl.base_class == null) {
// derived compact classes do not have fields
add_instance_init_function (cl);
-
- var function = new CCodeFunction (cl.get_lower_case_cprefix () + "free", "void");
- if (cl.access == SymbolAccessibility.PRIVATE) {
- function.modifiers = CCodeModifiers.STATIC;
- }
-
- function.add_parameter (new CCodeFormalParameter ("self", cl.get_cname () + "*"));
-
- var cblock = new CCodeBlock ();
-
- if (cl.destructor != null) {
- cblock.add_statement (cl.destructor.ccodenode);
- }
-
- cblock.add_statement (instance_finalize_fragment);
-
- var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_free"));
- ccall.add_argument (new CCodeIdentifier (cl.get_cname ()));
- ccall.add_argument (new CCodeIdentifier ("self"));
- cblock.add_statement (new CCodeExpressionStatement (ccall));
-
- function.block = cblock;
-
- cfile.add_function (function);
+ add_finalize_function (cl);
}
}
param_spec_struct = old_param_spec_struct;
prop_enum = old_prop_enum;
- class_init_fragment = old_class_init_fragment;
- base_init_fragment = old_base_init_fragment;
- class_finalize_fragment = old_class_finalize_fragment;
- base_finalize_fragment = old_base_finalize_fragment;
- instance_init_fragment = old_instance_init_fragment;
- instance_finalize_fragment = old_instance_finalize_fragment;
+ class_init_context = old_class_init_context;
+ base_init_context = old_base_init_context;
+ class_finalize_context = old_class_finalize_context;
+ base_finalize_context = old_base_finalize_context;
+ instance_init_context = old_instance_init_context;
+ instance_finalize_context = old_instance_finalize_context;
pop_context ();
}
@@ -1133,31 +1125,31 @@ public class Vala.GTypeModule : GErrorModule {
cfile.add_function (function);
}
- private void add_base_init_function (Class cl) {
+ private void begin_base_init_function (Class cl) {
+ push_context (base_init_context);
+
var base_init = new CCodeFunction ("%s_base_init".printf (cl.get_lower_case_cname (null)), "void");
base_init.add_parameter (new CCodeFormalParameter ("klass", "%sClass *".printf (cl.get_cname ())));
base_init.modifiers = CCodeModifiers.STATIC;
- var init_block = new CCodeBlock ();
- base_init.block = init_block;
+ push_function (base_init);
if (!context.require_glib_version (2, 24) && cl.has_class_private_fields) {
- var block = new CCodeBlock ();
var cdecl = new CCodeDeclaration ("%sClassPrivate *".printf (cl.get_cname ()));
cdecl.add_declarator (new CCodeVariableDeclarator ("priv"));
- block.add_statement (cdecl);
+ ccode.add_statement (cdecl);
cdecl = new CCodeDeclaration ("%sClassPrivate *".printf (cl.get_cname ()));
cdecl.add_declarator (new CCodeVariableDeclarator ("parent_priv", new CCodeConstant ("NULL")));
- block.add_statement (cdecl);
+ ccode.add_statement (cdecl);
cdecl = new CCodeDeclaration ("GType");
cdecl.add_declarator (new CCodeVariableDeclarator ("parent_type"));
- block.add_statement (cdecl);
+ ccode.add_statement (cdecl);
var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_parent"));
var ccall2 = new CCodeFunctionCall (new CCodeIdentifier ("G_TYPE_FROM_CLASS"));
ccall2.add_argument (new CCodeIdentifier ("klass"));
ccall.add_argument (ccall2);
- block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("parent_type"), ccall)));
+ ccode.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("parent_type"), ccall)));
var iftrue = new CCodeBlock ();
ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_CLASS_PRIVATE".printf (cl.get_upper_case_cname (null))));
@@ -1165,12 +1157,12 @@ public class Vala.GTypeModule : GErrorModule {
ccall2.add_argument (new CCodeIdentifier ("parent_type"));
ccall.add_argument (ccall2);
iftrue.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("parent_priv"), ccall)));
- block.add_statement (new CCodeIfStatement (new CCodeIdentifier ("parent_type"), iftrue));
+ ccode.add_statement (new CCodeIfStatement (new CCodeIdentifier ("parent_type"), iftrue));
ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_new0"));
ccall.add_argument (new CCodeIdentifier ("%sClassPrivate".printf(cl.get_cname())));
- block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("priv"), ccall)));
+ ccode.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("priv"), ccall)));
cfile.add_include ("string.h");
@@ -1181,7 +1173,7 @@ public class Vala.GTypeModule : GErrorModule {
ccall.add_argument (new CCodeIdentifier ("sizeof (%sClassPrivate)".printf(cl.get_cname())));
iftrue.add_statement (new CCodeExpressionStatement (ccall));
- block.add_statement (new CCodeIfStatement (new CCodeIdentifier ("parent_priv"), iftrue));
+ ccode.add_statement (new CCodeIfStatement (new CCodeIdentifier ("parent_priv"), iftrue));
ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_set_qdata"));
ccall2 = new CCodeFunctionCall (new CCodeIdentifier ("G_TYPE_FROM_CLASS"));
@@ -1189,42 +1181,26 @@ public class Vala.GTypeModule : GErrorModule {
ccall.add_argument (ccall2);
ccall.add_argument (new CCodeIdentifier ("_vala_%s_class_private_quark".printf (cl.get_lower_case_cname ())));
ccall.add_argument (new CCodeIdentifier ("priv"));
- block.add_statement (new CCodeExpressionStatement (ccall));
-
- init_block.add_statement (block);
-
- block = new CCodeBlock ();
- cdecl = new CCodeDeclaration ("%sClassPrivate *".printf (cl.get_cname ()));
- cdecl.add_declarator (new CCodeVariableDeclarator ("priv"));
- block.add_statement (cdecl);
-
- ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_CLASS_PRIVATE".printf (cl.get_upper_case_cname (null))));
- ccall.add_argument (new CCodeConstant ("klass"));
- block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("priv"), ccall)));
-
- ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_free"));
- ccall.add_argument (new CCodeIdentifier ("%sClassPrivate".printf (cl.get_cname ())));
- ccall.add_argument (new CCodeIdentifier ("priv"));
- block.add_statement (new CCodeExpressionStatement (ccall));
- base_finalize_fragment.append (block);
+ ccode.add_statement (new CCodeExpressionStatement (ccall));
}
- init_block.add_statement (base_init_fragment);
+ pop_context ();
+ }
- cfile.add_function (base_init);
+ private void add_base_init_function (Class cl) {
+ cfile.add_function (base_init_context.ccode);
}
- public virtual void generate_class_init (Class cl, CCodeBlock init_block) {
+ public virtual void generate_class_init (Class cl) {
}
- private void add_class_init_function (Class cl) {
- var class_init = new CCodeFunction ("%s_class_init".printf (cl.get_lower_case_cname (null)), "void");
- class_init.add_parameter (new CCodeFormalParameter ("klass", "%sClass *".printf (cl.get_cname ())));
- class_init.modifiers = CCodeModifiers.STATIC;
+ private void begin_class_init_function (Class cl) {
+ push_context (class_init_context);
+
+ var func = new CCodeFunction ("%s_class_init".printf (cl.get_lower_case_cname (null)));
+ func.add_parameter (new CCodeFormalParameter ("klass", "%sClass *".printf (cl.get_cname ())));
+ func.modifiers = CCodeModifiers.STATIC;
- var init_block = new CCodeBlock ();
- class_init.block = init_block;
-
CCodeFunctionCall ccall;
/* save pointer to parent class */
@@ -1234,10 +1210,13 @@ public class Vala.GTypeModule : GErrorModule {
parent_decl.add_declarator (parent_var_decl);
parent_decl.modifiers = CCodeModifiers.STATIC;
cfile.add_type_member_declaration (parent_decl);
+
+ push_function (func);
+
ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_peek_parent"));
ccall.add_argument (new CCodeIdentifier ("klass"));
var parent_assignment = new CCodeAssignment (new CCodeIdentifier ("%s_parent_class".printf (cl.get_lower_case_cname (null))), ccall);
- init_block.add_statement (new CCodeExpressionStatement (parent_assignment));
+ ccode.add_expression (parent_assignment);
if (!cl.is_compact && !cl.is_subtype_of (gobject_type) && (cl.get_fields ().size > 0 || cl.destructor != null || cl.is_fundamental ())) {
@@ -1250,7 +1229,7 @@ public class Vala.GTypeModule : GErrorModule {
ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (fundamental_class.get_upper_case_cname (null))));
ccall.add_argument (new CCodeIdentifier ("klass"));
var finalize_assignment = new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "finalize"), new CCodeIdentifier (cl.get_lower_case_cprefix () + "finalize"));
- init_block.add_statement (new CCodeExpressionStatement (finalize_assignment));
+ ccode.add_expression (finalize_assignment);
}
/* add struct for private fields */
@@ -1258,7 +1237,7 @@ public class Vala.GTypeModule : GErrorModule {
ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_add_private"));
ccall.add_argument (new CCodeIdentifier ("klass"));
ccall.add_argument (new CCodeConstant ("sizeof (%sPrivate)".printf (cl.get_cname ())));
- init_block.add_statement (new CCodeExpressionStatement (ccall));
+ ccode.add_expression (ccall);
}
/* connect overridden methods */
@@ -1273,10 +1252,10 @@ public class Vala.GTypeModule : GErrorModule {
var ccast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (((Class) base_type).get_upper_case_cname (null))));
ccast.add_argument (new CCodeIdentifier ("klass"));
- init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, m.base_method.vfunc_name), new CCodeIdentifier (m.get_real_cname ()))));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, m.base_method.vfunc_name), new CCodeIdentifier (m.get_real_cname ())));
if (m.coroutine) {
- init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, m.base_method.get_finish_vfunc_name ()), new CCodeIdentifier (m.get_finish_real_cname ()))));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, m.base_method.get_finish_vfunc_name ()), new CCodeIdentifier (m.get_finish_real_cname ())));
}
}
}
@@ -1288,7 +1267,7 @@ public class Vala.GTypeModule : GErrorModule {
}
var ccast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (cl.get_upper_case_cname (null))));
ccast.add_argument (new CCodeIdentifier ("klass"));
- init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, sig.default_handler.vfunc_name), new CCodeIdentifier (sig.default_handler.get_real_cname ()))));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, sig.default_handler.vfunc_name), new CCodeIdentifier (sig.default_handler.get_real_cname ())));
}
/* connect overridden properties */
@@ -1303,30 +1282,33 @@ public class Vala.GTypeModule : GErrorModule {
if (prop.get_accessor != null) {
string cname = "%s_real_get_%s".printf (cl.get_lower_case_cname (null), prop.name);
- init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "get_%s".printf (prop.name)), new CCodeIdentifier (cname))));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "get_%s".printf (prop.name)), new CCodeIdentifier (cname)));
}
if (prop.set_accessor != null) {
string cname = "%s_real_set_%s".printf (cl.get_lower_case_cname (null), prop.name);
- init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "set_%s".printf (prop.name)), new CCodeIdentifier (cname))));
+ ccode.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (ccast, "set_%s".printf (prop.name)), new CCodeIdentifier (cname)));
}
}
- generate_class_init (cl, init_block);
+ generate_class_init (cl);
if (!cl.is_compact) {
/* create signals */
foreach (Signal sig in cl.get_signals ()) {
if (sig.comment != null) {
- init_block.add_statement (new CCodeComment (sig.comment.content));
+ ccode.add_statement (new CCodeComment (sig.comment.content));
}
- init_block.add_statement (new CCodeExpressionStatement (get_signal_creation (sig, cl)));
+ ccode.add_expression (get_signal_creation (sig, cl));
}
}
- init_block.add_statement (register_dbus_info (cl));
- init_block.add_statement (class_init_fragment);
+ register_dbus_info (cl);
- cfile.add_function (class_init);
+ pop_context ();
+ }
+
+ private void add_class_init_function (Class cl) {
+ cfile.add_function (class_init_context.ccode);
}
private void add_interface_init_function (Class cl, Interface iface) {
@@ -1540,111 +1522,167 @@ public class Vala.GTypeModule : GErrorModule {
return new CCodeCastExpression (cfunc, cast);
}
- private void add_instance_init_function (Class cl) {
- var instance_init = new CCodeFunction ("%s_instance_init".printf (cl.get_lower_case_cname (null)), "void");
- instance_init.add_parameter (new CCodeFormalParameter ("self", "%s *".printf (cl.get_cname ())));
- instance_init.modifiers = CCodeModifiers.STATIC;
-
+ private void begin_instance_init_function (Class cl) {
+ push_context (instance_init_context);
+
+ var func = new CCodeFunction ("%s_instance_init".printf (cl.get_lower_case_cname (null)));
+ func.add_parameter (new CCodeFormalParameter ("self", "%s *".printf (cl.get_cname ())));
+ func.modifiers = CCodeModifiers.STATIC;
+
+ push_function (func);
+
if (cl.is_compact) {
// Add declaration, since the instance_init function is explicitly called
// by the creation methods
- cfile.add_function_declaration (instance_init);
+ cfile.add_function_declaration (func);
}
- var init_block = new CCodeBlock ();
- instance_init.block = init_block;
-
if (!cl.is_compact && (cl.has_private_fields || cl.get_type_parameters ().size > 0)) {
var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_PRIVATE".printf (cl.get_upper_case_cname (null))));
ccall.add_argument (new CCodeIdentifier ("self"));
- init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), ccall)));
+ func.add_expression (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), ccall));
}
-
- init_block.add_statement (instance_init_fragment);
- cfile.add_function (instance_init);
+ pop_context ();
}
- private void add_class_finalize_function (Class cl) {
+ private void add_instance_init_function (Class cl) {
+ cfile.add_function (instance_init_context.ccode);
+ }
+
+ private void begin_class_finalize_function (Class cl) {
+ push_context (class_finalize_context);
+
var function = new CCodeFunction ("%s_class_finalize".printf (cl.get_lower_case_cname (null)), "void");
function.modifiers = CCodeModifiers.STATIC;
function.add_parameter (new CCodeFormalParameter ("klass", cl.get_cname () + "Class *"));
- cfile.add_function_declaration (function);
-
- var cblock = new CCodeBlock ();
+
+ push_function (function);
if (cl.class_destructor != null) {
- cblock.add_statement (cl.class_destructor.ccodenode);
+ cl.class_destructor.body.emit (this);
}
- cblock.add_statement (class_finalize_fragment);
+ pop_context ();
+ }
- function.block = cblock;
- cfile.add_function (function);
+ private void add_class_finalize_function (Class cl) {
+ cfile.add_function_declaration (class_finalize_context.ccode);
+ cfile.add_function (class_finalize_context.ccode);
}
- private void add_base_finalize_function (Class cl) {
+ private void begin_base_finalize_function (Class cl) {
+ push_context (base_finalize_context);
+
var function = new CCodeFunction ("%s_base_finalize".printf (cl.get_lower_case_cname (null)), "void");
function.modifiers = CCodeModifiers.STATIC;
function.add_parameter (new CCodeFormalParameter ("klass", cl.get_cname () + "Class *"));
- cfile.add_function_declaration (function);
-
- var cblock = new CCodeBlock ();
+
+ push_function (function);
if (cl.class_destructor != null) {
- cblock.add_statement (cl.class_destructor.ccodenode);
+ cl.class_destructor.body.emit (this);
}
- cblock.add_statement (base_finalize_fragment);
-
- function.block = cblock;
- cfile.add_function (function);
+ pop_context ();
}
- private void add_finalize_function (Class cl) {
- var function = new CCodeFunction ("%s_finalize".printf (cl.get_lower_case_cname (null)), "void");
- function.modifiers = CCodeModifiers.STATIC;
+ private void add_base_finalize_function (Class cl) {
+ push_context (base_finalize_context);
+
+ if (!context.require_glib_version (2, 24) && cl.has_class_private_fields) {
+ ccode.open_block ();
+
+ var cdecl = new CCodeDeclaration ("%sClassPrivate *".printf (cl.get_cname ()));
+ cdecl.add_declarator (new CCodeVariableDeclarator ("priv"));
+ ccode.add_statement (cdecl);
+
+ var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_CLASS_PRIVATE".printf (cl.get_upper_case_cname (null))));
+ ccall.add_argument (new CCodeConstant ("klass"));
+ ccode.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("priv"), ccall)));
+
+ ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_free"));
+ ccall.add_argument (new CCodeIdentifier ("%sClassPrivate".printf (cl.get_cname ())));
+ ccall.add_argument (new CCodeIdentifier ("priv"));
+ ccode.add_statement (new CCodeExpressionStatement (ccall));
- var fundamental_class = cl;
- while (fundamental_class.base_class != null) {
- fundamental_class = fundamental_class.base_class;
+ ccode.close ();
}
- function.add_parameter (new CCodeFormalParameter ("obj", fundamental_class.get_cname () + "*"));
+ cfile.add_function_declaration (ccode);
+ cfile.add_function (ccode);
- cfile.add_function_declaration (function);
+ pop_context ();
+ }
+ private void begin_finalize_function (Class cl) {
+ push_context (instance_finalize_context);
- var cblock = new CCodeBlock ();
+ if (!cl.is_compact) {
+ var fundamental_class = cl;
+ while (fundamental_class.base_class != null) {
+ fundamental_class = fundamental_class.base_class;
+ }
- CCodeFunctionCall ccall = generate_instance_cast (new CCodeIdentifier ("obj"), cl);
+ var func = new CCodeFunction ("%s_finalize".printf (cl.get_lower_case_cname (null)));
+ func.add_parameter (new CCodeFormalParameter ("obj", fundamental_class.get_cname () + "*"));
+ func.modifiers = CCodeModifiers.STATIC;
- var cdecl = new CCodeDeclaration ("%s *".printf (cl.get_cname ()));
- cdecl.add_declarator (new CCodeVariableDeclarator ("self", ccall));
-
- cblock.add_statement (cdecl);
+ push_function (func);
- if (cl.destructor != null) {
- cblock.add_statement (cl.destructor.ccodenode);
- }
+ CCodeFunctionCall ccall = generate_instance_cast (new CCodeIdentifier ("obj"), cl);
- cblock.add_statement (instance_finalize_fragment);
+ ccode.add_declaration ("%s *".printf (cl.get_cname ()), new CCodeVariableDeclarator ("self"));
+ ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("self"), ccall));
- // chain up to finalize function of the base class
- if (cl.base_class != null) {
- var ccast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (fundamental_class.get_upper_case_cname ())));
- ccast.add_argument (new CCodeIdentifier ("%s_parent_class".printf (cl.get_lower_case_cname (null))));
- ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (ccast, "finalize"));
- ccall.add_argument (new CCodeIdentifier ("obj"));
- cblock.add_statement (new CCodeExpressionStatement (ccall));
+ if (cl.destructor != null) {
+ cl.destructor.body.emit (this);
+ }
+ } else {
+ var function = new CCodeFunction (cl.get_lower_case_cprefix () + "free", "void");
+ if (cl.access == SymbolAccessibility.PRIVATE) {
+ function.modifiers = CCodeModifiers.STATIC;
+ }
+
+ function.add_parameter (new CCodeFormalParameter ("self", cl.get_cname () + "*"));
+
+ push_function (function);
+
+ if (cl.destructor != null) {
+ cl.destructor.body.emit (this);
+ }
}
+ pop_context ();
+ }
- function.block = cblock;
+ private void add_finalize_function (Class cl) {
+ if (!cl.is_compact) {
+ var fundamental_class = cl;
+ while (fundamental_class.base_class != null) {
+ fundamental_class = fundamental_class.base_class;
+ }
- cfile.add_function (function);
+ // chain up to finalize function of the base class
+ if (cl.base_class != null) {
+ var ccast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (fundamental_class.get_upper_case_cname ())));
+ ccast.add_argument (new CCodeIdentifier ("%s_parent_class".printf (cl.get_lower_case_cname (null))));
+ var ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (ccast, "finalize"));
+ ccall.add_argument (new CCodeIdentifier ("obj"));
+ instance_finalize_context.ccode.add_expression (ccall);
+ }
+
+ cfile.add_function_declaration (instance_finalize_context.ccode);
+ } else {
+ var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_free"));
+ ccall.add_argument (new CCodeIdentifier (cl.get_cname ()));
+ ccall.add_argument (new CCodeIdentifier ("self"));
+ instance_finalize_context.ccode.add_expression (ccall);
+ }
+
+ cfile.add_function (instance_finalize_context.ccode);
}
public override CCodeFunctionCall get_param_spec (Property prop) {
@@ -1687,7 +1725,7 @@ public class Vala.GTypeModule : GErrorModule {
}
if (prop.initializer != null) {
- cspec.add_argument ((CCodeExpression) prop.initializer.ccodenode);
+ cspec.add_argument ((CCodeExpression) get_ccodenode (prop.initializer));
} else {
cspec.add_argument (new CCodeConstant (prop.property_type.data_type.get_default_value ()));
}
@@ -1698,7 +1736,7 @@ public class Vala.GTypeModule : GErrorModule {
cspec.add_argument (new CCodeConstant ("G_MININT"));
cspec.add_argument (new CCodeConstant ("G_MAXINT"));
if (prop.initializer != null) {
- cspec.add_argument ((CCodeExpression) prop.initializer.ccodenode);
+ cspec.add_argument ((CCodeExpression) get_ccodenode (prop.initializer));
} else {
cspec.add_argument (new CCodeConstant ("0"));
}
@@ -1707,7 +1745,7 @@ public class Vala.GTypeModule : GErrorModule {
cspec.add_argument (new CCodeConstant ("0"));
cspec.add_argument (new CCodeConstant ("G_MAXUINT"));
if (prop.initializer != null) {
- cspec.add_argument ((CCodeExpression) prop.initializer.ccodenode);
+ cspec.add_argument ((CCodeExpression) get_ccodenode (prop.initializer));
} else {
cspec.add_argument (new CCodeConstant ("0U"));
}
@@ -1716,7 +1754,7 @@ public class Vala.GTypeModule : GErrorModule {
cspec.add_argument (new CCodeConstant ("G_MININT64"));
cspec.add_argument (new CCodeConstant ("G_MAXINT64"));
if (prop.initializer != null) {
- cspec.add_argument ((CCodeExpression) prop.initializer.ccodenode);
+ cspec.add_argument ((CCodeExpression) get_ccodenode (prop.initializer));
} else {
cspec.add_argument (new CCodeConstant ("0"));
}
@@ -1725,7 +1763,7 @@ public class Vala.GTypeModule : GErrorModule {
cspec.add_argument (new CCodeConstant ("0"));
cspec.add_argument (new CCodeConstant ("G_MAXUINT64"));
if (prop.initializer != null) {
- cspec.add_argument ((CCodeExpression) prop.initializer.ccodenode);
+ cspec.add_argument ((CCodeExpression) get_ccodenode (prop.initializer));
} else {
cspec.add_argument (new CCodeConstant ("0U"));
}
@@ -1734,7 +1772,7 @@ public class Vala.GTypeModule : GErrorModule {
cspec.add_argument (new CCodeConstant ("G_MINLONG"));
cspec.add_argument (new CCodeConstant ("G_MAXLONG"));
if (prop.initializer != null) {
- cspec.add_argument ((CCodeExpression) prop.initializer.ccodenode);
+ cspec.add_argument ((CCodeExpression) get_ccodenode (prop.initializer));
} else {
cspec.add_argument (new CCodeConstant ("0L"));
}
@@ -1743,14 +1781,14 @@ public class Vala.GTypeModule : GErrorModule {
cspec.add_argument (new CCodeConstant ("0"));
cspec.add_argument (new CCodeConstant ("G_MAXULONG"));
if (prop.initializer != null) {
- cspec.add_argument ((CCodeExpression) prop.initializer.ccodenode);
+ cspec.add_argument ((CCodeExpression) get_ccodenode (prop.initializer));
} else {
cspec.add_argument (new CCodeConstant ("0UL"));
}
} else if (st.get_type_id () == "G_TYPE_BOOLEAN") {
cspec.call = new CCodeIdentifier ("g_param_spec_boolean");
if (prop.initializer != null) {
- cspec.add_argument ((CCodeExpression) prop.initializer.ccodenode);
+ cspec.add_argument ((CCodeExpression) get_ccodenode (prop.initializer));
} else {
cspec.add_argument (new CCodeConstant ("FALSE"));
}
@@ -1759,7 +1797,7 @@ public class Vala.GTypeModule : GErrorModule {
cspec.add_argument (new CCodeConstant ("G_MININT8"));
cspec.add_argument (new CCodeConstant ("G_MAXINT8"));
if (prop.initializer != null) {
- cspec.add_argument ((CCodeExpression) prop.initializer.ccodenode);
+ cspec.add_argument ((CCodeExpression) get_ccodenode (prop.initializer));
} else {
cspec.add_argument (new CCodeConstant ("0"));
}
@@ -1768,7 +1806,7 @@ public class Vala.GTypeModule : GErrorModule {
cspec.add_argument (new CCodeConstant ("0"));
cspec.add_argument (new CCodeConstant ("G_MAXUINT8"));
if (prop.initializer != null) {
- cspec.add_argument ((CCodeExpression) prop.initializer.ccodenode);
+ cspec.add_argument ((CCodeExpression) get_ccodenode (prop.initializer));
} else {
cspec.add_argument (new CCodeConstant ("0"));
}
@@ -1777,7 +1815,7 @@ public class Vala.GTypeModule : GErrorModule {
cspec.add_argument (new CCodeConstant ("-G_MAXFLOAT"));
cspec.add_argument (new CCodeConstant ("G_MAXFLOAT"));
if (prop.initializer != null) {
- cspec.add_argument ((CCodeExpression) prop.initializer.ccodenode);
+ cspec.add_argument ((CCodeExpression) get_ccodenode (prop.initializer));
} else {
cspec.add_argument (new CCodeConstant ("0.0F"));
}
@@ -1786,14 +1824,14 @@ public class Vala.GTypeModule : GErrorModule {
cspec.add_argument (new CCodeConstant ("-G_MAXDOUBLE"));
cspec.add_argument (new CCodeConstant ("G_MAXDOUBLE"));
if (prop.initializer != null) {
- cspec.add_argument ((CCodeExpression) prop.initializer.ccodenode);
+ cspec.add_argument ((CCodeExpression) get_ccodenode (prop.initializer));
} else {
cspec.add_argument (new CCodeConstant ("0.0"));
}
} else if (st.get_type_id () == "G_TYPE_GTYPE") {
cspec.call = new CCodeIdentifier ("g_param_spec_gtype");
if (prop.initializer != null) {
- cspec.add_argument ((CCodeExpression) prop.initializer.ccodenode);
+ cspec.add_argument ((CCodeExpression) get_ccodenode (prop.initializer));
} else {
cspec.add_argument (new CCodeConstant ("G_TYPE_NONE"));
}
@@ -2065,7 +2103,7 @@ public class Vala.GTypeModule : GErrorModule {
var ccomma = new CCodeCommaExpression ();
var temp_var = get_temp_variable (new CType ("GEnumValue*"), false, expr, false);
- temp_vars.add (temp_var);
+ emit_temp_var (temp_var);
var class_ref = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_ref"));
class_ref.add_argument (new CCodeIdentifier (ma.inner.value_type.get_type_id ()));
diff --git a/vala/valablock.vala b/vala/valablock.vala
index 64cbfaa..d7b35f2 100644
--- a/vala/valablock.vala
+++ b/vala/valablock.vala
@@ -165,6 +165,7 @@ public class Vala.Block : Symbol, Statement {
for (int j = 0; j < stmt_list.length; j++) {
if (stmt_list.get (j) == stmt) {
stmt_list.insert (j, new_stmt);
+ new_stmt.parent_node = this;
break;
}
}
@@ -173,6 +174,7 @@ public class Vala.Block : Symbol, Statement {
stmt_list.add (new_stmt);
stmt_list.add (stmt);
statement_list[i] = stmt_list;
+ new_stmt.parent_node = this;
}
}
}
@@ -184,11 +186,13 @@ public class Vala.Block : Symbol, Statement {
for (int j = 0; j < stmt_list.length; j++) {
if (stmt_list.get (j) == old_stmt) {
stmt_list.set (j, new_stmt);
+ new_stmt.parent_node = this;
break;
}
}
} else if (statement_list[i] == old_stmt) {
statement_list[i] = new_stmt;
+ new_stmt.parent_node = this;
break;
}
}
diff --git a/vala/valaexpression.vala b/vala/valaexpression.vala
index 23c01e2..eafb202 100644
--- a/vala/valaexpression.vala
+++ b/vala/valaexpression.vala
@@ -1,6 +1,6 @@
/* valaexpression.vala
*
- * Copyright (C) 2006-2009 Jürg Billeter
+ * Copyright (C) 2006-2010 Jürg Billeter
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -55,14 +55,6 @@ public abstract class Vala.Expression : CodeNode {
*/
public bool lvalue { get; set; }
- /**
- * Contains all temporary variables this expression requires for
- * execution.
- *
- * The code generator sets and uses them for memory management.
- */
- public ArrayList<LocalVariable> temp_vars;
-
private List<CCodeExpression> array_sizes;
public CCodeExpression? delegate_target { get; set; }
@@ -89,13 +81,6 @@ public abstract class Vala.Expression : CodeNode {
return false;
}
- public void add_temp_var (LocalVariable local) {
- if (temp_vars == null) {
- temp_vars = new ArrayList<LocalVariable> ();
- }
- temp_vars.add (local);
- }
-
/**
* Add an array size C code expression.
*/
diff --git a/vala/valamethod.vala b/vala/valamethod.vala
index a29ab05..bc6510e 100644
--- a/vala/valamethod.vala
+++ b/vala/valamethod.vala
@@ -233,6 +233,8 @@ public class Vala.Method : Symbol {
public bool is_async_callback { get; set; }
+ public int yield_count { get; set; }
+
private List<FormalParameter> parameters = new ArrayList<FormalParameter> ();
private string cname;
private string finish_name;
diff --git a/vala/valamethodcall.vala b/vala/valamethodcall.vala
index a493c56..23a109a 100644
--- a/vala/valamethodcall.vala
+++ b/vala/valamethodcall.vala
@@ -538,6 +538,7 @@ public class Vala.MethodCall : Expression {
error = true;
Report.error (source_reference, "yield expression not available outside async method");
}
+ analyzer.current_method.yield_count++;
}
if (m != null && m.coroutine && !is_yield_expression && ((MemberAccess) call).member_name != "end") {
// .begin call of async method, no error can happen here
diff --git a/vala/valayieldstatement.vala b/vala/valayieldstatement.vala
index be526a1..0fd6e34 100644
--- a/vala/valayieldstatement.vala
+++ b/vala/valayieldstatement.vala
@@ -75,6 +75,8 @@ public class Vala.YieldStatement : CodeNode, Statement {
error = yield_expression.error;
}
+ analyzer.current_method.yield_count++;
+
return !error;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]