diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-04-20 07:12:26 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-04-20 07:12:26 +0000 |
| commit | 61e582f6bccfffdcd3ba93a5bf5a7e1c5b882a6d (patch) | |
| tree | bc9aa9b868b3c61ed1fdfee6dd46b33471cdfd9c | |
| parent | abadc660e081d6bebb0f19f441dfb16c3bd08412 (diff) | |
| download | bcm5719-llvm-61e582f6bccfffdcd3ba93a5bf5a7e1c5b882a6d.tar.gz bcm5719-llvm-61e582f6bccfffdcd3ba93a5bf5a7e1c5b882a6d.zip | |
Replace r155185 with a better fix, which also addresses PR12557. When looking
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.
llvm-svn: 155187
| -rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 6 | ||||
| -rw-r--r-- | clang/test/SemaTemplate/class-template-decl.cpp | 10 | ||||
| -rw-r--r-- | clang/test/SemaTemplate/friend-template.cpp | 24 |
3 files changed, 27 insertions, 13 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index a0b996beecd..e16e7d67c63 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -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 diff --git a/clang/test/SemaTemplate/class-template-decl.cpp b/clang/test/SemaTemplate/class-template-decl.cpp index 4d69ac4f713..bd2accee3c2 100644 --- a/clang/test/SemaTemplate/class-template-decl.cpp +++ b/clang/test/SemaTemplate/class-template-decl.cpp @@ -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; - }; -} diff --git a/clang/test/SemaTemplate/friend-template.cpp b/clang/test/SemaTemplate/friend-template.cpp index 9c95fa0151c..2b05527cf17 100644 --- a/clang/test/SemaTemplate/friend-template.cpp +++ b/clang/test/SemaTemplate/friend-template.cpp @@ -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; +} |

