diff options
| author | Douglas Gregor <dgregor@apple.com> | 2010-01-16 20:21:20 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2010-01-16 20:21:20 +0000 |
| commit | f5974fa0d5a8bc4055fb2a5c0e52dbd5dc3c62c9 (patch) | |
| tree | d24671aa9a5c8da1ffde4f2bd60d372c99e7500e | |
| parent | faf85c0dbe25c2f13a33483f0eece8646d0fc3dc (diff) | |
| download | bcm5719-llvm-f5974fa0d5a8bc4055fb2a5c0e52dbd5dc3c62c9.tar.gz bcm5719-llvm-f5974fa0d5a8bc4055fb2a5c0e52dbd5dc3c62c9.zip | |
When we are instantiating a member function of a local class, be sure
to merge the local instantiation scope with the outer local
instantiation scope, so that we can instantiate declarations from the
function owning the local class. Fixes an assert while instantiating
Boost.MPL's BOOST_MPL_ASSERT_MSG.
llvm-svn: 93651
| -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>(); |

