]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
cp-tree.def (BOUND_TEMPLATE_TEMPLATE_PARM): New tree code.
authorKriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
Tue, 5 Sep 2000 01:01:39 +0000 (01:01 +0000)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 5 Sep 2000 01:01:39 +0000 (21:01 -0400)
        * cp-tree.def (BOUND_TEMPLATE_TEMPLATE_PARM): New tree code.
        (TEMPLATE_TEMPLATE_PARM): Adjust comment.
        * cp-tree.h (TYPE_BINFO): Adjust comment.
        (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO): Likewise.
        (TEMPLATE_TYPE_PARM_INDEX): Likewise.
        (IS_AGGR_TYPE): Use BOUND_TEMPLATE_TEMPLATE_PARM instead.
        (TYPE_TEMPLATE_INFO): Likewise.
        (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL): Likewise.
        * class.c (push_nested_class): Likewise.
        * decl.c (lookup_name_real): Likewise.
        (grokdeclarator): Likewise.
        (grok_op_properties): Likewise.
        (xref_tag): Likewise.
        (xref_basetypes): Likewise.
        * decl2.c (constructor_name_full): Likewise.
        (arg_assoc_template_arg): Add TEMPLATE_TEMPLATE_PARM case.
        (arg_assoc_type): Use BOUND_TEMPLATE_TEMPLATE_PARM instead.
        * error.c (dump_type): Split TEMPLATE_TEMPLATE_PARM case.
        (dump_type_prefix): Add BOUND_TEMPLATE_TEMPLATE_PARM.
        (dump_type_suffix): Likewise.
        * init.c (is_aggr_type): Use BOUND_TEMPLATE_TEMPLATE_PARM
        instead.
        (get_aggr_from_typedef): Likewise.
        * mangle.c (write_type): Split TEMPLATE_TEMPLATE_PARM case.
        (write_expression): Add BOUND_TEMPLATE_TEMPLATE_PARM.
        (write_template_parm): Likewise.
        (write_template_template_parm): Check tree code instead of
        using TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
        * method.c (build_overload_nested_name): Add
        BOUND_TEMPLATE_TEMPLATE_PARM.
        (process_overload_item): Split TEMPLATE_TEMPLATE_PARM case.
        * parse.y (bad_parm): Add BOUND_TEMPLATE_TEMPLATE_PARM.
        * pt.c (convert_template_argument): Check tree code instead of
        using TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
        (for_each_template_parm_r): Split TEMPLATE_TEMPLATE_PARM case.
        (for_each_template_parm): Adjust comment.
        (tsubst): Add BOUND_TEMPLATE_TEMPLATE_PARM.  Reorganize.
        (tsubst_copy): Add BOUND_TEMPLATE_TEMPLATE_PARM.
        (unify): Add BOUND_TEMPLATE_TEMPLATE_PARM.  Reorganize.  Use
        template_args_equal to compare template template parameter cases.
        * ptree.c (print_lang_type): Add BOUND_TEMPLATE_TEMPLATE_PARM.
        * search.c (lookup_field_1): Use BOUND_TEMPLATE_TEMPLATE_PARM
        instead.
        * tree.c (copy_template_template_parm): Decide whether to create
        a TEMPLATE_TEMPLATE_PARM or BOUND_TEMPLATE_TEMPLATE_PARM node.
        (walk_tree): Add BOUND_TEMPLATE_TEMPLATE_PARM.
        (copy_tree_r): Likewise.
        * typeck.c (comptypes): Likewise.  Check tree code instead of
        using TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.

From-SVN: r36149

17 files changed:
gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.def
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/error.c
gcc/cp/init.c
gcc/cp/mangle.c
gcc/cp/method.c
gcc/cp/parse.y
gcc/cp/pt.c
gcc/cp/ptree.c
gcc/cp/search.c
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/testsuite/g++.old-deja/g++.pt/ttp62.C [new file with mode: 0644]

