aboutsummaryrefslogtreecommitdiff
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
commit79c2278a66d8fc0943774d1b7c71a32f7764e1e2 (patch)
tree39d2ef92c12f76c7285ae2e3d783350fcfcabf9d
parentdfa4fa0fc5b78a91c74db84fce305771c2038229 (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93651 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/DeclBase.h9
-rw-r--r--lib/AST/DeclBase.cpp11
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp10
-rw-r--r--test/SemaTemplate/instantiate-local-class.cpp12
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>();