}
foreach (LocalVariable local in temp_ref_vars) {
- ccode.add_expression (destroy_variable (local));
+ ccode.add_expression (destroy_local (local));
}
temp_ref_vars.clear ();
ccode.add_assignment (lhs, rhs);
foreach (LocalVariable local in temp_ref_vars) {
- ccode.add_expression (destroy_variable (local));
+ ccode.add_expression (destroy_local (local));
}
temp_ref_vars.clear ();
current_method.coroutine = false;
}
- ccode.add_expression (destroy_variable (local));
+ ccode.add_expression (destroy_local (local));
if (old_coroutine) {
current_method.coroutine = true;
m.coroutine = false;
}
- ccode.add_expression (destroy_variable (param));
+ ccode.add_expression (destroy_parameter (param));
if (old_coroutine) {
m.coroutine = true;
bool is_unowned_delegate = acc.value_parameter.variable_type is DelegateType && !acc.value_parameter.variable_type.value_owned;
if (requires_destroy (param_type) && !is_unowned_delegate) {
- ccode.add_expression (destroy_variable (acc.value_parameter));
+ ccode.add_expression (destroy_parameter (acc.value_parameter));
}
}
}
var local = local_vars[i];
local.active = false;
if (!local.unreachable && !local.floating && !local.captured && requires_destroy (local.variable_type)) {
- ccode.add_expression (destroy_variable (local));
+ ccode.add_expression (destroy_local (local));
}
}
var m = (Method) b.parent_symbol;
foreach (Parameter param in m.get_parameters ()) {
if (!param.captured && !param.ellipsis && requires_destroy (param.variable_type) && param.direction == ParameterDirection.IN) {
- ccode.add_expression (destroy_variable (param));
+ ccode.add_expression (destroy_parameter (param));
} else if (param.direction == ParameterDirection.OUT && !m.coroutine) {
return_out_parameter (param);
}
// logic in this method is temporarily duplicated in destroy_value
// apply changes to both methods
- public virtual CCodeExpression destroy_variable (Variable variable, CCodeExpression? inner = null) {
+ public virtual CCodeExpression destroy_variable (Variable variable, TargetValue target_lvalue) {
var type = variable.variable_type;
- var target_lvalue = get_variable_cvalue (variable, inner);
var cvar = get_cvalue_ (target_lvalue);
if (type is DelegateType) {
var array_type = (ArrayType) type;
if (requires_destroy (array_type.element_type) && !variable.no_array_length) {
CCodeExpression csizeexpr = null;
- TargetValue access_value = null;
- if (variable is LocalVariable) {
- access_value = load_local ((LocalVariable) variable);
- } else if (variable is Parameter) {
- access_value = load_parameter ((Parameter) variable);
- }
- bool first = true;
- for (int dim = 1; dim <= array_type.rank; dim++) {
- if (first) {
- csizeexpr = get_array_length_cvalue (access_value, dim);
- first = false;
- } else {
- csizeexpr = new CCodeBinaryExpression (CCodeBinaryOperator.MUL, csizeexpr, get_array_length_cvalue (access_value, dim));
+ if (variable.array_null_terminated) {
+ var len_call = new CCodeFunctionCall (new CCodeIdentifier ("_vala_array_length"));
+ len_call.add_argument (cvar);
+ csizeexpr = len_call;
+ } else if (variable.has_array_length_cexpr) {
+ csizeexpr = new CCodeConstant (variable.get_array_length_cexpr ());
+ } else {
+ bool first = true;
+ for (int dim = 1; dim <= array_type.rank; dim++) {
+ if (first) {
+ csizeexpr = get_array_length_cvalue (target_lvalue, dim);
+ first = false;
+ } else {
+ csizeexpr = new CCodeBinaryExpression (CCodeBinaryOperator.MUL, csizeexpr, get_array_length_cvalue (target_lvalue, dim));
+ }
}
}
return new CCodeConditionalExpression (cisnull, new CCodeConstant ("NULL"), cassign);
}
+ public CCodeExpression destroy_local (LocalVariable local) {
+ return destroy_variable (local, get_local_cvalue (local));
+ }
+
+ public CCodeExpression destroy_parameter (Parameter param) {
+ return destroy_variable (param, get_parameter_cvalue (param));
+ }
+
+ public CCodeExpression destroy_field (Field field, Expression? instance) {
+ return destroy_variable (field, get_field_cvalue (field, instance));
+ }
+
public CCodeExpression get_unref_expression (CCodeExpression cvar, DataType type, Expression? expr, bool is_macro_definition = false) {
- if (expr != null && (expr.symbol_reference is LocalVariable || expr.symbol_reference is Parameter)) {
- return destroy_variable ((Variable) expr.symbol_reference);
+ if (expr != null) {
+ if (expr.symbol_reference is LocalVariable) {
+ return destroy_local ((LocalVariable) expr.symbol_reference);
+ } else if (expr.symbol_reference is Parameter) {
+ return destroy_parameter ((Parameter) expr.symbol_reference);
+ }
}
var value = new GLibValue (type, cvar);
if (expr != null && expr.target_value != null) {
}
foreach (LocalVariable local in temp_ref_vars) {
- ccode.add_expression (destroy_variable (local));
+ ccode.add_expression (destroy_local (local));
}
if (full_expr_var != null) {
/* free temporary objects and handle errors */
foreach (LocalVariable local in temp_ref_vars) {
- ccode.add_expression (destroy_variable (local));
+ ccode.add_expression (destroy_local (local));
}
if (stmt.tree_can_fail && stmt.expression.tree_can_fail) {
for (int i = local_vars.size - 1; i >= 0; i--) {
var local = local_vars[i];
if (!local.unreachable && local.active && !local.floating && !local.captured && requires_destroy (local.variable_type)) {
- ccode.add_expression (destroy_variable (local));
+ ccode.add_expression (destroy_local (local));
}
}
private void append_param_free (Method m) {
foreach (Parameter param in m.get_parameters ()) {
if (!param.ellipsis && requires_destroy (param.variable_type) && param.direction == ParameterDirection.IN) {
- ccode.add_expression (destroy_variable (param));
+ ccode.add_expression (destroy_parameter (param));
}
}
}
if (param.variable_type.is_disposable ()){
ccode.add_else ();
- ccode.add_expression (destroy_variable (param));
+ ccode.add_expression (destroy_parameter (param));
}
ccode.close ();
}
}
- public virtual TargetValue get_variable_cvalue (Variable variable, CCodeExpression? inner = null) {
- assert_not_reached ();
- }
+ public abstract TargetValue get_local_cvalue (LocalVariable local);
+
+ public abstract TargetValue get_parameter_cvalue (Parameter param);
+
+ public abstract TargetValue get_field_cvalue (Field field, Expression? instance);
public virtual string get_delegate_target_cname (string delegate_cname) {
assert_not_reached ();
}
/* Returns lvalue access to the given local variable */
- public TargetValue get_local_cvalue (LocalVariable local) {
+ public override TargetValue get_local_cvalue (LocalVariable local) {
var result = new GLibValue (local.variable_type.copy ());
var array_type = local.variable_type as ArrayType;
}
/* Returns access values to the given parameter */
- public TargetValue get_parameter_cvalue (Parameter param) {
+ public override TargetValue get_parameter_cvalue (Parameter param) {
var result = new GLibValue (param.variable_type.copy ());
if (param.captured || is_in_coroutine ()) {
result.value_type.value_owned = true;
}
/* Returns lvalue access to the given field */
- public TargetValue get_field_cvalue (Field field, Expression? instance) {
+ public override TargetValue get_field_cvalue (Field field, Expression? instance) {
var result = new GLibValue (field.variable_type.copy ());
var array_type = field.variable_type as ArrayType;
return result;
}
- /* Returns lvalue access to the given symbol */
- public override TargetValue get_variable_cvalue (Variable variable, CCodeExpression? inner = null) {
- if (variable is LocalVariable) {
- return get_local_cvalue ((LocalVariable) variable);
- } else if (variable is Parameter) {
- return get_parameter_cvalue ((Parameter) variable);
- } else {
- assert_not_reached ();
- }
- }
-
/* Returns unowned access to the given local variable */
public override TargetValue load_local (LocalVariable local) {
return load_variable (local, get_local_cvalue (local));