]> granicus.if.org Git - clang/commitdiff
Parse friend template ids as types instead of ending up in
authorJohn McCall <rjmccall@apple.com>
Wed, 14 Apr 2010 00:24:33 +0000 (00:24 +0000)
committerJohn McCall <rjmccall@apple.com>
Wed, 14 Apr 2010 00:24:33 +0000 (00:24 +0000)
ActOnClassTemplateSpecialization and being very confused.
Fixes PR6514 (for non-templated-scope friends).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101198 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Parse/ParseDeclCXX.cpp
test/CXX/temp/temp.decls/temp.friend/p1.cpp

index c6df57193b61072a31c2becfdb911ff2bd10c127..60aee6abd121f752ebca9920a4501c53bbf8aaca 100644 (file)
@@ -780,9 +780,6 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
   Action::DeclResult TagOrTempResult = true; // invalid
   Action::TypeResult TypeResult = true; // invalid
 
-  // FIXME: When TUK == TUK_Reference and we have a template-id, we need
-  // to turn that template-id into a type.
-
   bool Owned = false;
   if (TemplateId) {
     // Explicit specialization, class template partial specialization,
@@ -806,7 +803,14 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
                                              TemplateArgsPtr,
                                              TemplateId->RAngleLoc,
                                              AttrList);
-    } else if (TUK == Action::TUK_Reference) {
+
+    // Friend template-ids are treated as references unless
+    // they have template headers, in which case they're ill-formed
+    // (FIXME: "template <class T> friend class A<T>::B<int>;").
+    // We diagnose this error in ActOnClassTemplateSpecialization.
+    } else if (TUK == Action::TUK_Reference ||
+               (TUK == Action::TUK_Friend &&
+                TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) {
       TypeResult
         = Actions.ActOnTemplateIdType(TemplateTy::make(TemplateId->Template),
                                       TemplateId->TemplateNameLoc,
index 41cf3632b16f0d1f8be8b36515af065bdcfaa296..7604a23edb082689152ffd0f22577a72f219f39f 100644 (file)
@@ -276,3 +276,20 @@ namespace test12 {
     return Foo<long>(t, true);
   }
 }
+
+// PR6514
+namespace test13 {
+  template <int N, template <int> class Temp>
+  class Role : public Temp<N> {
+    friend class Temp<N>;
+    int x;
+  };
+
+  template <int N> class Foo {
+    void foo(Role<N, test13::Foo> &role) {
+      (void) role.x;
+    }
+  };
+
+  template class Foo<0>;
+}