diff options
| -rw-r--r-- | clang/include/clang/AST/DeclBase.h | 9 | ||||
| -rw-r--r-- | clang/lib/AST/DeclBase.cpp | 11 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 10 | ||||
| -rw-r--r-- | clang/test/SemaTemplate/instantiate-local-class.cpp | 12 |
4 files changed, 33 insertions, 9 deletions
diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 497f86347a8..0902b450a4a 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/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/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 3afb4e44f3e..76ff83448a0 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/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/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index e909c4f0b9b..e6be5389cd0 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/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/clang/test/SemaTemplate/instantiate-local-class.cpp b/clang/test/SemaTemplate/instantiate-local-class.cpp new file mode 100644 index 00000000000..5cb63b49ee9 --- /dev/null +++ b/clang/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>(); |

