* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@149223
138bc75d-0d04-0410-961f-
82ee72b054a4
+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.
+
2009-07-03 Jason Merrill <jason@redhat.com>
* cp-tree.h (struct lang_decl): Overhaul.
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 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;
};
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) \
#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)
/* 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)
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"
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
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
else if (code == PARM_DECL)
{
/* A function parameter used in a late-specified return type. */
- int index = parm_index (expr);
+ int index = DECL_PARM_INDEX (expr);
+ gcc_assert (index >= 1);
write_string ("fp");
if (index > 1)
write_unsigned_number (index - 2);
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;
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);
}
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. */
+ val = iterative_hash_object (DECL_PARM_INDEX (arg), val);
return iterative_hash_template_arg (TREE_TYPE (arg), val);
case TARGET_EXPR:
/* 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))
+ && DECL_PARM_INDEX (t1) == DECL_PARM_INDEX (t2))
return true;
else
return false;
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)
+ if ((TREE_CODE (decl) == FUNCTION_DECL
+ || TREE_CODE (decl) == VAR_DECL)
&& DECL_COMDAT (decl))
return lk_external;
+2009-07-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/40619
+ * g++.dg/cpp0x/auto16.C: New.
+
2009-07-03 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR fortran/40638
--- /dev/null
+// 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)> {}