index 564de16fdb7c8df64f0c405bb1d90dbb173f6f4d..d4388fc6de9f074f1009b9d8f0a4f800d9532d57 100644 (file)
@@ -1,3 +1,55 @@
+2000-09-04  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
+
+       * cp-tree.def (BOUND_TEMPLATE_TEMPLATE_PARM): New tree code.
+       (TEMPLATE_TEMPLATE_PARM): Adjust comment.
+       * cp-tree.h (TYPE_BINFO): Adjust comment.
+       (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO): Likewise.
+       (TEMPLATE_TYPE_PARM_INDEX): Likewise.
+       (IS_AGGR_TYPE): Use BOUND_TEMPLATE_TEMPLATE_PARM instead.
+       (TYPE_TEMPLATE_INFO): Likewise.
+       (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL): Likewise.
+       * class.c (push_nested_class): Likewise.
+       * decl.c (lookup_name_real): Likewise.
+       (grokdeclarator): Likewise.
+       (grok_op_properties): Likewise.
+       (xref_tag): Likewise.
+       (xref_basetypes): Likewise.
+       * decl2.c (constructor_name_full): Likewise.
+       (arg_assoc_template_arg): Add TEMPLATE_TEMPLATE_PARM case.
+       (arg_assoc_type): Use BOUND_TEMPLATE_TEMPLATE_PARM instead.
+       * error.c (dump_type): Split TEMPLATE_TEMPLATE_PARM case.
+       (dump_type_prefix): Add BOUND_TEMPLATE_TEMPLATE_PARM.
+       (dump_type_suffix): Likewise.
+       * init.c (is_aggr_type): Use BOUND_TEMPLATE_TEMPLATE_PARM
+       instead.
+       (get_aggr_from_typedef): Likewise.
+       * mangle.c (write_type): Split TEMPLATE_TEMPLATE_PARM case.
+       (write_expression): Add BOUND_TEMPLATE_TEMPLATE_PARM.
+       (write_template_parm): Likewise.
+       (write_template_template_parm): Check tree code instead of
+       using TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
+       * method.c (build_overload_nested_name): Add 
+       BOUND_TEMPLATE_TEMPLATE_PARM.
+       (process_overload_item): Split TEMPLATE_TEMPLATE_PARM case.
+       * parse.y (bad_parm): Add BOUND_TEMPLATE_TEMPLATE_PARM.
+       * pt.c (convert_template_argument): Check tree code instead of
+       using TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
+       (for_each_template_parm_r): Split TEMPLATE_TEMPLATE_PARM case.
+       (for_each_template_parm): Adjust comment.
+       (tsubst): Add BOUND_TEMPLATE_TEMPLATE_PARM.  Reorganize.
+       (tsubst_copy): Add BOUND_TEMPLATE_TEMPLATE_PARM.
+       (unify): Add BOUND_TEMPLATE_TEMPLATE_PARM.  Reorganize.  Use
+       template_args_equal to compare template template parameter cases.
+       * ptree.c (print_lang_type): Add BOUND_TEMPLATE_TEMPLATE_PARM.
+       * search.c (lookup_field_1): Use BOUND_TEMPLATE_TEMPLATE_PARM
+       instead.
+       * tree.c (copy_template_template_parm): Decide whether to create
+       a TEMPLATE_TEMPLATE_PARM or BOUND_TEMPLATE_TEMPLATE_PARM node.
+       (walk_tree): Add BOUND_TEMPLATE_TEMPLATE_PARM.
+       (copy_tree_r): Likewise.
+       * typeck.c (comptypes): Likewise.  Check tree code instead of
+       using TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
+
 2000-09-04  Mark Elbrecht  <snowball3@bigfoot.com>
 
        * decl.c (finish_function): Move the code for handling functions
index c10f09d340920f8a03687f4e277738ddfd8543d4..d4c2ad2a436df18476fc542fa5b003bb92d744dd 100644 (file)
@@ -5644,7 +5644,7 @@ push_nested_class (type, modify)
       || TREE_CODE (type) == NAMESPACE_DECL
       || ! IS_AGGR_TYPE (type)
       || TREE_CODE (type) == TEMPLATE_TYPE_PARM
-      || TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM)
+      || TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
     return;
   
   context = DECL_CONTEXT (TYPE_MAIN_DECL (type));
index 71edb203f90247d2b1bd61663a268d5a94737aad..07ec1eae6299839649e707c6079b7e9e048e9844 100644 (file)
@@ -144,14 +144,16 @@ DEFTREECODE (TEMPLATE_TYPE_PARM, "template_type_parm", 't', 0)
    This parameter must be a type.  The TYPE_FIELDS value will be a 
    TEMPLATE_PARM_INDEX.
 
-   If it is used without template arguments like TT in C<TT>, 
+   It is used without template arguments like TT in C<TT>, 
    TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO is NULL_TREE
-   and TYPE_NAME is a TEMPLATE_DECL.
+   and TYPE_NAME is a TEMPLATE_DECL.  */
+DEFTREECODE (TEMPLATE_TEMPLATE_PARM, "template_template_parm", 't', 0)
 
-   Otherwise it is used with bound template arguments like TT<int>.
+/* Like TEMPLATE_TEMPLATE_PARM it is used with bound template arguments 
+   like TT<int>.
    In this case, TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO contains the
    template name and its bound arguments.  TYPE_NAME is a TYPE_DECL.  */
-DEFTREECODE (TEMPLATE_TEMPLATE_PARM, "template_template_parm", 't', 0)
+DEFTREECODE (BOUND_TEMPLATE_TEMPLATE_PARM, "bound_template_template_parm", 't', 0)
 
 /* A type designated by `typename T::t'.  TYPE_CONTEXT is `T',
    TYPE_NAME is an IDENTIFIER_NODE for `t'.  If the type was named via
index 4fee6fffc6361d87812b0ad36c2118da753df256..2da46defd2f5842aa344d9cc4a59795fdc93eead 100644 (file)
@@ -112,8 +112,8 @@ Boston, MA 02111-1307, USA.  */
    TYPE_BINFO
      For an ENUMERAL_TYPE, this is ENUM_TEMPLATE_INFO.
      For a TYPENAME_TYPE, this is TYPENAME_TYPE_FULLNAME.
-     For a TEMPLATE_TEMPLATE_PARM, this is
-     TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
+     For a TEMPLATE_TEMPLATE_PARM or BOUND_TEMPLATE_TEMPLATE_PARM, 
+     this is TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
 
   BINFO_VIRTUALS
      For a binfo, this is a TREE_LIST.  The BV_DELTA of each node
@@ -1241,8 +1241,7 @@ enum languages { lang_c, lang_cplusplus, lang_java };
   (TREE_CODE (t) == TEMPLATE_TYPE_PARM         \
    || TREE_CODE (t) == TYPENAME_TYPE           \
    || TREE_CODE (t) == TYPEOF_TYPE             \
-   || (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM \
-       && TYPE_TEMPLATE_INFO (t))              \
+   || TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM    \
    || TYPE_LANG_FLAG_5 (t))
 
 /* Set IS_AGGR_TYPE for T to VAL.  T must be a class, struct, or 
@@ -2298,14 +2297,14 @@ struct lang_decl
    non-type template parameters.  */
 #define ENUM_TEMPLATE_INFO(NODE) (TYPE_BINFO (ENUMERAL_TYPE_CHECK (NODE)))
 
