]> granicus.if.org Git - clang/commitdiff
Replace r155185 with a better fix, which also addresses PR12557. When looking
authorRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 20 Apr 2012 07:12:26 +0000 (07:12 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 20 Apr 2012 07:12:26 +0000 (07:12 +0000)
up an elaborated type specifier in a friend declaration, only look for type
declarations, per [basic.lookup.elab]p2. If we know that the redeclaration
lookup for a friend class template in a dependent context finds a non-template,
don't delay the diagnostic to instantiation time.

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

lib/Sema/SemaTemplate.cpp
test/SemaTemplate/class-template-decl.cpp
test/SemaTemplate/friend-template.cpp

index a0b996beecd3c81586eb1ae6b55ebf44d52ee8e6..e16e7d67c63d5b3a2aaf4d6922c77ff4145fa72e 100644 (file)
@@ -867,7 +867,7 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
 
   // Find any previous declaration with this name.
   DeclContext *SemanticContext;
-  LookupResult Previous(*this, Name, NameLoc, LookupOrdinaryName,
+  LookupResult Previous(*this, Name, NameLoc, LookupTagName,
                         ForRedeclaration);
   if (SS.isNotEmpty() && !SS.isInvalid()) {
     SemanticContext = computeDeclContext(SS, true);
@@ -938,7 +938,7 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
       while (!OutermostContext->isFileContext())
         OutermostContext = OutermostContext->getLookupParent();
 
-      if (PrevClassTemplate &&
+      if (PrevDecl &&
           (OutermostContext->Equals(PrevDecl->getDeclContext()) ||
            OutermostContext->Encloses(PrevDecl->getDeclContext()))) {
         SemanticContext = PrevDecl->getDeclContext();
@@ -951,7 +951,7 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
       }
     }
 
-    if (CurContext->isDependentContext()) {
+    if (CurContext->isDependentContext() && PrevClassTemplate) {
       // If this is a dependent context, we don't want to link the friend
       // class template to the template in scope, because that would perform
       // checking of the template parameter lists that can't be performed
index 4d69ac4f7136632ba40291ff4acf9d6ecfaed76b..bd2accee3c215ddb00b7e1829736b22576c8b361 100644 (file)
@@ -94,13 +94,3 @@ namespace rdar9676205 {
     };
   };
 }
-
-namespace Redecl {
-  struct S {
-    int packaged_task;
-    template<typename> class future {
-      template<typename> friend class packaged_task;
-    };
-    future<void> share;
-  };
-}
index 9c95fa0151c144dad0290169503990efb1fc04ad..2b05527cf171489e852f0a3a1cf6d1428a36edb1 100644 (file)
@@ -243,3 +243,27 @@ namespace rdar11147355 {
   
   A<double>::B<double>  ab;
 }
+
+namespace RedeclUnrelated {
+  struct S {
+    int packaged_task;
+    template<typename> class future {
+      template<typename> friend class packaged_task;
+    };
+    future<void> share;
+  };
+}
+
+namespace PR12557 {
+  template <typename>
+  struct Foo;
+
+  template <typename Foo_>
+  struct Bar {
+    typedef Foo_  Foo; // expected-note {{previous}}
+
+    template <typename> friend struct Foo; // expected-error {{redefinition of 'Foo' as different kind of symbol}}
+  };
+
+  Bar<int> b;
+}