This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for c++/40619
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Sat, 04 Jul 2009 00:32:23 -0400
- Subject: C++ PATCH for c++/40619
So my last patch makes it straightforward to add the parm index to
DECL_LANG_SPECIFIC; there's really no way to figure out the index when
we're looking at a late-specified return type without specifically
associating it with the parm decl itself.
Adding DECL_LANG_SPECIFIC to parms cuts the memory savings from the last
patch in half.
Tested x86_64-pc-linux-gnu, applied to trunk. The last patch is
unsuitable for 4.4, so I'm going to do something different there.
2009-07-04 Jason Merrill <jason@redhat.com>
PR c++/40619
* cp-tree.h (struct lang_decl_parm): New.
(struct lang_decl): Add it.
(LANG_DECL_PARM_CHECK): New.
(DECL_PARM_INDEX): New.
* decl2.c (parm_index): Remove.
* lex.c (retrofit_lang_decl): Handle parms.
(cxx_dup_lang_specific_decl): Likewise.
* mangle.c (write_expression): Adjust.
* tree.c (cp_tree_equal): Adjust.
(decl_linkage): Only check DECL_COMDAT for functions and variables.
* parser.c (cp_parser_parameter_declaration_list): Set
DECL_PARM_INDEX.
* pt.c (iterative_hash_template_arg): Hash it.
*** gcc/cp/cp-tree.h
--- gcc/cp/cp-tree.h 2009-07-03 20:53:49.503723830 -0400
*************** struct GTY(()) lang_decl_ns {
*** 1675,1680 ****
--- 1675,1687 ----
struct cp_binding_level *level;
};
+ /* DECL_LANG_SPECIFIC for parameters. */
+
+ struct GTY(()) lang_decl_parm {
+ struct lang_decl_base base;
+ int index;
+ };
+
/* DECL_LANG_SPECIFIC for all types. It would be nice to just make this a
union rather than a struct containing a union as its only field, but
tree.h declares it as a struct. */
*************** struct GTY(()) lang_decl {
*** 1685,1690 ****
--- 1692,1698 ----
struct lang_decl_min GTY((tag ("0"))) min;
struct lang_decl_fn GTY ((tag ("1"))) fn;
struct lang_decl_ns GTY((tag ("2"))) ns;
+ struct lang_decl_parm GTY((tag ("3"))) parm;
} u;
};
*************** struct GTY(()) lang_decl {
*** 1715,1720 ****
--- 1723,1734 ----
lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \
<->u.ns; })
+ #define LANG_DECL_PARM_CHECK(NODE) __extension__ \
+ ({ struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE); \
+ if (TREE_CODE (NODE) != PARM_DECL) \
+ lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \
+ <->u.parm; })
+
#define LANG_DECL_U2_CHECK(NODE, TF) __extension__ \
({ struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE); \
if (lt->u.base.u2sel != TF) \
*************** struct GTY(()) lang_decl {
*** 1732,1737 ****
--- 1746,1754 ----
#define LANG_DECL_NS_CHECK(NODE) \
(&DECL_LANG_SPECIFIC (NODE)->u.ns)
+ #define LANG_DECL_PARM_CHECK(NODE) \
+ (&DECL_LANG_SPECIFIC (NODE)->u.parm)
+
#define LANG_DECL_U2_CHECK(NODE, TF) \
(&DECL_LANG_SPECIFIC (NODE)->u.min.u2)
*************** struct GTY(()) lang_decl {
*** 1847,1852 ****
--- 1864,1874 ----
/* Discriminator for name mangling. */
#define DECL_DISCRIMINATOR(NODE) (LANG_DECL_U2_CHECK (NODE, 1)->discriminator)
+ /* The index of a user-declared parameter in its function, starting at 1.
+ All artificial parameters will have index 0. */
+ #define DECL_PARM_INDEX(NODE) \
+ (LANG_DECL_PARM_CHECK (NODE)->index)
+
/* Nonzero if the VTT parm has been added to NODE. */
#define DECL_HAS_VTT_PARM_P(NODE) \
(LANG_DECL_FN_CHECK (NODE)->has_vtt_parm_p)
*** gcc/cp/decl2.c
--- gcc/cp/decl2.c 2009-07-03 20:46:00.755723720 -0400
*************** mark_used (tree decl)
*** 3910,3936 ****
processing_template_decl = saved_processing_template_decl;
}
- /* Given function PARM_DECL PARM, return its index in the function's list
- of parameters, beginning with 1. */
-
- int
- parm_index (tree parm)
- {
- int index;
- tree arg;
-
- for (index = 1, arg = DECL_ARGUMENTS (DECL_CONTEXT (parm));
- arg;
- ++index, arg = TREE_CHAIN (arg))
- {
- if (DECL_NAME (parm) == DECL_NAME (arg))
- break;
- if (DECL_ARTIFICIAL (arg))
- --index;
- }
-
- gcc_assert (arg);
- return index;
- }
-
#include "gt-cp-decl2.h"
--- 3910,3913 ----
*** gcc/cp/lex.c
--- gcc/cp/lex.c 2009-07-03 20:53:32.030724153 -0400
*************** retrofit_lang_decl (tree t)
*** 538,543 ****
--- 538,545 ----
sel = 1, size = sizeof (struct lang_decl_fn);
else if (TREE_CODE (t) == NAMESPACE_DECL)
sel = 2, size = sizeof (struct lang_decl_ns);
+ else if (TREE_CODE (t) == PARM_DECL)
+ sel = 3, size = sizeof (struct lang_decl_parm);
else if (LANG_DECL_HAS_MIN (t))
sel = 0, size = sizeof (struct lang_decl_min);
else
*************** cxx_dup_lang_specific_decl (tree node)
*** 577,582 ****
--- 579,586 ----
size = sizeof (struct lang_decl_fn);
else if (TREE_CODE (node) == NAMESPACE_DECL)
size = sizeof (struct lang_decl_ns);
+ else if (TREE_CODE (node) == PARM_DECL)
+ size = sizeof (struct lang_decl_parm);
else if (LANG_DECL_HAS_MIN (node))
size = sizeof (struct lang_decl_min);
else
*** gcc/cp/mangle.c
--- gcc/cp/mangle.c 2009-07-03 23:50:48.023724261 -0400
*************** write_expression (tree expr)
*** 2199,2205 ****
else if (code == PARM_DECL)
{
/* A function parameter used in a late-specified return type. */
! int index = parm_index (expr);
write_string ("fp");
if (index > 1)
write_unsigned_number (index - 2);
--- 2199,2206 ----
else if (code == PARM_DECL)
{
/* A function parameter used in a late-specified return type. */
! int index = DECL_PARM_INDEX (expr);
! gcc_assert (index >= 1);
write_string ("fp");
if (index > 1)
write_unsigned_number (index - 2);
*** gcc/cp/parser.c
--- gcc/cp/parser.c 2009-07-03 23:49:38.303723188 -0400
*************** cp_parser_parameter_declaration_list (cp
*** 14111,14116 ****
--- 14111,14117 ----
tree parameters = NULL_TREE;
tree *tail = ¶meters;
bool saved_in_unbraced_linkage_specification_p;
+ int index = 0;
/* Assume all will go well. */
*is_error = false;
*************** cp_parser_parameter_declaration_list (cp
*** 14162,14167 ****
--- 14163,14174 ----
if (DECL_NAME (decl))
decl = pushdecl (decl);
+ if (decl != error_mark_node)
+ {
+ retrofit_lang_decl (decl);
+ DECL_PARM_INDEX (decl) = ++index;
+ }
+
/* Add the new parameter to the list. */
*tail = build_tree_list (parameter->default_argument, decl);
tail = &TREE_CHAIN (*tail);
*** gcc/cp/pt.c
--- gcc/cp/pt.c 2009-07-03 20:47:33.947472947 -0400
*************** iterative_hash_template_arg (tree arg, h
*** 1488,1496 ****
}
case PARM_DECL:
! /* I tried hashing parm_index as well, but in some cases we get
! called too soon for that to work, so just hash the type and let
! lookup check that the index matches. */
return iterative_hash_template_arg (TREE_TYPE (arg), val);
case TARGET_EXPR:
--- 1488,1494 ----
}
case PARM_DECL:
! val = iterative_hash_object (DECL_PARM_INDEX (arg), val);
return iterative_hash_template_arg (TREE_TYPE (arg), val);
case TARGET_EXPR:
*** gcc/cp/tree.c
--- gcc/cp/tree.c 2009-07-03 20:57:55.886722412 -0400
*************** cp_tree_equal (tree t1, tree t2)
*** 1997,2003 ****
/* For comparing uses of parameters in late-specified return types
with an out-of-class definition of the function. */
if (same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
! && parm_index (t1) == parm_index (t2))
return true;
else
return false;
--- 1997,2003 ----
/* For comparing uses of parameters in late-specified return types
with an out-of-class definition of the function. */
if (same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
! && DECL_PARM_INDEX (t1) == DECL_PARM_INDEX (t2))
return true;
else
return false;
*************** decl_linkage (tree decl)
*** 2723,2729 ****
template instantiations have internal linkage (in the object
file), but the symbols should still be treated as having external
linkage from the point of view of the language. */
! if (TREE_CODE (decl) != TYPE_DECL && DECL_LANG_SPECIFIC (decl)
&& DECL_COMDAT (decl))
return lk_external;
--- 2723,2730 ----
template instantiations have internal linkage (in the object
file), but the symbols should still be treated as having external
linkage from the point of view of the language. */
! if ((TREE_CODE (decl) == FUNCTION_DECL
! || TREE_CODE (decl) == VAR_DECL)
&& DECL_COMDAT (decl))
return lk_external;
*** gcc/testsuite/g++.dg/cpp0x/auto16.C
--- gcc/testsuite/g++.dg/cpp0x/auto16.C 2009-07-03 21:04:23.919510590 -0400
***************
*** 0 ****
--- 1,7 ----
+ // PR c++/40619
+ // { dg-options "-std=c++0x" }
+
+ template<typename U> struct X {};
+
+ template<typename T> auto f(T t) -> X<decltype(t+1)> {}
+ template<typename T> auto g(T t) -> X<decltype(t+1)> {}