diff options
| author | Douglas Gregor <dgregor@apple.com> | 2009-10-09 21:11:42 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2009-10-09 21:11:42 +0000 |
| commit | 7f34baeb4b28f5d96c2b60113cb5e7808ecf7963 (patch) | |
| tree | c54f7088e07b4564e8b960b5087c38be209d9429 | |
| parent | e19c1810d72d4d23b216595f30aaec867f024399 (diff) | |
| download | bcm5719-llvm-7f34baeb4b28f5d96c2b60113cb5e7808ecf7963.tar.gz bcm5719-llvm-7f34baeb4b28f5d96c2b60113cb5e7808ecf7963.zip | |
When declaring a friend class template, we may end up finding an
injected-class-name (e.g., when we're referring to other
specializations of the current class template). Make sure that we see
the template rather than the injected-class-name. Fixes PR4768.
llvm-svn: 83672
| -rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 16 | ||||
| -rw-r--r-- | clang/test/SemaTemplate/friend-template.cpp | 16 |
2 files changed, 32 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 219d73146ea..3ee257a94eb 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -616,6 +616,22 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, // whether this is a valid redeclaration. ClassTemplateDecl *PrevClassTemplate = dyn_cast_or_null<ClassTemplateDecl>(PrevDecl); + + // We may have found the injected-class-name of a class template, + // class template partial specialization, or class template specialization. + // In these cases, grab the template that is being defined or specialized. + if (!PrevClassTemplate && PrevDecl && isa<CXXRecordDecl>(PrevDecl) && + cast<CXXRecordDecl>(PrevDecl)->isInjectedClassName()) { + PrevDecl = cast<CXXRecordDecl>(PrevDecl->getDeclContext()); + PrevClassTemplate + = cast<CXXRecordDecl>(PrevDecl)->getDescribedClassTemplate(); + if (!PrevClassTemplate && isa<ClassTemplateSpecializationDecl>(PrevDecl)) { + PrevClassTemplate + = cast<ClassTemplateSpecializationDecl>(PrevDecl) + ->getSpecializedTemplate(); + } + } + if (PrevClassTemplate) { // Ensure that the template parameter lists are compatible. if (!TemplateParameterListsAreEqual(TemplateParams, diff --git a/clang/test/SemaTemplate/friend-template.cpp b/clang/test/SemaTemplate/friend-template.cpp index df27c920b7b..9a483aeb5b1 100644 --- a/clang/test/SemaTemplate/friend-template.cpp +++ b/clang/test/SemaTemplate/friend-template.cpp @@ -28,3 +28,19 @@ namespace N { template<typename T> void f0(T) { } template<typename T> void f1(T) { } // expected-error{{redefinition}} } + +// PR4768 +template<typename T> +struct X0 { + template<typename U> friend struct X0; +}; + +template<typename T> +struct X0<T*> { + template<typename U> friend struct X0; +}; + +template<> +struct X0<int> { + template<typename U> friend struct X0; +}; |

