* 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
+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
#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:
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));
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. */
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)
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);
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 (']');
}
}
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
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;
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;
--- /dev/null
+// 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