-/* Template information for a template template parameter.  */
+/* Template information for a bound template template parameter.  */
 #define TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO(NODE) (TYPE_BINFO (NODE))
 
 /* Template information for an ENUMERAL_, RECORD_, or UNION_TYPE.  */
 #define TYPE_TEMPLATE_INFO(NODE)                       \
   (TREE_CODE (NODE) == ENUMERAL_TYPE                   \
    ? ENUM_TEMPLATE_INFO (NODE) :                       \
-   (TREE_CODE (NODE) == TEMPLATE_TEMPLATE_PARM         \
+   (TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM   \
     ? TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (NODE) :    \
     (TYPE_LANG_SPECIFIC (NODE)                         \
      ? CLASSTYPE_TEMPLATE_INFO (NODE)                  \
@@ -3716,8 +3715,8 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
 #define TEMPLATE_PARM_ORIG_LEVEL(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->orig_level)
 #define TEMPLATE_PARM_DECL(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->decl)
 
-/* These macros are for accessing the fields of TEMPLATE_TYPE_PARM 
-   and TEMPLATE_TEMPLATE_PARM nodes.  */
+/* These macros are for accessing the fields of TEMPLATE_TYPE_PARM, 
+   TEMPLATE_TEMPLATE_PARM and BOUND_TEMPLATE_TEMPLATE_PARM nodes.  */
 #define TEMPLATE_TYPE_PARM_INDEX(NODE) (TYPE_FIELDS (NODE))
 #define TEMPLATE_TYPE_IDX(NODE) \
   (TEMPLATE_PARM_IDX (TEMPLATE_TYPE_PARM_INDEX (NODE)))
@@ -3755,7 +3754,7 @@ enum tree_string_flags
 /* Returns the TEMPLATE_DECL associated to a TEMPLATE_TEMPLATE_PARM
    node.  */
 #define TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL(NODE)     \
-  (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (NODE)                 \
+  ((TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM)  \
    ? TYPE_TI_TEMPLATE (NODE)                           \
    : TYPE_NAME (NODE))
 
index 0f4d1c183adf9eabb398b2edf363478d58b81f3b..664d125564411a25e8948fd29b81ff3b25ae4eb8 100644 (file)
@@ -5925,7 +5925,7 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only)
            }
          else if (! IS_AGGR_TYPE (type)
                   || TREE_CODE (type) == TEMPLATE_TYPE_PARM
-                  || TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM
+                  || TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM
                   || TREE_CODE (type) == TYPENAME_TYPE)
            /* Someone else will give an error about this if needed.  */
            val = NULL_TREE;
@@ -9873,7 +9873,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
                       && TREE_CODE (TREE_OPERAND (decl, 1)) == INDIRECT_REF)
                ctype = cname;
              else if (TREE_CODE (cname) == TEMPLATE_TYPE_PARM
-                      || TREE_CODE (cname) == TEMPLATE_TEMPLATE_PARM)
+                      || TREE_CODE (cname) == BOUND_TEMPLATE_TEMPLATE_PARM)
                {
                  cp_error ("`%T::%D' is not a valid declarator", cname,
                            TREE_OPERAND (decl, 1));
@@ -12461,7 +12461,7 @@ grok_op_properties (decl, virtualp, friendp)
                    if (IS_AGGR_TYPE (arg)
                        || TREE_CODE (arg) == ENUMERAL_TYPE
                        || TREE_CODE (arg) == TEMPLATE_TYPE_PARM
-                       || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
+                       || TREE_CODE (arg) == BOUND_TEMPLATE_TEMPLATE_PARM)
                      goto foundaggr;
                  }
              cp_error
@@ -12768,7 +12768,7 @@ xref_tag (code_type_node, name, globalize)
     t = IDENTIFIER_TYPE_VALUE (name);
 
   if (t && TREE_CODE (t) != code && TREE_CODE (t) != TEMPLATE_TYPE_PARM
-      && TREE_CODE (t) != TEMPLATE_TEMPLATE_PARM)
+      && TREE_CODE (t) != BOUND_TEMPLATE_TEMPLATE_PARM)
     t = NULL_TREE;
 
   if (! globalize)
