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
This commit is contained in:
Mark Mitchell 1999-09-29 17:24:21 +00:00 committed by Mark Mitchell
parent 0acbb8d94d
commit b5ac18ea8c
5 changed files with 134 additions and 94 deletions

View File

@ -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

View File

@ -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:

View File

@ -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);
{
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}");
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 (']');
}
}

View File

@ -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;

View File

@ -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