diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 21 | ||||
-rw-r--r-- | gcc/cp/cp-tree.def | 8 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 11 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 6 | ||||
-rw-r--r-- | gcc/cp/error.c | 45 | ||||
-rw-r--r-- | gcc/cp/parser.c | 47 | ||||
-rw-r--r-- | gcc/cp/pt.c | 106 | ||||
-rw-r--r-- | gcc/cp/tree.c | 24 |
8 files changed, 129 insertions, 139 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c4a5949..47c1afc 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,26 @@ 2003-08-10 Nathan Sidwell <nathan@codesourcery.com> + * cp-tree.h (TMPL_ARGS_HAVE_MULTIPLE_LEVELS): non-NULL + NODE is always a TREE_VEC of non-zero size. + (NUM_TMPL_ARGS): NODE is always a TREE_VEC. + * decl2.c (arg_assoc): Template args will be a vec. + * error.c (dump_decl) <TEMPLATE_ID_EXPR case>: Call + dump_template_argument_list. + (dump_template_parms): Args will be a vec. + * parser.c (cp_parser_template_argument_list): Produce a + vector, not a list. + * pt.c (coerce_template_parms): Args are always vectors. + (mangle_class_name_for_template): Likewise. + (lookup_template_function): Likewise. + (lookup_template_class): Likewise. + (tsubst_template_args): Likewise. + (tsubst_baselink): Use tsubst_template_args. + (tsubst_qualified_id): Likewise. + (tsubst_copy) <TEMPLATE_ID_EXPR case>: Likewise. + (tsubst_copy_and_build) <TEMPLATE_ID_EXPR case>: Likewise. + (any_dependent_template_args_p): Args are always vectors. + * tree.c (cp_tree_equal): Add TEMPLATE_ID_EXPR case. + PR c++/11670 * call.c (convert_like_real): Add rvalue binding error message. * error.c (dump_expr) <NOP_EXPR case>: Detect when the no expr is diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def index f020a23..a5fa243 100644 --- a/gcc/cp/cp-tree.def +++ b/gcc/cp/cp-tree.def @@ -207,10 +207,10 @@ DEFTREECODE (USING_STMT, "using_directive", 'e', 1) DEFTREECODE (DEFAULT_ARG, "default_arg", 'x', 0) /* A template-id, like foo<int>. The first operand is the template. - The second is the TREE_LIST or TREE_VEC of explicitly specified - arguments. The template will be a FUNCTION_DECL, TEMPLATE_DECL, or - an OVERLOAD. If the template-id refers to a member template, the - template may be an IDENTIFIER_NODE. */ + The second is NULL if there are no explicit arguments, or a + TREE_VEC of arguments. The template will be a FUNCTION_DECL, + TEMPLATE_DECL, or an OVERLOAD. If the template-id refers to a + member template, the template may be an IDENTIFIER_NODE. */ DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", 'e', 2) /* A list-like node for chaining overloading candidates. TREE_TYPE is diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 36dda85..d47c307 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -2203,11 +2203,8 @@ struct lang_decl GTY(()) /* Nonzero 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 \ +#define TMPL_ARGS_HAVE_MULTIPLE_LEVELS(NODE) \ + (NODE && TREE_VEC_ELT (NODE, 0) \ && TREE_CODE (TREE_VEC_ELT (NODE, 0)) == TREE_VEC) /* The depth of a template argument vector. When called directly by @@ -2241,9 +2238,7 @@ struct lang_decl GTY(()) /* 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))) + (TREE_VEC_LENGTH (NODE)) /* Returns the innermost level of template arguments in ARGS. */ #define INNERMOST_TEMPLATE_ARGS(NODE) \ diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 46c4083..556f62a 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -3716,7 +3716,7 @@ arg_assoc (struct arg_lookup *k, tree n) tree template = TREE_OPERAND (n, 0); tree args = TREE_OPERAND (n, 1); tree ctx; - tree arg; + int ix; if (TREE_CODE (template) == COMPONENT_REF) template = TREE_OPERAND (template, 1); @@ -3739,8 +3739,8 @@ arg_assoc (struct arg_lookup *k, tree n) return true; /* Now the arguments. */ - for (arg = args; arg != NULL_TREE; arg = TREE_CHAIN (arg)) - if (arg_assoc_template_arg (k, TREE_VALUE (arg)) == 1) + for (ix = TREE_VEC_LENGTH (args); ix--;) + if (arg_assoc_template_arg (k, TREE_VEC_ELT (args, ix)) == 1) return true; } else diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 3531f94..cd44f15 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -920,18 +920,14 @@ dump_decl (tree t, int flags) case TEMPLATE_ID_EXPR: { - tree args; tree name = TREE_OPERAND (t, 0); + if (is_overloaded_fn (name)) name = DECL_NAME (get_first_fn (name)); dump_decl (name, flags); pp_template_argument_list_start (cxx_pp); - for (args = TREE_OPERAND (t, 1); args; args = TREE_CHAIN (args)) - { - dump_template_argument (TREE_VALUE (args), flags); - if (TREE_CHAIN (args)) - pp_separate_with_comma (cxx_pp); - } + if (TREE_OPERAND (t, 1)) + dump_template_argument_list (TREE_OPERAND (t, 1), flags); pp_template_argument_list_end (cxx_pp); } break; @@ -1256,41 +1252,24 @@ dump_template_parms (tree info, int primary, int flags) to crash producing error messages. */ if (args && !primary) { - int len = 0; - int ix = 0; - int need_comma = 0; + int len, ix; - if (TREE_CODE (args) == TREE_VEC) - { - if (TREE_VEC_LENGTH (args) > 0 - && TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC) - args = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1); + if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args)) + args = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1); + + len = TREE_VEC_LENGTH (args); - len = TREE_VEC_LENGTH (args); - } - else if (TREE_CODE (args) == TREE_LIST) - len = -1; - while (ix != len && args) + for (ix = 0; ix != len; ix++) { - tree arg; - if (len >= 0) - { - arg = TREE_VEC_ELT (args, ix); - ix++; - } - else - { - arg = TREE_VALUE (args); - args = TREE_CHAIN (args); - } - if (need_comma) + tree arg = TREE_VEC_ELT (args, ix); + + if (ix) pp_separate_with_comma (cxx_pp); if (!arg) pp_identifier (cxx_pp, "<template parameter error>"); else dump_template_argument (arg, flags); - need_comma = 1; } } else if (primary) diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 12f541a..94fea3d 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -7675,32 +7675,51 @@ cp_parser_template_name (cp_parser* parser, template-argument template-argument-list , template-argument - Returns a TREE_LIST representing the arguments, in the order they - appeared. The TREE_VALUE of each node is a representation of the - argument. */ + Returns a TREE_VEC containing the arguments. */ static tree cp_parser_template_argument_list (cp_parser* parser) { - tree arguments = NULL_TREE; + tree fixed_args[10]; + unsigned n_args = 0; + unsigned alloced = 10; + tree *arg_ary = fixed_args; + tree vec; - while (true) + do { tree argument; + if (n_args) + /* Consume the comma. */ + cp_lexer_consume_token (parser->lexer); + /* Parse the template-argument. */ argument = cp_parser_template_argument (parser); - /* Add it to the list. */ - arguments = tree_cons (NULL_TREE, argument, arguments); - /* If it is not a `,', then there are no more arguments. */ - if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA)) - break; - /* Otherwise, consume the ','. */ - cp_lexer_consume_token (parser->lexer); + if (n_args == alloced) + { + alloced *= 2; + + if (arg_ary == fixed_args) + { + arg_ary = xmalloc (sizeof (tree) * alloced); + memcpy (arg_ary, fixed_args, sizeof (tree) * n_args); + } + else + arg_ary = xrealloc (arg_ary, sizeof (tree) * alloced); + } + arg_ary[n_args++] = argument; } + while (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)); + + vec = make_tree_vec (n_args); - /* We built up the arguments in reverse order. */ - return nreverse (arguments); + while (n_args--) + TREE_VEC_ELT (vec, n_args) = arg_ary[n_args]; + + if (arg_ary != fixed_args) + free (arg_ary); + return vec; } /* Parse a template-argument. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index a4e55c0..5eba7ad 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3583,7 +3583,7 @@ coerce_template_parms (tree parms, tree new_inner_args; inner_args = INNERMOST_TEMPLATE_ARGS (args); - nargs = NUM_TMPL_ARGS (inner_args); + nargs = inner_args ? NUM_TMPL_ARGS (inner_args) : 0; nparms = TREE_VEC_LENGTH (parms); if (nargs > nparms @@ -3614,12 +3614,7 @@ coerce_template_parms (tree parms, parm = TREE_VEC_ELT (parms, i); /* Calculate the Ith argument. */ - if (inner_args && TREE_CODE (inner_args) == TREE_LIST) - { - arg = TREE_VALUE (inner_args); - inner_args = TREE_CHAIN (inner_args); - } - else if (i < nargs) + if (i < nargs) arg = TREE_VEC_ELT (inner_args, i); else if (require_all_arguments) /* There must be a default arg in this case. */ @@ -3752,13 +3747,6 @@ mangle_class_name_for_template (const char* name, tree parms, tree arglist) else my_friendly_assert (TREE_CODE (parm) == PARM_DECL, 269); - if (TREE_CODE (arg) == TREE_LIST) - { - /* New list cell was built because old chain link was in - use. */ - my_friendly_assert (TREE_PURPOSE (arg) == NULL_TREE, 270); - arg = TREE_VALUE (arg); - } /* No need to check arglist against parmlist here; we did that in coerce_template_parms, called from lookup_template_class. */ cat (expr_as_string (arg, TFF_PLAIN_IDENTIFIER)); @@ -3854,6 +3842,7 @@ lookup_template_function (tree fns, tree arglist) if (fns == error_mark_node || arglist == error_mark_node) return error_mark_node; + my_friendly_assert (!arglist || TREE_CODE (arglist) == TREE_VEC, 20030726); if (fns == NULL_TREE) { error ("non-template used as template"); @@ -3904,9 +3893,6 @@ maybe_get_template_decl_from_type_decl (tree decl) parameters, find the desired type. D1 is the PTYPENAME terminal, and ARGLIST is the list of arguments. - (Actually ARGLIST may be either a TREE_LIST or a TREE_VEC. It will - be a TREE_LIST if called directly from the parser, and a TREE_VEC - otherwise.) IN_DECL, if non-NULL, is the template declaration we are trying to instantiate. @@ -3932,8 +3918,6 @@ lookup_template_class (tree d1, tree t; timevar_push (TV_NAME_LOOKUP); - my_friendly_assert ((!arglist || TREE_CODE (arglist) == TREE_LIST) - == ((complain & tf_user) != 0), 20030724); if (TREE_CODE (d1) == IDENTIFIER_NODE) { @@ -5492,30 +5476,18 @@ tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl) static tree tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl) { - int is_list = !(t && TREE_CODE (t) == TREE_VEC); - int len = is_list ? list_length (t) : TREE_VEC_LENGTH (t); + int len = TREE_VEC_LENGTH (t); int need_new = 0, i; - tree position = t; tree *elts = alloca (len * sizeof (tree)); for (i = 0; i < len; i++) { - tree orig_arg; - tree new_arg = NULL_TREE; + tree orig_arg = TREE_VEC_ELT (t, i); + tree new_arg; - if (is_list) - { - orig_arg = TREE_VALUE (position); - position = TREE_CHAIN (position); - } + if (TREE_CODE (orig_arg) == TREE_VEC) + new_arg = tsubst_template_args (orig_arg, args, complain, in_decl); else - { - orig_arg = TREE_VEC_ELT (t, i); - if (TREE_CODE (orig_arg) == TREE_VEC) - new_arg = tsubst_template_args (orig_arg, args, complain, in_decl); - } - - if (!new_arg) new_arg = tsubst_template_arg (orig_arg, args, complain, in_decl); if (new_arg == error_mark_node) @@ -5529,19 +5501,9 @@ tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (!need_new) return t; - if (is_list) - { - t = NULL_TREE; - - for (i = len; i--;) - t = tree_cons (NULL_TREE, elts[i], t); - } - else - { - t = make_tree_vec (len); - for (i = 0; i < len; i++) - TREE_VEC_ELT (t, i) = elts[i]; - } + t = make_tree_vec (len); + for (i = 0; i < len; i++) + TREE_VEC_ELT (t, i) = elts[i]; return t; } @@ -7052,9 +7014,9 @@ tsubst_baselink (tree baselink, tree object_type, template_id_p = true; template_args = TREE_OPERAND (fns, 1); fns = TREE_OPERAND (fns, 0); - template_args = tsubst_copy_and_build (template_args, args, - complain, in_decl, - /*function_p=*/false); + if (template_args) + template_args = tsubst_template_args (template_args, args, + complain, in_decl); } name = DECL_NAME (get_first_fn (fns)); baselink = lookup_fnfields (qualifying_scope, name, /*protect=*/1); @@ -7094,9 +7056,10 @@ tsubst_qualified_id (tree qualified_id, tree args, if (TREE_CODE (name) == TEMPLATE_ID_EXPR) { is_template = true; - template_args = tsubst_copy_and_build (TREE_OPERAND (name, 1), - args, complain, in_decl, - /*function_p=*/false); + template_args = TREE_OPERAND (name, 1); + if (template_args) + template_args = tsubst_template_args (template_args, args, + complain, in_decl); name = TREE_OPERAND (name, 0); } else @@ -7431,7 +7394,8 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) tree targs = TREE_OPERAND (t, 1); fn = tsubst_copy (fn, args, complain, in_decl); - targs = tsubst_template_args (targs, args, complain, in_decl); + if (targs) + targs = tsubst_template_args (targs, args, complain, in_decl); return lookup_template_function (fn, targs); } @@ -7930,7 +7894,10 @@ tsubst_copy_and_build (tree t, { tree object; tree template = RECUR (TREE_OPERAND (t, 0)); - tree targs = RECUR (TREE_OPERAND (t, 1)); + tree targs = TREE_OPERAND (t, 1); + + if (targs) + targs = tsubst_template_args (targs, args, complain, in_decl); if (TREE_CODE (template) == COMPONENT_REF) { @@ -11697,29 +11664,14 @@ dependent_template_arg_p (tree arg) bool any_dependent_template_arguments_p (tree args) { + int i; + if (!args) return false; - my_friendly_assert (TREE_CODE (args) == TREE_LIST - || TREE_CODE (args) == TREE_VEC, - 20030707); - - if (TREE_CODE (args) == TREE_LIST) - { - while (args) - { - if (dependent_template_arg_p (TREE_VALUE (args))) - return true; - args = TREE_CHAIN (args); - } - } - else - { - int i; - for (i = 0; i < TREE_VEC_LENGTH (args); ++i) - if (dependent_template_arg_p (TREE_VEC_ELT (args, i))) - return true; - } + for (i = 0; i < TREE_VEC_LENGTH (args); ++i) + if (dependent_template_arg_p (TREE_VEC_ELT (args, i))) + return true; return false; } diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 0fcba63..64676fd 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1587,6 +1587,30 @@ cp_tree_equal (tree t1, tree t2) && same_type_p (TREE_TYPE (TEMPLATE_PARM_DECL (t1)), TREE_TYPE (TEMPLATE_PARM_DECL (t2)))); + case TEMPLATE_ID_EXPR: + { + unsigned ix; + tree vec1, vec2; + + if (!cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0))) + return false; + vec1 = TREE_OPERAND (t1, 1); + vec2 = TREE_OPERAND (t2, 1); + + if (!vec1 || !vec2) + return !vec1 && !vec2; + + if (TREE_VEC_LENGTH (vec1) != TREE_VEC_LENGTH (vec2)) + return false; + + for (ix = TREE_VEC_LENGTH (vec1); ix--;) + if (!cp_tree_equal (TREE_VEC_ELT (vec1, ix), + TREE_VEC_ELT (vec2, ix))) + return false; + + return true; + } + case SIZEOF_EXPR: case ALIGNOF_EXPR: { |