From b5ac18ea8c1365118cfee58840ff738b0de67b5e Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Wed, 29 Sep 1999 17:24:21 +0000 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 17 ++++++++ gcc/cp/cp-tree.h | 60 +++++++++++++++++++++++++ gcc/cp/error.c | 64 +++++++++++++-------------- gcc/cp/pt.c | 70 +++--------------------------- gcc/testsuite/g++.old-deja/g++.pt/error1.C | 19 ++++++++ 5 files changed, 135 insertions(+), 95 deletions(-) create mode 100644 gcc/testsuite/g++.old-deja/g++.pt/error1.C 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 + + * 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 * 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 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 + +template +struct S +{ + template + void f (); + +}; + +template +template +void S::f () +{ + U& u; // ERROR - uninitialized reference +} + +template void S::f(); // ERROR - instantiated from here -- 2.7.4