@@ -13014,7 +13014,7 @@ xref_basetypes (code_type_node, name, ref, binfo)
          || (TREE_CODE (basetype) != RECORD_TYPE
              && TREE_CODE (basetype) != TYPENAME_TYPE
              && TREE_CODE (basetype) != TEMPLATE_TYPE_PARM
-             && TREE_CODE (basetype) != TEMPLATE_TEMPLATE_PARM))
+             && TREE_CODE (basetype) != BOUND_TEMPLATE_TEMPLATE_PARM))
        {
          cp_error ("base type `%T' fails to be a struct or class type",
                    TREE_VALUE (binfo));
index 417348c4033e43df3460706437bedecaf55e701f..7fbd80c33ce5f7b7f74d3346208b29fb4b3267a3 100644 (file)
@@ -2043,7 +2043,7 @@ constructor_name_full (thing)
      tree thing;
 {
   if (TREE_CODE (thing) == TEMPLATE_TYPE_PARM
-      || TREE_CODE (thing) == TEMPLATE_TEMPLATE_PARM
+      || TREE_CODE (thing) == BOUND_TEMPLATE_TEMPLATE_PARM
       || TREE_CODE (thing) == TYPENAME_TYPE)
     thing = TYPE_NAME (thing);
   else if (IS_AGGR_TYPE_CODE (TREE_CODE (thing)))
@@ -4860,7 +4860,9 @@ arg_assoc_template_arg (k, arg)
      contribute to the set of associated namespaces.  ]  */
 
   /* Consider first template template arguments.  */
-  if (TREE_CODE (arg) == TEMPLATE_DECL)
+  if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
+    return 0;
+  else if (TREE_CODE (arg) == TEMPLATE_DECL)
     {
       tree ctx = CP_DECL_CONTEXT (arg);
 
@@ -4976,7 +4978,7 @@ arg_assoc_type (k, type)
       /* Associate the return type. */
       return arg_assoc_type (k, TREE_TYPE (type));
     case TEMPLATE_TYPE_PARM:
-    case TEMPLATE_TEMPLATE_PARM:
+    case BOUND_TEMPLATE_TEMPLATE_PARM:
       return 0;
     case TYPENAME_TYPE:
       return 0;
index 8a48360432874ddb4fdbcd382f8fe461e13d2c17..873f787de1450b1792fdd4959e6d710dcfb1b263 100644 (file)
@@ -462,22 +462,21 @@ dump_type (t, flags)
       break;
 
     case TEMPLATE_TEMPLATE_PARM:
-      if (!TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t))
-       {
-         /* For parameters inside template signature. */
-         if (TYPE_IDENTIFIER (t))
-           OB_PUTID (TYPE_IDENTIFIER (t));
-         else
-           OB_PUTS ("{anonymous template template parameter}");
-       }
+      /* For parameters inside template signature. */
+      if (TYPE_IDENTIFIER (t))
+       OB_PUTID (TYPE_IDENTIFIER (t));
       else
-       {
-         tree args = TYPE_TI_ARGS (t);
-         OB_PUTID (TYPE_IDENTIFIER (t));
-         OB_PUTC ('<');
-          dump_template_argument_list (args, flags);
-         OB_END_TEMPLATE_ID ();
-       }
+       OB_PUTS ("{anonymous template template parameter}");
+      break;
+
+    case BOUND_TEMPLATE_TEMPLATE_PARM:
+      {
+       tree args = TYPE_TI_ARGS (t);
+       OB_PUTID (TYPE_IDENTIFIER (t));
+       OB_PUTC ('<');
+        dump_template_argument_list (args, flags);
+       OB_END_TEMPLATE_ID ();
+      }
       break;
 
     case TEMPLATE_TYPE_PARM:
@@ -704,6 +703,7 @@ dump_type_prefix (t, flags)
     case RECORD_TYPE:
     case TEMPLATE_TYPE_PARM:
     case TEMPLATE_TEMPLATE_PARM:
+    case BOUND_TEMPLATE_TEMPLATE_PARM:
     case TREE_LIST:
     case TYPE_DECL:
     case TREE_VEC:
index 91449c1732056d38f4a410c1e108f5ddc2e1c1ef..7d1e3b4b546243daddca2c3b343f16d86c6ab64a 100644 (file)
@@ -1390,7 +1390,7 @@ is_aggr_type (type, or_else)
 
   if (! IS_AGGR_TYPE (type)
       && TREE_CODE (type) != TEMPLATE_TYPE_PARM
-      && TREE_CODE (type) != TEMPLATE_TEMPLATE_PARM)
+      && TREE_CODE (type) != BOUND_TEMPLATE_TEMPLATE_PARM)
     {
       if (or_else)
        cp_error ("`%T' is not an aggregate type", type);
@@ -1422,7 +1422,7 @@ get_aggr_from_typedef (name, or_else)
 
   if (! IS_AGGR_TYPE (type)
       && TREE_CODE (type) != TEMPLATE_TYPE_PARM
-      && TREE_CODE (type) != TEMPLATE_TEMPLATE_PARM)
+      && TREE_CODE (type) != BOUND_TEMPLATE_TEMPLATE_PARM)
     {
       if (or_else)
        cp_error ("type `%T' is of non-aggregate type", type);
index fb4d166baab326ca5da2622b52d532fe9481e8b6..da0448047405cbb6a66a5096c97d4470c926b72a 100644 (file)
@@ -1319,9 +1319,12 @@ write_type (type)
 
        case TEMPLATE_TEMPLATE_PARM:
          write_template_template_param (type);
-         if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (type))
-           write_template_args 
-             (TI_ARGS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (type)));
+         break;
+
+       case BOUND_TEMPLATE_TEMPLATE_PARM:
+         write_template_template_param (type);
+         write_template_args 
+           (TI_ARGS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (type)));
          break;
 
        case OFFSET_TYPE:
@@ -1624,7 +1627,8 @@ write_expression (expr)
   /* Handle template parameters. */
   if (code == TEMPLATE_TYPE_PARM 
       || code == TEMPLATE_TEMPLATE_PARM
-      ||  code == TEMPLATE_PARM_INDEX)
+      || code == BOUND_TEMPLATE_TEMPLATE_PARM
+      || code == TEMPLATE_PARM_INDEX)
     write_template_param (expr);
   /* Handle literals.  */
   else if (TREE_CODE_CLASS (code) == 'c')
@@ -1863,7 +1867,8 @@ write_pointer_to_member_type (type)
 }
 
 /* Non-terminal <template-param>.  PARM is a TEMPLATE_TYPE_PARM,
-   TEMPLATE_TEMPLATE_PARM, or a TEMPLATE_PARM_INDEX.
+   TEMPLATE_TEMPLATE_PARM, BOUND_TEMPLATE_TEMPLATE_PARM or a
+   TEMPLATE_PARM_INDEX.
 
      <template-param> ::= T </parameter/ number> _  */
 
