return get_ccode_attribute(sym).real_name;
}
+ public static string get_ccode_constructv_name (CreationMethod m) {
+ const string infix = "constructv";
+
+ var parent = m.parent_symbol as Class;
+
+ if (m.name == ".new") {
+ return "%s%s".printf (get_ccode_lower_case_prefix (parent), infix);
+ } else {
+ return "%s%s_%s".printf (get_ccode_lower_case_prefix (parent), infix, m.name);
+ }
+ }
+
public static string get_ccode_vfunc_name (Method m) {
return get_ccode_attribute(m).vfunc_name;
}
// Enum.VALUE.to_string()
var en = (Enum) ma.inner.value_type.data_type;
ccall.call = new CCodeIdentifier (generate_enum_tostring_function (en));
+ } else if (expr.is_constructv_chainup) {
+ ccall.call = new CCodeIdentifier (get_ccode_constructv_name ((CreationMethod) m));
}
} else if (itype is SignalType) {
var sig_type = (SignalType) itype;
var cl = (Class) ((ObjectType) itype).type_symbol;
m = cl.default_construction_method;
generate_method_declaration (m, cfile);
- ccall = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_real_name (m)));
+ var real_name = get_ccode_real_name (m);
+ if (expr.is_constructv_chainup) {
+ real_name = get_ccode_constructv_name ((CreationMethod) m);
+ }
+ ccall = new CCodeFunctionCall (new CCodeIdentifier (real_name));
} else if (itype is StructValueType) {
// constructor
var st = (Struct) ((StructValueType) itype).type_symbol;
* except when using printf-style arguments */
if (m == null) {
in_arg_map.set (get_param_pos (-1, true), new CCodeConstant ("NULL"));
- } else if (!m.printf_format && !m.scanf_format && get_ccode_sentinel (m) != "") {
+ } else if (!m.printf_format && !m.scanf_format && get_ccode_sentinel (m) != "" && !expr.is_constructv_chainup) {
in_arg_map.set (get_param_pos (-1, true), new CCodeConstant (get_ccode_sentinel (m)));
}
}
if (m.is_variadic ()) {
// _constructv function
- function = new CCodeFunction (get_constructv_name ((CreationMethod) m));
+ function = new CCodeFunction (get_ccode_constructv_name ((CreationMethod) m));
cparam_map = new HashMap<int,CCodeParameter> (direct_hash, direct_equal);
generate_cparameters (m, decl_space, cparam_map, function);
}
}
- private string get_constructv_name (CreationMethod m) {
- const string infix = "constructv";
-
- var parent = m.parent_symbol as Class;
-
- if (m.name == ".new") {
- return "%s%s".printf (CCodeBaseModule.get_ccode_lower_case_prefix (parent), infix);
- } else {
- return "%s%s_%s".printf (CCodeBaseModule.get_ccode_lower_case_prefix (parent), infix, m.name);
- }
- }
-
void register_plugin_types (Symbol sym, Set<Symbol> registered_types) {
var ns = sym as Namespace;
var cl = sym as Class;
public override void visit_method (Method m) {
string real_name = get_ccode_real_name (m);
if (m is CreationMethod && m.is_variadic ()) {
- real_name = get_constructv_name ((CreationMethod) m);
+ real_name = get_ccode_constructv_name ((CreationMethod) m);
}
push_context (new EmitContext (m));
push_function (vfunc);
- string constructor = (m.is_variadic ()) ? get_constructv_name (m) : get_ccode_real_name (m);
+ string constructor = (m.is_variadic ()) ? get_ccode_constructv_name (m) : get_ccode_real_name (m);
var vcall = new CCodeFunctionCall (new CCodeIdentifier (constructor));
if (self_as_first_parameter) {
delegates/bug638415.vala \
delegates/bug639751.vala \
delegates/bug703804.vala \
+ objects/chainup.vala \
objects/classes.vala \
objects/fields.vala \
objects/interfaces.vala \
--- /dev/null
+class FooBase {
+ public int bar;
+
+ public FooBase (int _, ...) {
+ va_list v = va_list ();
+ bar = v.arg ();
+ }
+
+ public FooBase.baz (int _, ...) {
+ va_list v = va_list ();
+ this (_, v);
+ }
+}
+
+class Foo : FooBase {
+ public Foo (int _, ...) {
+ va_list v = va_list ();
+ base (_, v);
+ }
+
+ public Foo.baz (int _, ...) {
+ va_list v = va_list ();
+ base.baz (_, v);
+ }
+
+ public Foo.qux (int _, ...) {
+ va_list v = va_list ();
+ this.baz (_, v);
+ }
+}
+
+void main () {
+ var foo = new Foo (0, 10);
+ assert (foo.bar == 10);
+ foo = new Foo.baz (0, 20);
+ assert (foo.bar == 20);
+ foo = new Foo.qux (0, 30);
+ assert (foo.bar == 30);
+}
/**
* Specifies the default construction method.
*/
- public Method default_construction_method { get; set; }
+ public CreationMethod default_construction_method { get; set; }
/**
* Specifies the instance constructor.
}
if (m is CreationMethod) {
if (m.name == null) {
- default_construction_method = m;
+ default_construction_method = (CreationMethod) m;
m.name = ".new";
}
public bool is_assert { get; private set; }
+ /**
+ * Whether this chain up uses the constructv function with va_list.
+ */
+ public bool is_constructv_chainup { get; private set; }
+
public Expression _call;
private List<Expression> argument_list = new ArrayList<Expression> ();
var mtype = call.value_type;
+ CreationMethod base_cm = null;
+
if (mtype is ObjectType || call.symbol_reference == context.analyzer.object_type) {
// constructor chain-up
var cm = context.analyzer.find_current_method () as CreationMethod;
if (mtype is ObjectType) {
var otype = (ObjectType) mtype;
var cl = (Class) otype.type_symbol;
- var base_cm = cl.default_construction_method;
+ base_cm = cl.default_construction_method;
if (base_cm == null) {
error = true;
Report.error (source_reference, "chain up to `%s' not supported".printf (cl.get_full_name ()));
}
cm.chain_up = true;
- var base_cm = (CreationMethod) call.symbol_reference;
+ base_cm = (CreationMethod) call.symbol_reference;
if (!base_cm.has_construct_function) {
error = true;
Report.error (source_reference, "chain up to `%s' not supported".printf (base_cm.get_full_name ()));
return false;
}
+ /* Check for constructv chain up */
+ if (base_cm != null && base_cm.is_variadic () && args.size == base_cm.get_parameters ().size) {
+ var this_last_arg = args[args.size-1];
+ if (this_last_arg.value_type is StructValueType && this_last_arg.value_type.data_type == context.analyzer.va_list_type.data_type) {
+ is_constructv_chainup = true;
+ }
+ }
+
if (may_throw) {
if (parent_node is LocalVariable || parent_node is ExpressionStatement) {
// simple statements, no side effects after method call
public DataType unichar_type;
public DataType double_type;
public DataType type_type;
+ public DataType va_list_type;
public Class object_type;
public StructValueType gvalue_type;
public ObjectType gvariant_type;
size_t_type = new IntegerType ((Struct) root_symbol.scope.lookup ("size_t"));
ssize_t_type = new IntegerType ((Struct) root_symbol.scope.lookup ("ssize_t"));
double_type = new FloatingType ((Struct) root_symbol.scope.lookup ("double"));
+ va_list_type = new StructValueType ((Struct) root_symbol.scope.lookup ("va_list"));
var unichar_struct = (Struct) root_symbol.scope.lookup ("unichar");
if (unichar_struct != null) {