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 | 7f792cf329578f0b75d4b5676464bde602e467bb (patch) | |
tree | dcff6177142787f9decf7207d1d6147bdf4169cd /clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | |
parent | 520442b32c4918097b3f874206e570e40b0d66d6 (diff) | |
download | bcm5719-llvm-7f792cf329578f0b75d4b5676464bde602e467bb.tar.gz bcm5719-llvm-7f792cf329578f0b75d4b5676464bde602e467bb.zip |
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.
llvm-svn: 93666
Diffstat (limited to 'clang/lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index e6be5389cd0..98619f3a16b 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/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)) { |