summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-01-16 20:21:20 +0000
committerDouglas Gregor <dgregor@apple.com>2010-01-16 20:21:20 +0000
commitf5974fa0d5a8bc4055fb2a5c0e52dbd5dc3c62c9 (patch)
treed24671aa9a5c8da1ffde4f2bd60d372c99e7500e
parentfaf85c0dbe25c2f13a33483f0eece8646d0fc3dc (diff)
downloadbcm5719-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.h9
-rw-r--r--clang/lib/AST/DeclBase.cpp11
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp10
-rw-r--r--clang/test/SemaTemplate/instantiate-local-class.cpp12
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>();
OpenPOWER on IntegriCloud