This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH to aggregate returns
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 20 Aug 2003 23:18:51 -0400
- Subject: C++ PATCH to aggregate returns
This patch does three things:
1) breaks out most of simplify_aggr_init_exprs_r into a separate function.
2) corrects the type of the return slot argument so we don't need to adjust
it in the inliner.
3) avoids clobbering the identity of a variable initialized by an inline
function.
These are all primarily for the benefit of tree-ssa, but are also
applicable to the trunk.
Tested x86_64-pc-linux-gnu, applied to trunk and tree-ssa.
2003-08-20 Jason Merrill <jason@redhat.com>
* semantics.c (simplify_aggr_init_expr): Split out from
simplify_aggr_init_exprs_r. Convert slot address to match
the return type.
* cp-tree.h: Declare it.
* tree.c (cp_copy_res_decl_for_inlining): Don't clobber the
DECL_NAME of a user variable.
*** cp-tree.h.~1~ Wed Aug 20 03:06:40 2003
--- cp-tree.h Wed Aug 20 20:22:17 2003
*************** extern tree check_template_template_defa
*** 4147,4152 ****
--- 4147,4153 ----
extern void expand_or_defer_fn (tree);
extern void check_accessibility_of_qualified_id (tree, tree, tree);
extern tree finish_qualified_id_expr (tree, tree, bool, bool);
+ extern void simplify_aggr_init_expr (tree *);
/* in tree.c */
extern void lang_check_failed (const char *, int,
*** semantics.c.~1~ Wed Aug 20 14:00:08 2003
--- semantics.c Wed Aug 20 20:22:17 2003
*************** cp_expand_stmt (tree t)
*** 2713,2749 ****
static tree
simplify_aggr_init_exprs_r (tree* tp,
! int* walk_subtrees ATTRIBUTE_UNUSED ,
! void* data ATTRIBUTE_UNUSED )
{
- tree aggr_init_expr;
- tree call_expr;
- tree fn;
- tree args;
- tree slot;
- tree type;
- enum style_t { ctor, arg, pcc } style;
-
- aggr_init_expr = *tp;
/* We don't need to walk into types; there's nothing in a type that
needs simplification. (And, furthermore, there are places we
actively don't want to go. For example, we don't want to wander
into the default arguments for a FUNCTION_DECL that appears in a
CALL_EXPR.) */
! if (TYPE_P (aggr_init_expr))
{
*walk_subtrees = 0;
return NULL_TREE;
}
/* Only AGGR_INIT_EXPRs are interesting. */
! else if (TREE_CODE (aggr_init_expr) != AGGR_INIT_EXPR)
return NULL_TREE;
/* Form an appropriate CALL_EXPR. */
! fn = TREE_OPERAND (aggr_init_expr, 0);
! args = TREE_OPERAND (aggr_init_expr, 1);
! slot = TREE_OPERAND (aggr_init_expr, 2);
! type = TREE_TYPE (aggr_init_expr);
if (AGGR_INIT_VIA_CTOR_P (aggr_init_expr))
style = ctor;
--- 2713,2758 ----
static tree
simplify_aggr_init_exprs_r (tree* tp,
! int* walk_subtrees,
! void* data ATTRIBUTE_UNUSED)
{
/* We don't need to walk into types; there's nothing in a type that
needs simplification. (And, furthermore, there are places we
actively don't want to go. For example, we don't want to wander
into the default arguments for a FUNCTION_DECL that appears in a
CALL_EXPR.) */
! if (TYPE_P (*tp))
{
*walk_subtrees = 0;
return NULL_TREE;
}
/* Only AGGR_INIT_EXPRs are interesting. */
! else if (TREE_CODE (*tp) != AGGR_INIT_EXPR)
return NULL_TREE;
+ simplify_aggr_init_expr (tp);
+
+ /* Keep iterating. */
+ return NULL_TREE;
+ }
+
+ /* Replace the AGGR_INIT_EXPR at *TP with an equivalent CALL_EXPR. This
+ function is broken out from the above for the benefit of the tree-ssa
+ project. */
+
+ void
+ simplify_aggr_init_expr (tree *tp)
+ {
+ tree aggr_init_expr = *tp;
+
/* Form an appropriate CALL_EXPR. */
! tree fn = TREE_OPERAND (aggr_init_expr, 0);
! tree args = TREE_OPERAND (aggr_init_expr, 1);
! tree slot = TREE_OPERAND (aggr_init_expr, 2);
! tree type = TREE_TYPE (aggr_init_expr);
!
! tree call_expr;
! enum style_t { ctor, arg, pcc } style;
if (AGGR_INIT_VIA_CTOR_P (aggr_init_expr))
style = ctor;
*************** simplify_aggr_init_exprs_r (tree* tp,
*** 2762,2776 ****
{
/* Pass the address of the slot. If this is a constructor, we
replace the first argument; otherwise, we tack on a new one. */
if (style == ctor)
args = TREE_CHAIN (args);
cxx_mark_addressable (slot);
! args = tree_cons (NULL_TREE,
! build1 (ADDR_EXPR,
! build_pointer_type (TREE_TYPE (slot)),
! slot),
! args);
}
call_expr = build (CALL_EXPR,
--- 2771,2796 ----
{
/* Pass the address of the slot. If this is a constructor, we
replace the first argument; otherwise, we tack on a new one. */
+ tree addr;
+
if (style == ctor)
args = TREE_CHAIN (args);
cxx_mark_addressable (slot);
! addr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (slot)), slot);
! if (style == arg)
! {
! /* The return type might have different cv-quals from the slot. */
! tree fntype = TREE_TYPE (TREE_TYPE (fn));
! #ifdef ENABLE_CHECKING
! if (TREE_CODE (fntype) != FUNCTION_TYPE
! && TREE_CODE (fntype) != METHOD_TYPE)
! abort ();
! #endif
! addr = convert (build_pointer_type (TREE_TYPE (fntype)), addr);
! }
!
! args = tree_cons (NULL_TREE, addr, args);
}
call_expr = build (CALL_EXPR,
*************** simplify_aggr_init_exprs_r (tree* tp,
*** 2801,2809 ****
/* Replace the AGGR_INIT_EXPR with the CALL_EXPR. */
TREE_CHAIN (call_expr) = TREE_CHAIN (aggr_init_expr);
*tp = call_expr;
-
- /* Keep iterating. */
- return NULL_TREE;
}
/* Emit all thunks to FN that should be emitted when FN is emitted. */
--- 2821,2826 ----
*** tree.c.~1~ Sun Aug 10 11:10:35 2003
--- tree.c Wed Aug 20 20:22:17 2003
*************** cp_copy_res_decl_for_inlining (tree resu
*** 2193,2199 ****
/* We have a named return value; copy the name and source
position so we can get reasonable debugging information, and
register the return variable as its equivalent. */
! if (TREE_CODE (var) == VAR_DECL)
{
DECL_NAME (var) = DECL_NAME (nrv);
DECL_SOURCE_LOCATION (var) = DECL_SOURCE_LOCATION (nrv);
--- 2193,2202 ----
/* We have a named return value; copy the name and source
position so we can get reasonable debugging information, and
register the return variable as its equivalent. */
! if (TREE_CODE (var) == VAR_DECL
! /* But not if we're initializing a variable from the
! enclosing function which already has its own name. */
! && DECL_NAME (var) == NULL_TREE)
{
DECL_NAME (var) = DECL_NAME (nrv);
DECL_SOURCE_LOCATION (var) = DECL_SOURCE_LOCATION (nrv);