diff options
-rw-r--r-- | include/clang/AST/DeclBase.h | 9 | ||||
-rw-r--r-- | lib/AST/DeclBase.cpp | 11 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 10 | ||||
-rw-r--r-- | test/SemaTemplate/instantiate-local-class.cpp | 12 |
4 files changed, 33 insertions, 9 deletions
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 497f86347a..0902b450a4 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -1017,13 +1017,8 @@ private: }; inline bool Decl::isTemplateParameter() const { - return getKind() == TemplateTypeParm || getKind() == NonTypeTemplateParm; -} - -inline bool Decl::isDefinedOutsideFunctionOrMethod() const { - if (getDeclContext()) - return !getDeclContext()->getLookupContext()->isFunctionOrMethod(); - return true; + return getKind() == TemplateTypeParm || getKind() == NonTypeTemplateParm || + getKind() == TemplateTemplateParm; } } // end clang. diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 3afb4e44f3..76ff83448a 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -102,6 +102,17 @@ bool Decl::isFunctionOrFunctionTemplate() const { return isa<FunctionDecl>(this) || isa<FunctionTemplateDecl>(this); } +bool Decl::isDefinedOutsideFunctionOrMethod() const { + for (const DeclContext *DC = getDeclContext(); + DC && !DC->isTranslationUnit(); + DC = DC->getParent()) + if (DC->isFunctionOrMethod()) + return false; + + return true; +} + + //===----------------------------------------------------------------------===// // PrettyStackTraceDecl Implementation //===----------------------------------------------------------------------===// diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index e909c4f0b9..e6be5389cd 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -717,7 +717,10 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, return Info->Function; } - Sema::LocalInstantiationScope Scope(SemaRef, TemplateParams != 0); + bool MergeWithParentScope = (TemplateParams != 0) || + !(isa<Decl>(Owner) && + cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod()); + Sema::LocalInstantiationScope Scope(SemaRef, MergeWithParentScope); llvm::SmallVector<ParmVarDecl *, 4> Params; QualType T = SubstFunctionType(D, Params); @@ -844,7 +847,10 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, return Info->Function; } - Sema::LocalInstantiationScope Scope(SemaRef, TemplateParams != 0); + bool MergeWithParentScope = (TemplateParams != 0) || + !(isa<Decl>(Owner) && + cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod()); + Sema::LocalInstantiationScope Scope(SemaRef, MergeWithParentScope); llvm::SmallVector<ParmVarDecl *, 4> Params; QualType T = SubstFunctionType(D, Params); diff --git a/test/SemaTemplate/instantiate-local-class.cpp b/test/SemaTemplate/instantiate-local-class.cpp new file mode 100644 index 0000000000..5cb63b49ee --- /dev/null +++ b/test/SemaTemplate/instantiate-local-class.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -verify %s +template<typename T> +void f0() { + struct X; + typedef struct Y { + T (X::* f1())(int) { return 0; } + } Y2; + + Y2 y = Y(); +} + +template void f0<int>(); |