cp-tree.h (TMPL_ARGS_HAVE_MULTIPLE_LEVELS): Move here from pt.c.
authorMark Mitchell <mark@codesourcery.com>
Wed, 29 Sep 1999 17:24:21 +0000 (17:24 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Wed, 29 Sep 1999 17:24:21 +0000 (17:24 +0000)
* 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
gcc/cp/cp-tree.h
gcc/cp/error.c
gcc/cp/pt.c
gcc/testsuite/g++.old-deja/g++.pt/error1.C [new file with mode: 0644]

index 32d62b0..56d78d4 100644 (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
index 7920fdf..3adb303 100644 (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:
index ddb1ed9..ac9427b 100644 (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);
-
-          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<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 (']');
     }
 }
index dc5beab..baf6c35 100644 (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;
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 (file)
index 0000000..675a31a
--- /dev/null
@@ -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