diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-01-16 22:29:39 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-01-16 22:29:39 +0000 |
commit | 60406bede202b66ebdd98cac0c38d20f9698aeca (patch) | |
tree | ad7fd0c5b7373c5a0cd72e0547f3337f1cce40e2 /lib/Sema/SemaTemplateInstantiateDecl.cpp | |
parent | ce757a7a1ee905f87551996a69da3e95e8afeeb7 (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.cpp | 31 |
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)) { |