aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>1999-09-29 17:24:21 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1999-09-29 17:24:21 +0000
commitb5ac18ea8c1365118cfee58840ff738b0de67b5e (patch)
tree775f4aa955fdfd22ef0cbf7763b5945fd4ab87e1 /gcc
parent0acbb8d94d6268bff84fb87e6e7e25768b58911f (diff)
downloadgcc-b5ac18ea8c1365118cfee58840ff738b0de67b5e.zip
gcc-b5ac18ea8c1365118cfee58840ff738b0de67b5e.tar.gz
gcc-b5ac18ea8c1365118cfee58840ff738b0de67b5e.tar.bz2
cp-tree.h (TMPL_ARGS_HAVE_MULTIPLE_LEVELS): Move here from pt.c.
* cp-tree.h (TMPL_ARGS_HAVE_MULTIPLE_LEVELS): Move here from pt.c. (TMPL_ARGS_DEPTH, TMPL_ARGS_LEVEL, SET_TMPL_ARGS_LEVEL): Likewise. (TMPL_ARG, SET_TMPL_ARG, NUM_TMPL_ARGS, TMPL_PARMS_DEPTH): Likewise. * error.c (dump_template_bindings): Remove unused parameter. Handle multiple levels of template parameters. (dump_template_decl): Use `parms', not `args', for template parameters. Fix thinko. (dump_function_decl): Use DECL_TEMPLATE_INSTANTIATION. Don't pass flags to dump_template_bindings. * pt.c (TMPL_ARGS_HAVE_MULTIPLE_LEVELS): Move to cp-tree.h. (TMPL_ARGS_DEPTH, TMPL_ARGS_LEVEL, SET_TMPL_ARGS_LEVEL): Likewise. (TMPL_ARG, SET_TMPL_ARG, NUM_TMPL_ARGS, TMPL_PARMS_DEPTH): Likewise. (tsubst_copy): Clarify variable name. (most_general_template): Robustify. From-SVN: r29708
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog17
-rw-r--r--gcc/cp/cp-tree.h60
-rw-r--r--gcc/cp/error.c64
-rw-r--r--gcc/cp/pt.c70
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/error1.C19
5 files changed, 135 insertions, 95 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 32d62b0..56d78d4 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,20 @@
+1999-09-29 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (TMPL_ARGS_HAVE_MULTIPLE_LEVELS): Move here from pt.c.
+ (TMPL_ARGS_DEPTH, TMPL_ARGS_LEVEL, SET_TMPL_ARGS_LEVEL): Likewise.
+ (TMPL_ARG, SET_TMPL_ARG, NUM_TMPL_ARGS, TMPL_PARMS_DEPTH): Likewise.
+ * error.c (dump_template_bindings): Remove unused parameter.
+ Handle multiple levels of template parameters.
+ (dump_template_decl): Use `parms', not `args', for template
+ parameters. Fix thinko.
+ (dump_function_decl): Use DECL_TEMPLATE_INSTANTIATION. Don't pass
+ flags to dump_template_bindings.
+ * pt.c (TMPL_ARGS_HAVE_MULTIPLE_LEVELS): Move to cp-tree.h.
+ (TMPL_ARGS_DEPTH, TMPL_ARGS_LEVEL, SET_TMPL_ARGS_LEVEL): Likewise.
+ (TMPL_ARG, SET_TMPL_ARG, NUM_TMPL_ARGS, TMPL_PARMS_DEPTH): Likewise.
+ (tsubst_copy): Clarify variable name.
+ (most_general_template): Robustify.
+
1999-09-29 Nathan Sidwell <nathan@acm.org>
* error.c (dump_template_parms): Don't use TS_PEDANTIC_NAME
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 7920fdf5..3adb303 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -1852,6 +1852,66 @@ struct lang_decl
#define TI_SPEC_INFO(NODE) (TREE_CHAIN (NODE))
#define TI_PENDING_TEMPLATE_FLAG(NODE) TREE_LANG_FLAG_1 (NODE)
+/* We use TREE_VECs to hold template arguments. If there is only one
+ level of template arguments, then the TREE_VEC contains the
+ arguments directly. If there is more than one level of template
+ arguments, then each entry in the TREE_VEC is itself a TREE_VEC,
+ containing the template arguments for a single level. The first
+ entry in the outer TREE_VEC is the outermost level of template
+ parameters; the last is the innermost.
+
+ It is incorrect to ever form a template argument vector containing
+ only one level of arguments, but which is a TREE_VEC containing as
+ its only entry the TREE_VEC for that level. */
+
+/* Non-zero if the template arguments is actually a vector of vectors,
+ rather than just a vector. */
+#define TMPL_ARGS_HAVE_MULTIPLE_LEVELS(NODE) \
+ (NODE != NULL_TREE \
+ && TREE_CODE (NODE) == TREE_VEC \
+ && TREE_VEC_LENGTH (NODE) > 0 \
+ && TREE_VEC_ELT (NODE, 0) != NULL_TREE \
+ && TREE_CODE (TREE_VEC_ELT (NODE, 0)) == TREE_VEC)
+
+/* The depth of a template argument vector. When called directly by
+ the parser, we use a TREE_LIST rather than a TREE_VEC to represent
+ template arguments. In fact, we may even see NULL_TREE if there
+ are no template arguments. In both of those cases, there is only
+ one level of template arguments. */
+#define TMPL_ARGS_DEPTH(NODE) \
+ (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (NODE) ? TREE_VEC_LENGTH (NODE) : 1)
+
+/* The LEVELth level of the template ARGS. Note that template
+ parameter levels are indexed from 1, not from 0. */
+#define TMPL_ARGS_LEVEL(ARGS, LEVEL) \
+ (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (ARGS) \
+ ? TREE_VEC_ELT ((ARGS), (LEVEL) - 1) : ARGS)
+
+/* Set the LEVELth level of the template ARGS to VAL. This macro does
+ not work with single-level argument vectors. */
+#define SET_TMPL_ARGS_LEVEL(ARGS, LEVEL, VAL) \
+ (TREE_VEC_ELT ((ARGS), (LEVEL) - 1) = (VAL))
+
+/* Accesses the IDXth parameter in the LEVELth level of the ARGS. */
+#define TMPL_ARG(ARGS, LEVEL, IDX) \
+ (TREE_VEC_ELT (TMPL_ARGS_LEVEL (ARGS, LEVEL), IDX))
+
+/* Set the IDXth element in the LEVELth level of ARGS to VAL. This
+ macro does not work with single-level argument vectors. */
+#define SET_TMPL_ARG(ARGS, LEVEL, IDX, VAL) \
+ (TREE_VEC_ELT (TREE_VEC_ELT ((ARGS), (LEVEL) - 1), (IDX)) = (VAL))
+
+/* Given a single level of template arguments in NODE, return the
+ number of arguments. */
+#define NUM_TMPL_ARGS(NODE) \
+ ((NODE) == NULL_TREE ? 0 \
+ : (TREE_CODE (NODE) == TREE_VEC \
+ ? TREE_VEC_LENGTH (NODE) : list_length (NODE)))
+
+/* The number of levels of template parameters given by NODE. */
+#define TMPL_PARMS_DEPTH(NODE) \
+ (TREE_INT_CST_HIGH (TREE_PURPOSE (NODE)))
+
/* The TEMPLATE_DECL instantiated or specialized by NODE. This
TEMPLATE_DECL will be the immediate parent, not the most general
template. For example, in:
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index ddb1ed9..ac9427b 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -92,7 +92,7 @@ static tree ident_fndecl PROTO((tree));
static void dump_template_argument PROTO((tree, enum tree_string_flags));
static void dump_template_argument_list PROTO((tree, enum tree_string_flags));
static void dump_template_parameter PROTO((tree, enum tree_string_flags));
-static void dump_template_bindings PROTO((tree, tree, enum tree_string_flags));
+static void dump_template_bindings PROTO((tree, tree));
static void dump_scope PROTO((tree, enum tree_string_flags));
static void dump_template_parms PROTO((tree, int, enum tree_string_flags));
@@ -293,41 +293,39 @@ dump_template_parameter (parm, flags)
TREE_VEC. */
static void
-dump_template_bindings (parms, args, flags)
+dump_template_bindings (parms, args)
tree parms, args;
- enum tree_string_flags flags;
{
- int arg_idx = 0;
int need_comma = 0;
while (parms)
{
tree p = TREE_VALUE (parms);
+ int lvl = TMPL_PARMS_DEPTH (parms);
+ int arg_idx = 0;
int i;
for (i = 0; i < TREE_VEC_LENGTH (p); ++i)
- {
- tree arg = TREE_VEC_ELT (args, arg_idx);
-
- if (need_comma)
- OB_PUTS (", ");
- dump_template_parameter (TREE_VEC_ELT (p, i), TS_PLAIN);
- OB_PUTS (" = ");
- if (arg)
- dump_template_argument (arg, TS_PLAIN);
- else
- OB_PUTS ("{missing}");
+ {
+ tree arg = TMPL_ARG (args, lvl, arg_idx);
+
+ if (need_comma)
+ OB_PUTS (", ");
+ dump_template_parameter (TREE_VEC_ELT (p, i), TS_PLAIN);
+ OB_PUTS (" = ");
+ if (arg)
+ dump_template_argument (arg, TS_PLAIN);
+ else
+ OB_PUTS ("{missing}");
- ++arg_idx;
- need_comma = 1;
- }
+ ++arg_idx;
+ need_comma = 1;
+ }
parms = TREE_CHAIN (parms);
}
}
-
-
/* Dump into the obstack a human-readable equivalent of TYPE. FLAGS
controls the format. */
@@ -1042,31 +1040,32 @@ dump_template_decl (t, flags)
tree t;
enum tree_string_flags flags;
{
- tree orig_args = DECL_TEMPLATE_PARMS (t);
- tree args;
+ tree orig_parms = DECL_TEMPLATE_PARMS (t);
+ tree parms;
int i;
if (flags & TS_TEMPLATE_PREFIX)
{
- for (args = orig_args = nreverse (orig_args);
- args;
- args = TREE_CHAIN (args))
+ for (parms = orig_parms = nreverse (orig_parms);
+ parms;
+ parms = TREE_CHAIN (parms))
{
- int len = TREE_VEC_LENGTH (TREE_VALUE (args));
+ tree inner_parms = INNERMOST_TEMPLATE_PARMS (parms);
+ int len = TREE_VEC_LENGTH (inner_parms);
OB_PUTS ("template <");
for (i = 0; i < len; i++)
{
if (i)
OB_PUTS (", ");
- dump_template_parameter (TREE_VEC_ELT (args, i), flags);
+ dump_template_parameter (TREE_VEC_ELT (inner_parms, i), flags);
}
OB_END_TEMPLATE_ID ();
OB_PUTC (' ');
}
- nreverse(orig_args);
+ nreverse(orig_parms);
/* If we've shown the template<args> prefix, we'd better show the
- * decl's type too. */
+ decl's type too. */
flags |= TS_DECL_TYPE;
}
if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL)
@@ -1113,11 +1112,12 @@ dump_function_decl (t, flags)
t = DECL_TEMPLATE_RESULT (t);
/* Pretty print template instantiations only. */
- if (DECL_USE_TEMPLATE (t) == 1 || DECL_USE_TEMPLATE (t) == 3)
+ if (DECL_TEMPLATE_INSTANTIATION (t))
{
template_args = DECL_TI_ARGS (t);
t = most_general_template (t);
- template_parms = DECL_TEMPLATE_PARMS (t);
+ if (TREE_CODE (t) == TEMPLATE_DECL)
+ template_parms = DECL_TEMPLATE_PARMS (t);
}
fntype = TREE_TYPE (t);
@@ -1184,7 +1184,7 @@ dump_function_decl (t, flags)
if (template_parms != NULL_TREE && template_args != NULL_TREE)
{
OB_PUTS (" [with ");
- dump_template_bindings (template_parms, template_args, flags);
+ dump_template_bindings (template_parms, template_args);
OB_PUTC (']');
}
}
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index dc5beab..baf6c35 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -158,66 +158,6 @@ static int template_args_equal PROTO((tree, tree));
static void print_template_context PROTO((int));
static void tsubst_default_arguments PROTO((tree));
-/* We use TREE_VECs to hold template arguments. If there is only one
- level of template arguments, then the TREE_VEC contains the
- arguments directly. If there is more than one level of template
- arguments, then each entry in the TREE_VEC is itself a TREE_VEC,
- containing the template arguments for a single level. The first
- entry in the outer TREE_VEC is the outermost level of template
- parameters; the last is the innermost.
-
- It is incorrect to ever form a template argument vector containing
- only one level of arguments, but which is a TREE_VEC containing as
- its only entry the TREE_VEC for that level. */
-
-/* Non-zero if the template arguments is actually a vector of vectors,
- rather than just a vector. */
-#define TMPL_ARGS_HAVE_MULTIPLE_LEVELS(NODE) \
- (NODE != NULL_TREE \
- && TREE_CODE (NODE) == TREE_VEC \
- && TREE_VEC_LENGTH (NODE) > 0 \
- && TREE_VEC_ELT (NODE, 0) != NULL_TREE \
- && TREE_CODE (TREE_VEC_ELT (NODE, 0)) == TREE_VEC)
-
-/* The depth of a template argument vector. When called directly by
- the parser, we use a TREE_LIST rather than a TREE_VEC to represent
- template arguments. In fact, we may even see NULL_TREE if there
- are no template arguments. In both of those cases, there is only
- one level of template arguments. */
-#define TMPL_ARGS_DEPTH(NODE) \
- (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (NODE) ? TREE_VEC_LENGTH (NODE) : 1)
-
-/* The LEVELth level of the template ARGS. Note that template
- parameter levels are indexed from 1, not from 0. */
-#define TMPL_ARGS_LEVEL(ARGS, LEVEL) \
- (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (ARGS) \
- ? TREE_VEC_ELT ((ARGS), (LEVEL) - 1) : ARGS)
-
-/* Set the LEVELth level of the template ARGS to VAL. This macro does
- not work with single-level argument vectors. */
-#define SET_TMPL_ARGS_LEVEL(ARGS, LEVEL, VAL) \
- (TREE_VEC_ELT ((ARGS), (LEVEL) - 1) = (VAL))
-
-/* Accesses the IDXth parameter in the LEVELth level of the ARGS. */
-#define TMPL_ARG(ARGS, LEVEL, IDX) \
- (TREE_VEC_ELT (TMPL_ARGS_LEVEL (ARGS, LEVEL), IDX))
-
-/* Set the IDXth element in the LEVELth level of ARGS to VAL. This
- macro does not work with single-level argument vectors. */
-#define SET_TMPL_ARG(ARGS, LEVEL, IDX, VAL) \
- (TREE_VEC_ELT (TREE_VEC_ELT ((ARGS), (LEVEL) - 1), (IDX)) = (VAL))
-
-/* Given a single level of template arguments in NODE, return the
- number of arguments. */
-#define NUM_TMPL_ARGS(NODE) \
- ((NODE) == NULL_TREE ? 0 \
- : (TREE_CODE (NODE) == TREE_VEC \
- ? TREE_VEC_LENGTH (NODE) : list_length (NODE)))
-
-/* The number of levels of template parameters given by NODE. */
-#define TMPL_PARMS_DEPTH(NODE) \
- (TREE_INT_CST_HIGH (TREE_PURPOSE (NODE)))
-
/* Called once to initialize pt.c. */
void
@@ -7081,10 +7021,10 @@ tsubst_copy (t, args, complain, in_decl)
to expand the STMT_EXPR here. */
if (!processing_template_decl)
{
- tree rtl_expr = begin_stmt_expr ();
+ tree stmt_expr = begin_stmt_expr ();
tsubst_expr (STMT_EXPR_STMT (t), args,
complain, in_decl);
- return finish_stmt_expr (rtl_expr);
+ return finish_stmt_expr (stmt_expr);
}
return t;
@@ -9092,7 +9032,11 @@ tree
most_general_template (decl)
tree decl;
{
- while (DECL_TEMPLATE_INFO (decl))
+ while (DECL_TEMPLATE_INFO (decl)
+ /* The DECL_TI_TEMPLATE can be a LOOKUP_EXPR or
+ IDENTIFIER_NODE in some cases. (See cp-tree.h for
+ details.) */
+ && TREE_CODE (DECL_TI_TEMPLATE (decl)) == TEMPLATE_DECL)
decl = DECL_TI_TEMPLATE (decl);
return decl;
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/error1.C b/gcc/testsuite/g++.old-deja/g++.pt/error1.C
new file mode 100644
index 0000000..675a31a
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.pt/error1.C
@@ -0,0 +1,19 @@
+// Build don't link:
+// Origin: Mark Mitchell <mark@codesourcery.com>
+
+template <class T>
+struct S
+{
+ template <class U>
+ void f ();
+
+};
+
+template <class T>
+template <class U>
+void S<T>::f ()
+{
+ U& u; // ERROR - uninitialized reference
+}
+
+template void S<int>::f<double>(); // ERROR - instantiated from here