@@ -1879,6 +1884,7 @@ write_template_param (parm)
     {
     case TEMPLATE_TYPE_PARM:
     case TEMPLATE_TEMPLATE_PARM:
+    case BOUND_TEMPLATE_TEMPLATE_PARM:
       parm_index = TEMPLATE_TYPE_IDX (parm);
       break;
 
@@ -1911,7 +1917,7 @@ write_template_template_param (parm)
   /* PARM, a TEMPLATE_TEMPLATE_PARM, is an instantiation of the
      template template parameter.  The substitution candidate here is
      only the template.  */
-  if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parm))
+  if (TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM)
     {
       template 
        = TI_TEMPLATE (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parm));
index 4c024d1e49ad610cda2eadec3614a2455062f958..1e5c4e36070092663678c2a09cfd098a928918cb 100644 (file)
@@ -446,7 +446,8 @@ build_overload_nested_name (decl)
     /* For a template type parameter, we want to output an 'Xn'
        rather than 'T' or some such. */
     if (TREE_CODE (context) == TEMPLATE_TYPE_PARM
-        || TREE_CODE (context) == TEMPLATE_TEMPLATE_PARM)
+        || TREE_CODE (context) == TEMPLATE_TEMPLATE_PARM
+        || TREE_CODE (context) == BOUND_TEMPLATE_TEMPLATE_PARM)
       build_mangled_name_for_type (context);
     else
     {
@@ -1512,26 +1513,23 @@ process_overload_item (parmtype, extra_Gcode)
       OB_PUTC ('?');
       break;
 
-    case TEMPLATE_TEMPLATE_PARM:
+    case BOUND_TEMPLATE_TEMPLATE_PARM:
       /* Find and output the original template parameter 
          declaration. */
-      if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parmtype))
-        {
-         build_mangled_template_parm_index ("tzX",
-                                            TEMPLATE_TYPE_PARM_INDEX 
-                                            (parmtype));
-          build_template_parm_names
-            (DECL_INNERMOST_TEMPLATE_PARMS (TYPE_TI_TEMPLATE (parmtype)),
-            TYPE_TI_ARGS (parmtype));
-        }
-      else
-        {
-         build_mangled_template_parm_index ("ZzX",
-                                            TEMPLATE_TYPE_PARM_INDEX 
-                                            (parmtype));
-          build_template_template_parm_names
-            (DECL_INNERMOST_TEMPLATE_PARMS (TYPE_STUB_DECL (parmtype)));
-        }
+      build_mangled_template_parm_index ("tzX",
+                                        TEMPLATE_TYPE_PARM_INDEX 
+                                        (parmtype));
+      build_template_parm_names
+       (DECL_INNERMOST_TEMPLATE_PARMS (TYPE_TI_TEMPLATE (parmtype)),
+        TYPE_TI_ARGS (parmtype));
+      break;
+
+    case TEMPLATE_TEMPLATE_PARM:
+      build_mangled_template_parm_index ("ZzX",
+                                        TEMPLATE_TYPE_PARM_INDEX 
+                                        (parmtype));
+      build_template_template_parm_names
+       (DECL_INNERMOST_TEMPLATE_PARMS (TYPE_STUB_DECL (parmtype)));
       break;
 
     case TEMPLATE_TYPE_PARM:
index 8f23d912ea686ee04184acc870aeb97f4a963162..eb6a01a6b1ad8a6c20bf9c9b13faf08611a99aa7 100644 (file)
@@ -3713,7 +3713,7 @@ bad_parm:
                  error ("type specifier omitted for parameter");
                  if (TREE_CODE ($$) == SCOPE_REF
                      && (TREE_CODE (TREE_OPERAND ($$, 0)) == TEMPLATE_TYPE_PARM
-                         || TREE_CODE (TREE_OPERAND ($$, 0)) == TEMPLATE_TEMPLATE_PARM))
+                         || TREE_CODE (TREE_OPERAND ($$, 0)) == BOUND_TEMPLATE_TEMPLATE_PARM))
                    cp_error ("  perhaps you want `typename %E' to make it a type", $$);
                  $$ = build_tree_list (integer_type_node, $$);
                }
index abf4f9b2d87ed54c512dd51ffa87b77f756e0362..cddf0f9ebd0a21936d1bfe661860cdd60f553feb 100644 (file)
@@ -3206,8 +3206,7 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
   is_tmpl_type 
     = ((TREE_CODE (arg) == TEMPLATE_DECL
        && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
-       || (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
-          && !TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (arg))
+       || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
        || (TREE_CODE (arg) == RECORD_TYPE
           && CLASSTYPE_TEMPLATE_INFO (arg)
           && TREE_CODE (TYPE_NAME (arg)) == TYPE_DECL
@@ -4187,13 +4186,13 @@ for_each_template_parm_r (tp, walk_subtrees, d)
        return error_mark_node;
       break;
 
-    case TEMPLATE_TEMPLATE_PARM:
+    case BOUND_TEMPLATE_TEMPLATE_PARM:
       /* Record template parameters such as `T' inside `TT<T>'.  */
-      if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t)
-         && for_each_template_parm (TYPE_TI_ARGS (t), fn, data))
+      if (for_each_template_parm (TYPE_TI_ARGS (t), fn, data))
        return error_mark_node;
       /* Fall through.  */
 
+    case TEMPLATE_TEMPLATE_PARM:
     case TEMPLATE_TYPE_PARM:
     case TEMPLATE_PARM_INDEX:
       if (fn && (*fn)(t, data))
@@ -4255,8 +4254,9 @@ for_each_template_parm_r (tp, walk_subtrees, d)
   return NULL_TREE;
 }
 
