aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplateInstantiateDecl.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-01-16 22:29:39 +0000
committerDouglas Gregor <dgregor@apple.com>2010-01-16 22:29:39 +0000
commit60406bede202b66ebdd98cac0c38d20f9698aeca (patch)
treead7fd0c5b7373c5a0cd72e0547f3337f1cce40e2 /lib/Sema/SemaTemplateInstantiateDecl.cpp
parentce757a7a1ee905f87551996a69da3e95e8afeeb7 (diff)
Introduce a second queue of "local" pending implicit instantiation,
which are instantiations of the member functions of local classes. These implicit instantiations have to occur at the same time as---and in the same local instantiation scope as---the enclosing function, since the member functions of the local class can refer to locals within the enclosing function. This should really, really fix PR5764. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93666 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp31
1 files changed, 25 insertions, 6 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index e6be5389cd..98619f3a16 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1653,8 +1653,14 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
ActOnStartOfFunctionDef(0, DeclPtrTy::make(Function));
// Introduce a new scope where local variable instantiations will be
- // recorded.
- LocalInstantiationScope Scope(*this);
+ // recorded, unless we're actually a member function within a local
+ // class, in which case we need to merge our results with the parent
+ // scope (of the enclosing function).
+ bool MergeWithParentScope = false;
+ if (CXXRecordDecl *Rec = dyn_cast<CXXRecordDecl>(Function->getDeclContext()))
+ MergeWithParentScope = Rec->isLocalClass();
+
+ LocalInstantiationScope Scope(*this, MergeWithParentScope);
// Introduce the instantiated function parameters into the local
// instantiation scope.
@@ -1691,6 +1697,11 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
DeclGroupRef DG(Function);
Consumer.HandleTopLevelDecl(DG);
+ // This class may have local implicit instantiations that need to be
+ // instantiation within this scope.
+ PerformPendingImplicitInstantiations(/*LocalOnly=*/true);
+ Scope.Exit();
+
if (Recursive) {
// Instantiate any pending implicit instantiations found during the
// instantiation of this template.
@@ -2223,10 +2234,18 @@ NamedDecl *Sema::FindInstantiatedDecl(NamedDecl *D,
/// \brief Performs template instantiation for all implicit template
/// instantiations we have seen until this point.
-void Sema::PerformPendingImplicitInstantiations() {
- while (!PendingImplicitInstantiations.empty()) {
- PendingImplicitInstantiation Inst = PendingImplicitInstantiations.front();
- PendingImplicitInstantiations.pop_front();
+void Sema::PerformPendingImplicitInstantiations(bool LocalOnly) {
+ while (!PendingLocalImplicitInstantiations.empty() ||
+ (!LocalOnly && !PendingImplicitInstantiations.empty())) {
+ PendingImplicitInstantiation Inst;
+
+ if (PendingLocalImplicitInstantiations.empty()) {
+ Inst = PendingImplicitInstantiations.front();
+ PendingImplicitInstantiations.pop_front();
+ } else {
+ Inst = PendingLocalImplicitInstantiations.front();
+ PendingLocalImplicitInstantiations.pop_front();
+ }
// Instantiate function definitions
if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Inst.first)) {