constructor. */
/* The AGGR_INIT_EXPR tweaking below breaks in templates. */
- gcc_assert (!processing_template_decl || SCALAR_TYPE_P (type));
+ gcc_assert (!processing_template_decl
+ || (SCALAR_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE));
if (CLASS_TYPE_P (type))
{
tree ctor = build_special_member_call
(NULL_TREE, complete_ctor_identifier,
NULL, type, LOOKUP_NORMAL, complain);
+ ctor = build_aggr_init_expr (type, ctor, complain);
if (ctor != error_mark_node)
- {
- ctor = build_aggr_init_expr (type, ctor, complain);
- AGGR_INIT_ZERO_FIRST (ctor) = 1;
- }
+ AGGR_INIT_ZERO_FIRST (ctor) = 1;
return ctor;
}
}
return build_zero_init (type, NULL_TREE, /*static_storage_p=*/false);
}
+/* Initialize current class with INIT, a TREE_LIST of
+ arguments for a target constructor. If TREE_LIST is void_type_node,
+ an empty initializer list was given. */
+
+static void
+perform_target_ctor (tree init)
+{
+ tree decl = current_class_ref;
+ tree type = current_class_type;
+
+ finish_expr_stmt (build_aggr_init (decl, init, LOOKUP_NORMAL,
+ tf_warning_or_error));
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+ {
+ tree expr = build_delete (type, decl, sfk_complete_destructor,
+ LOOKUP_NORMAL
+ |LOOKUP_NONVIRTUAL
+ |LOOKUP_DESTRUCTOR,
+ 0, tf_warning_or_error);
+ if (expr != error_mark_node)
+ finish_eh_cleanup (expr);
+ }
+}
+
/* Initialize MEMBER, a FIELD_DECL, with INIT, a TREE_LIST of
arguments. If TREE_LIST is void_type_node, an empty initializer
list was given; if NULL_TREE no initializer was given. */
}
}
+ if (init == error_mark_node)
+ return;
+
/* Effective C++ rule 12 requires that all data members be
initialized. */
if (warn_ecpp && init == NULL_TREE && TREE_CODE (type) != ARRAY_TYPE)
init = digest_init (type, init, tf_warning_or_error);
if (init == error_mark_node)
return;
- /* Use 'this' as the decl, as it has the lifetime we want. */
+ /* A FIELD_DECL doesn't really have a suitable lifetime, but
+ make_temporary_var_for_ref_to_temp will treat it as automatic and
+ set_up_extended_ref_temp wants to use the decl in a warning. */
init = extend_ref_init_temps (member, init, &cleanups);
if (TREE_CODE (type) == ARRAY_TYPE
&& TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (type)))
if (!COMPLETE_TYPE_P (current_class_type))
return;
+ if (mem_inits
+ && TYPE_P (TREE_PURPOSE (mem_inits))
+ && same_type_p (TREE_PURPOSE (mem_inits), current_class_type))
+ {
+ /* Delegating constructor. */
+ gcc_assert (TREE_CHAIN (mem_inits) == NULL_TREE);
+ perform_target_ctor (TREE_VALUE (mem_inits));
+ return;
+ }
+
if (DECL_DEFAULTED_FN (current_function_decl))
flags |= LOOKUP_DEFAULTED;
tree virtual_binfo;
int i;
- if (current_template_parms)
- return basetype;
+ if (same_type_p (basetype, current_class_type)
+ || current_template_parms)
+ return basetype;
class_binfo = TYPE_BINFO (current_class_type);
direct_binfo = NULL_TREE;
else
parms = make_tree_vector_single (init);
- if (true_exp == exp)
- ctor_name = complete_ctor_identifier;
- else
- ctor_name = base_ctor_identifier;
+ if (exp == current_class_ref && current_function_decl
+ && DECL_HAS_IN_CHARGE_PARM_P (current_function_decl))
+ {
+ /* Delegating constructor. */
+ tree complete;
+ tree base;
+ tree elt; unsigned i;
+
+ /* Unshare the arguments for the second call. */
+ VEC(tree,gc) *parms2 = make_tree_vector ();
+ FOR_EACH_VEC_ELT (tree, parms, i, elt)
+ {
+ elt = break_out_target_exprs (elt);
+ VEC_safe_push (tree, gc, parms2, elt);
+ }
+ complete = build_special_member_call (exp, complete_ctor_identifier,
+ &parms2, binfo, flags,
+ complain);
+ complete = fold_build_cleanup_point_expr (void_type_node, complete);
+ release_tree_vector (parms2);
- rval = build_special_member_call (exp, ctor_name, &parms, binfo, flags,
- complain);
+ base = build_special_member_call (exp, base_ctor_identifier,
+ &parms, binfo, flags,
+ complain);
+ base = fold_build_cleanup_point_expr (void_type_node, base);
+ rval = build3 (COND_EXPR, void_type_node,
+ build2 (EQ_EXPR, boolean_type_node,
+ current_in_charge_parm, integer_zero_node),
+ base,
+ complete);
+ }
+ else
+ {
+ if (true_exp == exp)
+ ctor_name = complete_ctor_identifier;
+ else
+ ctor_name = base_ctor_identifier;
+ rval = build_special_member_call (exp, ctor_name, &parms, binfo, flags,
+ complain);
+ }
if (parms != NULL)
release_tree_vector (parms);