-/* For each TEMPLATE_TYPE_PARM, TEMPLATE_TEMPLATE_PARM, or
-   TEMPLATE_PARM_INDEX in T, call FN with the parameter and the DATA.
+/* For each TEMPLATE_TYPE_PARM, TEMPLATE_TEMPLATE_PARM, 
+   BOUND_TEMPLATE_TEMPLATE_PARM or TEMPLATE_PARM_INDEX in T, 
+   call FN with the parameter and the DATA.
    If FN returns non-zero, the iteration is terminated, and
    for_each_template_parm returns 1.  Otherwise, the iteration
    continues.  If FN never returns a non-zero value, the value
@@ -6222,6 +6222,7 @@ tsubst (t, args, complain, in_decl)
 
     case TEMPLATE_TYPE_PARM:
     case TEMPLATE_TEMPLATE_PARM:
+    case BOUND_TEMPLATE_TEMPLATE_PARM:
     case TEMPLATE_PARM_INDEX:
       {
        int idx;
@@ -6231,7 +6232,8 @@ tsubst (t, args, complain, in_decl)
        r = NULL_TREE;
 
        if (TREE_CODE (t) == TEMPLATE_TYPE_PARM
-           || TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM)
+           || TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM
+           || TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
          {
            idx = TEMPLATE_TYPE_IDX (t);
            level = TEMPLATE_TYPE_LEVEL (t);
@@ -6261,38 +6263,33 @@ tsubst (t, args, complain, in_decl)
                      (arg, CP_TYPE_QUALS (arg) | CP_TYPE_QUALS (t),
                       complain);
                  }
-               else if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM)
+               else if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
                  {
-                   if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t))
-                     {
-                       /* We are processing a type constructed from
-                          a template template parameter */
-                       tree argvec = tsubst (TYPE_TI_ARGS (t),
-                                             args, complain, in_decl);
-                       if (argvec == error_mark_node)
-                         return error_mark_node;
+                   /* We are processing a type constructed from
+                      a template template parameter */
+                   tree argvec = tsubst (TYPE_TI_ARGS (t),
+                                         args, complain, in_decl);
+                   if (argvec == error_mark_node)
+                     return error_mark_node;
                        
-                       /* We can get a TEMPLATE_TEMPLATE_PARM here when 
-                          we are resolving nested-types in the signature of 
-                          a member function templates.
-                          Otherwise ARG is a TEMPLATE_DECL and is the real 
-                          template to be instantiated.  */
-                       if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
-                         arg = TYPE_NAME (arg);
-
-                       r = lookup_template_class (arg, 
-                                                  argvec, in_decl, 
-                                                  DECL_CONTEXT (arg),
-                                                  /*entering_scope=*/0);
-                       return cp_build_qualified_type_real (r, 
-                                                            TYPE_QUALS (t),
-                                                            complain);
-                     }
-                   else
-                     /* We are processing a template argument list.  */ 
-                     return arg;
+                   /* We can get a TEMPLATE_TEMPLATE_PARM here when 
+                      we are resolving nested-types in the signature of 
+                      a member function templates.
+                      Otherwise ARG is a TEMPLATE_DECL and is the real 
+                      template to be instantiated.  */
+                   if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
+                     arg = TYPE_NAME (arg);
+
+                   r = lookup_template_class (arg, 
+                                              argvec, in_decl, 
+                                              DECL_CONTEXT (arg),
+                                              /*entering_scope=*/0);
+                   return cp_build_qualified_type_real (r, 
+                                                        TYPE_QUALS (t),
+                                                        complain);
                  }
                else
+                 /* TEMPLATE_TEMPLATE_PARM or TEMPLATE_PARM_INDEX.  */
                  return arg;
              }
          }
@@ -6312,6 +6309,7 @@ tsubst (t, args, complain, in_decl)
          {
          case TEMPLATE_TYPE_PARM:
          case TEMPLATE_TEMPLATE_PARM:
+         case BOUND_TEMPLATE_TEMPLATE_PARM:
            if (CP_TYPE_QUALS (t))
              {
                r = tsubst (TYPE_MAIN_VARIANT (t), args, complain, in_decl);
@@ -6329,8 +6327,7 @@ tsubst (t, args, complain, in_decl)
                TYPE_POINTER_TO (r) = NULL_TREE;
                TYPE_REFERENCE_TO (r) = NULL_TREE;
 
-               if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM
-                   && TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t))
+               if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
                  {
                    tree argvec = tsubst (TYPE_TI_ARGS (t), args,
                                          complain, in_decl); 
@@ -7032,6 +7029,7 @@ tsubst_copy (t, args, complain, in_decl)
     case INTEGER_TYPE:
     case TEMPLATE_TYPE_PARM:
     case TEMPLATE_TEMPLATE_PARM:
+    case BOUND_TEMPLATE_TEMPLATE_PARM:
     case TEMPLATE_PARM_INDEX:
     case POINTER_TYPE:
     case REFERENCE_TYPE:
@@ -8302,6 +8300,7 @@ unify (tparms, targs, parm, arg, strict)
 
     case TEMPLATE_TYPE_PARM:
     case TEMPLATE_TEMPLATE_PARM:
+    case BOUND_TEMPLATE_TEMPLATE_PARM:
       tparm = TREE_VALUE (TREE_VEC_ELT (tparms, 0));
 
       if (TEMPLATE_TYPE_LEVEL (parm)
@@ -8321,53 +8320,61 @@ unify (tparms, targs, parm, arg, strict)
              && TREE_CODE (tparm) != TEMPLATE_DECL))
        return 1;
 
