* friend.c (make_friend_class): Handle template template parameters.
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 31 Aug 2012 02:50:08 +0000 (02:50 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 31 Aug 2012 02:50:08 +0000 (02:50 +0000)
* parser.c (cp_parser_template_declaration_after_export): Likewise.
* pt.c (tsubst_friend_class): Likewise.
(instantiate_class_template_1): Likewise
* decl.c (check_elaborated_type_specifier): Likewise.
(lookup_and_check_tag): Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@190828 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/friend.c
gcc/cp/parser.c
gcc/cp/pt.c

index f334778..fc49329 100644 (file)
@@ -1,5 +1,12 @@
 2012-08-30  Jason Merrill  <jason@redhat.com>
 
+       * friend.c (make_friend_class): Handle template template parameters.
+       * parser.c (cp_parser_template_declaration_after_export): Likewise.
+       * pt.c (tsubst_friend_class): Likewise.
+       (instantiate_class_template_1): Likewise
+       * decl.c (check_elaborated_type_specifier): Likewise.
+       (lookup_and_check_tag): Likewise.
+
        * pt.c (get_class_bindings): Call coerce_template_parms.  Add
        main_tmpl parameter.
        (more_specialized_class): Add main_tmpl parameter.
index 19485fc..c909dea 100644 (file)
@@ -11484,9 +11484,10 @@ check_elaborated_type_specifier (enum tag_types tag_code,
             type, tag_name (tag_code));
       return error_mark_node;
     }
-  /* Accept bound template template parameters.  */
+  /* Accept template template parameters.  */
   else if (allow_template_p
-          && TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
+          && (TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM
+              || TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM))
     ;
   /*   [dcl.type.elab]
 
@@ -11574,7 +11575,9 @@ lookup_and_check_tag (enum tag_types tag_code, tree name,
   else
     decl = lookup_type_scope (name, scope);
 
-  if (decl && DECL_CLASS_TEMPLATE_P (decl))
+  if (decl
+      && (DECL_CLASS_TEMPLATE_P (decl)
+         || DECL_TEMPLATE_TEMPLATE_PARM_P (decl)))
     decl = DECL_TEMPLATE_RESULT (decl);
 
   if (decl && TREE_CODE (decl) == TYPE_DECL)
@@ -11679,6 +11682,9 @@ xref_tag_1 (enum tag_types tag_code, tree name,
       && template_class_depth (current_class_type)
       && template_header_p)
     {
+      if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM)
+       return t;
+
       /* Since SCOPE is not TS_CURRENT, we are not looking at a
         definition of this tag.  Since, in addition, we are currently
         processing a (member) template declaration of a template
index d0cbaed..d4548ff 100644 (file)
@@ -224,7 +224,8 @@ make_friend_class (tree type, tree friend_type, bool complain)
   int class_template_depth = template_class_depth (type);
   int friend_depth = processing_template_decl - class_template_depth;
 
-  if (! MAYBE_CLASS_TYPE_P (friend_type))
+  if (! MAYBE_CLASS_TYPE_P (friend_type)
+      && TREE_CODE (friend_type) != TEMPLATE_TEMPLATE_PARM)
     {
       /* N1791: If the type specifier in a friend declaration designates a
         (possibly cv-qualified) class type, that class is declared as a
@@ -349,6 +350,8 @@ make_friend_class (tree type, tree friend_type, bool complain)
       error ("template parameter type %qT declared %<friend%>", friend_type);
       return;
     }
+  else if (TREE_CODE (friend_type) == TEMPLATE_TEMPLATE_PARM)
+    friend_type = TYPE_NAME (friend_type);
   else if (!CLASSTYPE_TEMPLATE_INFO (friend_type))
     {
       /* template <class T> friend class A; where A is not a template */
index 0f897c9..091a967 100644 (file)
@@ -21240,7 +21240,9 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
 
          decl = finish_member_template_decl (decl);
        }
-      else if (friend_p && decl && TREE_CODE (decl) == TYPE_DECL)
+      else if (friend_p && decl
+              && (TREE_CODE (decl) == TYPE_DECL
+                  || DECL_TYPE_TEMPLATE_P (decl)))
        make_friend_class (current_class_type, TREE_TYPE (decl),
                           /*complain=*/true);
     }
index 792e9d1..6506a67 100644 (file)
@@ -8152,6 +8152,12 @@ tsubst_friend_class (tree friend_tmpl, tree args)
   tree tmpl;
   tree context;
 
+  if (DECL_TEMPLATE_TEMPLATE_PARM_P (friend_tmpl))
+    {
+      tree t = tsubst (TREE_TYPE (friend_tmpl), args, tf_none, NULL_TREE);
+      return TREE_TYPE (t);
+    }
+
   context = CP_DECL_CONTEXT (friend_tmpl);
 
   if (context != global_namespace)
@@ -8736,7 +8742,8 @@ instantiate_class_template_1 (tree type)
        }
       else
        {
-         if (TYPE_P (t) || DECL_CLASS_TEMPLATE_P (t))
+         if (TYPE_P (t) || DECL_CLASS_TEMPLATE_P (t)
+             || DECL_TEMPLATE_TEMPLATE_PARM_P (t))
            {
              /* Build new CLASSTYPE_FRIEND_CLASSES.  */