diff options
| author | Eli Friedman <eli.friedman@gmail.com> | 2009-12-08 05:40:03 +0000 |
|---|---|---|
| committer | Eli Friedman <eli.friedman@gmail.com> | 2009-12-08 05:40:03 +0000 |
| commit | 7316819fcf056e26d159b7f8ac0f7d9448c4e40f (patch) | |
| tree | 80a35f980f89968d98689cff388f6ec95d140a4f | |
| parent | ff09559a8f7eb5ad8a6c77a348b24fdad6d0b9bf (diff) | |
| download | bcm5719-llvm-7316819fcf056e26d159b7f8ac0f7d9448c4e40f.tar.gz bcm5719-llvm-7316819fcf056e26d159b7f8ac0f7d9448c4e40f.zip | |
Fix for PR5710: make sure to put function template specializations into the
DeclContext, so they don't completely disappear from the AST.
I don't particularly like this fix, but I don't see any obviously better way
to deal with it, and I think it's pretty clearly an improvement; comments
welcome.
llvm-svn: 90835
| -rw-r--r-- | clang/lib/AST/DeclBase.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 8 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/function-template-explicit-specialization.cpp | 13 |
3 files changed, 20 insertions, 4 deletions
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index f276faf1bee..c557e615e78 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -741,6 +741,9 @@ void DeclContext::makeDeclVisibleInContext(NamedDecl *D, bool Recoverable) { // from being visible? if (isa<ClassTemplateSpecializationDecl>(D)) return; + if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) + if (FD->isFunctionTemplateSpecialization()) + return; DeclContext *PrimaryContext = getPrimaryContext(); if (PrimaryContext != this) { diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index bb3f8694250..472dc94bc5a 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -379,7 +379,9 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext) { // scope. if ((isa<FunctionTemplateDecl>(D) && cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->isOutOfLine()) || - (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isOutOfLine()) || + (isa<FunctionDecl>(D) && + (cast<FunctionDecl>(D)->isFunctionTemplateSpecialization() || + cast<FunctionDecl>(D)->isOutOfLine())) || (isa<VarDecl>(D) && cast<VarDecl>(D)->isOutOfLine())) return; @@ -2023,9 +2025,7 @@ Sema::HandleDeclarator(Scope *S, Declarator &D, // If this has an identifier and is not an invalid redeclaration or // function template specialization, add it to the scope stack. - if (Name && !(Redeclaration && New->isInvalidDecl()) && - !(isa<FunctionDecl>(New) && - cast<FunctionDecl>(New)->isFunctionTemplateSpecialization())) + if (Name && !(Redeclaration && New->isInvalidDecl())) PushOnScopeChains(New, S); return DeclPtrTy::make(New); diff --git a/clang/test/CodeGenCXX/function-template-explicit-specialization.cpp b/clang/test/CodeGenCXX/function-template-explicit-specialization.cpp new file mode 100644 index 00000000000..046bc325a5d --- /dev/null +++ b/clang/test/CodeGenCXX/function-template-explicit-specialization.cpp @@ -0,0 +1,13 @@ +// RUN: clang-cc -emit-llvm %s -o - | FileCheck %s + +template<typename T> void a(T); +template<> void a(int) {} + +// CHECK: define void @_Z1aIiEvT_ + +namespace X { +template<typename T> void b(T); +template<> void b(int) {} +} + +// CHECK: define void @_ZN1X1bIiEEvT_ |