-      if (TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM)
+      if (TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM)
        {
-         if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parm))
-           {
-             /* We arrive here when PARM does not involve template 
-                specialization.  */
+         /* ARG must be constructed from a template class.  */
+         if (TREE_CODE (arg) != RECORD_TYPE || !CLASSTYPE_TEMPLATE_INFO (arg))
+           return 1;
 
-             /* ARG must be constructed from a template class.  */
-             if (TREE_CODE (arg) != RECORD_TYPE || !CLASSTYPE_TEMPLATE_INFO (arg))
-               return 1;
+         {
+           tree parmtmpl = TYPE_TI_TEMPLATE (parm);
+           tree parmvec = TYPE_TI_ARGS (parm);
+           tree argvec = CLASSTYPE_TI_ARGS (arg);
+           tree argtmplvec
+             = DECL_INNERMOST_TEMPLATE_PARMS (CLASSTYPE_TI_TEMPLATE (arg));
+           int i;
 
-             {
-               tree parmtmpl = TYPE_TI_TEMPLATE (parm);
-               tree parmvec = TYPE_TI_ARGS (parm);
-               tree argvec = CLASSTYPE_TI_ARGS (arg);
-               tree argtmplvec
-                 = DECL_INNERMOST_TEMPLATE_PARMS (CLASSTYPE_TI_TEMPLATE (arg));
-               int i;
-
-               /* The parameter and argument roles have to be switched here 
-                  in order to handle default arguments properly.  For example, 
-                  template<template <class> class TT> void f(TT<int>) 
-                  should be able to accept vector<int> which comes from 
-                  template <class T, class Allocator = allocator> 
-                  class vector.  */
-
-               if (coerce_template_parms (argtmplvec, parmvec, parmtmpl, 0, 1)
-                   == error_mark_node)
-                 return 1;
+           /* The parameter and argument roles have to be switched here 
+              in order to handle default arguments properly.  For example, 
+              template<template <class> class TT> void f(TT<int>) 
+              should be able to accept vector<int> which comes from 
+              template <class T, class Allocator = allocator> 
+              class vector.  */
+
+           if (coerce_template_parms (argtmplvec, parmvec, parmtmpl, 0, 1)
+               == error_mark_node)
+             return 1;
          
-               /* Deduce arguments T, i from TT<T> or TT<i>.  
-                  We check each element of PARMVEC and ARGVEC individually
-                  rather than the whole TREE_VEC since they can have
-                  different number of elements.  */
+           /* Deduce arguments T, i from TT<T> or TT<i>.  
+              We check each element of PARMVEC and ARGVEC individually
+              rather than the whole TREE_VEC since they can have
+              different number of elements.  */
 
-               for (i = 0; i < TREE_VEC_LENGTH (parmvec); ++i)
-                 {
-                   tree t = TREE_VEC_ELT (parmvec, i);
+           for (i = 0; i < TREE_VEC_LENGTH (parmvec); ++i)
+             {
+               tree t = TREE_VEC_ELT (parmvec, i);
 
-                   if (unify (tparms, targs, t, 
-                              TREE_VEC_ELT (argvec, i), 
-                              UNIFY_ALLOW_NONE))
-                     return 1;
-                 }
+               if (unify (tparms, targs, t, 
+                          TREE_VEC_ELT (argvec, i), 
+                          UNIFY_ALLOW_NONE))
+                 return 1;
              }
-             arg = CLASSTYPE_TI_TEMPLATE (arg);
-           }
+         }
+         arg = CLASSTYPE_TI_TEMPLATE (arg);
+
+         /* Fall through to deduce template name.  */
+       }
+
+      if (TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM
+         || TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM)
+       {
+         /* Deduce template name TT from TT, TT<>, TT<T> and TT<i>.  */
+
+         /* Simple cases: Value already set, does match or doesn't.  */
+         if (targ != NULL_TREE && template_args_equal (targ, arg))
+           return 0;
+         else if (targ)
+           return 1;
        }
       else
        {
@@ -8388,13 +8395,13 @@ unify (tparms, targs, parm, arg, strict)
                                          /*complain=*/0);
          if (arg == error_mark_node)
            return 1;
-       }
 
