]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
cp-tree.h (TMPL_ARGS_HAVE_MULTIPLE_LEVELS): non-NULL NODE is always a TREE_VEC of...
authorNathan Sidwell <nathan@codesourcery.com>
Sun, 10 Aug 2003 15:10:35 +0000 (15:10 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Sun, 10 Aug 2003 15:10:35 +0000 (15:10 +0000)
cp:
* 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.

From-SVN: r70295

gcc/cp/ChangeLog
gcc/cp/cp-tree.def
gcc/cp/cp-tree.h
gcc/cp/decl2.c
gcc/cp/error.c
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/tree.c

index c4a59498cad2959f86d5b9760c5e2dd62d1c1fc6..47c1afc84d1728ed38c44b55d134b23b22d9278a 100644 (file)
@@ -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
index f020a23d6a2f65e68c57d3f1fbf69dd4be943b0c..a5fa243a167249b809968ad0980d9db1292a98f2 100644 (file)
@@ -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 
index 36dda85fe5b9ee57e2de728a4544721ce2d5f39f..d47c3077d093a3e9515e7faa6ec7e7688f3c79d9 100644 (file)
@@ -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) \
index 46c4083c2a7bd630a2b2f586a1643a5d00a3efdc..556f62a1472554dfcb8b2b29f832970f98babebf 100644 (file)
@@ -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
index 3531f94ec8aa4c4e1c63076313cffc4dbc0e7bec..cd44f15cbb42e6af6ffb1a6f38bf240a8cc7c8b2 100644 (file)
@@ -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)
index 12f541a73967ef509260004c28e80f7ca54d6860..94fea3deb90df662d1c60effaacc68820fd289f1 100644 (file)
@@ -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.
index a4e55c0330da7c3968a163a81a8bfb1d93d344fb..5eba7adf95240f7acd3d6a737e2827d828f1e283 100644 (file)
@@ -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;
 }
index 0fcba63bbf1f6e665979bb225d52a00409ea8a97..64676fdf544a2830d48ce7d945710283537960d8 100644 (file)
@@ -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:
       {