1999-08-26 Mark Mitchell <mark@codesourcery.com>
+ * cp-tree.def (AGGR_INIT_VIA_CTOR_P): New macro.
+ * tree.c (build_cplus_new): Set it.
+ * expr.c (cplus_expand_expr): Use it.
+
* decl.c (store_parm_decls): Reset immediate_size_expand.
(finish_function): Likewise.
LOCAL_BINDING_P (in CPLUS_BINDING)
ICS_USER_FLAG (in _CONV)
CLEANUP_P (in TRY_BLOCK)
+ AGGR_INIT_VIA_CTOR_P (in AGGR_INIT_EXPR)
1: IDENTIFIER_VIRTUAL_P.
TI_PENDING_TEMPLATE_FLAG.
TEMPLATE_PARMS_FOR_INLINE.
#define DELETE_EXPR_USE_VEC(NODE) TREE_LANG_FLAG_1 (NODE)
#define LOOKUP_EXPR_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE)
+/* Nonzero if this AGGR_INIT_EXPR provides for initialization via a
+ constructor call, rather than an ordinary function call. */
+#define AGGR_INIT_VIA_CTOR_P(NODE) TREE_LANG_FLAG_0 (NODE)
+
/* The TYPE_MAIN_DECL for a class template type is a TYPE_DECL, not a
TEMPLATE_DECL. This macro determines whether or not a given class
type is really a template type, as opposed to an instantiation or
initialization. It is left here to show the choices that
exist for C++. */
- if (TREE_CODE (func) == ADDR_EXPR
- && TREE_CODE (TREE_OPERAND (func, 0)) == FUNCTION_DECL
- && DECL_CONSTRUCTOR_P (TREE_OPERAND (func, 0)))
+ if (AGGR_INIT_VIA_CTOR_P (exp))
{
type = build_pointer_type (type);
/* Don't clobber a value that might be part of a default
tree type;
tree init;
{
+ tree fn;
tree slot;
tree rval;
slot = build (VAR_DECL, type);
DECL_ARTIFICIAL (slot) = 1;
layout_decl (slot, 0);
- rval = build (AGGR_INIT_EXPR, type,
- TREE_OPERAND (init, 0), TREE_OPERAND (init, 1), slot);
+
+ /* We split the CALL_EXPR into its function and its arguments here.
+ Then, in expand_expr, we put them back together. The reason for
+ this is that this expression might be a default argument
+ expression. In that case, we need a new temporary every time the
+ expression is used. That's what break_out_target_exprs does; it
+ replaces every AGGR_INIT_EXPR with a copy that uses a fresh
+ temporary slot. Then, expand_expr builds up a call-expression
+ using the new slot. */
+ fn = TREE_OPERAND (init, 0);
+ rval = build (AGGR_INIT_EXPR, type, fn, TREE_OPERAND (init, 1), slot);
TREE_SIDE_EFFECTS (rval) = 1;
+ AGGR_INIT_VIA_CTOR_P (rval)
+ = (TREE_CODE (fn) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
+ && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0)));
rval = build (TARGET_EXPR, type, slot, rval, NULL_TREE, NULL_TREE);
TREE_SIDE_EFFECTS (rval) = 1;