-      /* Simple cases: Value already set, does match or doesn't.  */
-      if (targ != NULL_TREE && same_type_p (targ, arg))
-       return 0;
-      else if (targ)
-       return 1;
+         /* Simple cases: Value already set, does match or doesn't.  */
+         if (targ != NULL_TREE && same_type_p (targ, arg))
+           return 0;
+         else if (targ)
+           return 1;
+       }
 
       /* Make sure that ARG is not a variable-sized array.  (Note that
         were talking about variable-sized arrays (like `int[n]'),
index d3cd45eceac77bd7908146d9297bbb2a9dcc0003..5c4ac8467010fd63e92d562931e4692bc0f2f2a2 100644 (file)
@@ -75,6 +75,7 @@ print_lang_type (file, node, indent)
     {
     case TEMPLATE_TYPE_PARM:
     case TEMPLATE_TEMPLATE_PARM:
+    case BOUND_TEMPLATE_TEMPLATE_PARM:
       indent_to (file, indent + 3);
       fputs ("index ", file);
       fprintf (file, HOST_WIDE_INT_PRINT_DEC, TEMPLATE_TYPE_IDX (node));
index bf19ce8575542ae1f93f1daaa7cf32105dea5ea1..befcb99eef3d9051d69c91453348f56d1372d56f 100644 (file)
@@ -587,7 +587,7 @@ lookup_field_1 (type, name)
   register tree field;
 
   if (TREE_CODE (type) == TEMPLATE_TYPE_PARM
-      || TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM)
+      || TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
     /* The TYPE_FIELDS of a TEMPLATE_TYPE_PARM are not fields at all;
        instead TYPE_FIELDS is the TEMPLATE_PARM_INDEX.  (Miraculously,
        the code often worked even when we treated the index as a list
index 371f00f4792a1f6b72b73308afc8eb2c25eebfa5..be2459aba98b2f190b54c81b7c840b1f53342160 100644 (file)
@@ -1176,7 +1176,8 @@ build_exception_variant (type, raises)
   return v;
 }
 
-/* Given a TEMPLATE_TEMPLATE_PARM node T, create a new one together with its 
+/* Given a TEMPLATE_TEMPLATE_PARM or BOUND_TEMPLATE_TEMPLATE_PARM
+   node T, create a new one together with its 
    lang_specific field and its corresponding *_DECL node.
    If NEWARGS is not NULL_TREE, this parameter is bound with new set of
    arguments.  */
@@ -1189,9 +1190,9 @@ copy_template_template_parm (t, newargs)
   tree decl = TYPE_NAME (t);
   tree t2;
 
-  t2 = make_aggr_type (TEMPLATE_TEMPLATE_PARM);
   if (newargs == NULL_TREE)
     {
+      t2 = make_aggr_type (TREE_CODE (t));
       decl = copy_decl (decl);
 
       /* No need to copy these.  */
@@ -1201,6 +1202,7 @@ copy_template_template_parm (t, newargs)
     }
   else
     {
+      t2 = make_aggr_type (BOUND_TEMPLATE_TEMPLATE_PARM);
       decl = build_decl (TYPE_DECL, DECL_NAME (decl), NULL_TREE);
 
       /* These nodes have to be created to reflect new TYPE_DECL and template
@@ -1329,6 +1331,7 @@ walk_tree (tp, func, data)
     case STRING_CST:
     case DEFAULT_ARG:
     case TEMPLATE_TEMPLATE_PARM:
+    case BOUND_TEMPLATE_TEMPLATE_PARM:
     case TEMPLATE_PARM_INDEX:
     case TEMPLATE_TYPE_PARM:
     case REAL_TYPE:
@@ -1581,7 +1584,8 @@ copy_tree_r (tp, walk_subtrees, data)
       if (TREE_CODE (*tp) == SCOPE_STMT)
        SCOPE_STMT_BLOCK (*tp) = NULL_TREE;
     }
-  else if (code == TEMPLATE_TEMPLATE_PARM)
+  else if (code == TEMPLATE_TEMPLATE_PARM
+          || code == BOUND_TEMPLATE_TEMPLATE_PARM)
     /* These must be copied specially.  */
     *tp = copy_template_template_parm (*tp, NULL_TREE);
   else if (TREE_CODE_CLASS (code) == 't')
index 015df0e78ad18a0c9f2e08c4da5027f3e6a536e6..823aaec624fb74a872c3b2c1471392344c3e15bd 100644 (file)
@@ -1012,6 +1012,7 @@ comptypes (t1, t2, strict)
   switch (TREE_CODE (t1))
     {
     case TEMPLATE_TEMPLATE_PARM:
+    case BOUND_TEMPLATE_TEMPLATE_PARM:
       if (TEMPLATE_TYPE_IDX (t1) != TEMPLATE_TYPE_IDX (t2)
          || TEMPLATE_TYPE_LEVEL (t1) != TEMPLATE_TYPE_LEVEL (t2))
        return 0;
@@ -1019,8 +1020,7 @@ comptypes (t1, t2, strict)
              (DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t1)),
               DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t2))))
        return 0;
-      if (!TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t1) 
-         && ! TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t2))
+      if (TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM)
        return 1;
       /* Don't check inheritance.  */
       strict = COMPARE_STRICT;
@@ -1030,7 +1030,7 @@ comptypes (t1, t2, strict)
     case UNION_TYPE:
       if (TYPE_TEMPLATE_INFO (t1) && TYPE_TEMPLATE_INFO (t2)
          && (TYPE_TI_TEMPLATE (t1) == TYPE_TI_TEMPLATE (t2)
-             || TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM))
+             || TREE_CODE (t1) == BOUND_TEMPLATE_TEMPLATE_PARM))
        val = comp_template_args (TYPE_TI_ARGS (t1),
                                  TYPE_TI_ARGS (t2));
     look_hard:
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ttp62.C b/gcc/testsuite/g++.old-deja/g++.pt/ttp62.C
new file mode 100644 (file)
index 0000000..77013c4
--- /dev/null
@@ -0,0 +1,27 @@
+// Origin: Ewgenij Gawrilow <gawrilow@math.TU-Berlin.DE>
+
+#include <iostream>
+
+template <template <class X> class B, class A>
+struct is_instance_of {
+   enum { answer=false };
+};
+
+template <template <class X> class B, class T>
+struct is_instance_of<B, B<T> > {
+   enum { answer=true };
+};
+
+template <class X> struct C { };
+template <class X> struct D { };
+
+template <class T>
+bool is_C (const T&) {
+   return is_instance_of<C,T>::answer;
+};
+
+int main() {
+   cout << "should be true: " << is_C(C<int>()) << endl;
+   cout << "should be false: " << is_C(D<int>()) << endl;
+   return 0;
+}