diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-06-30 17:20:14 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-06-30 17:20:14 +0000 |
commit | b33fe2ff12676bff9db595fdf77e29014d7ba397 (patch) | |
tree | deba668430364d13f17ccb4dc34fdd650560eaa0 /lib/Sema/SemaTemplateInstantiateDecl.cpp | |
parent | 5f6c19419184da428ad8982c1a5d706dbf4896ed (diff) |
When recursively instantiating function templates, keep track of the
instantiation stack so that we provide a full instantiation
backtrace. Previously, we performed all of the instantiations implied
by the recursion, but each looked like a "top-level" instantiation.
The included test case tests the previous fix for the instantiation of
DeclRefExprs. Note that the "instantiated from" diagnostics still
don't tell us which template arguments we're instantiating with.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74540 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 7053bba8ed..769e0d222a 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -663,10 +663,19 @@ TemplateDeclInstantiator::InitMethodInstantiation(CXXMethodDecl *New, /// \brief Instantiate the definition of the given function from its /// template. /// +/// \param PointOfInstantiation the point at which the instantiation was +/// required. Note that this is not precisely a "point of instantiation" +/// for the function, but it's close. +/// /// \param Function the already-instantiated declaration of a -/// function. +/// function template specialization or member function of a class template +/// specialization. +/// +/// \param Recursive if true, recursively instantiates any functions that +/// are required by this instantiation. void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, - FunctionDecl *Function) { + FunctionDecl *Function, + bool Recursive) { if (Function->isInvalidDecl()) return; @@ -689,6 +698,13 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, if (Inst) return; + // If we're performing recursive template instantiation, create our own + // queue of pending implicit instantiations that we will instantiate later, + // while we're still within our own instantiation context. + std::deque<PendingImplicitInstantiation> SavedPendingImplicitInstantiations; + if (Recursive) + PendingImplicitInstantiations.swap(SavedPendingImplicitInstantiations); + ActOnStartOfFunctionDef(0, DeclPtrTy::make(Function)); // Introduce a new scope where local variable instantiations will be @@ -717,6 +733,15 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, DeclGroupRef DG(Function); Consumer.HandleTopLevelDecl(DG); + + if (Recursive) { + // Instantiate any pending implicit instantiations found during the + // instantiation of this template. + PerformPendingImplicitInstantiations(); + + // Restore the set of pending implicit instantiations. + PendingImplicitInstantiations.swap(SavedPendingImplicitInstantiations); + } } /// \brief Instantiate the definition of the given variable from its @@ -859,11 +884,11 @@ NamedDecl * Sema::InstantiateCurrentDeclRef(NamedDecl *D) { void Sema::PerformPendingImplicitInstantiations() { while (!PendingImplicitInstantiations.empty()) { PendingImplicitInstantiation Inst = PendingImplicitInstantiations.front(); - PendingImplicitInstantiations.pop(); + PendingImplicitInstantiations.pop_front(); if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Inst.first)) if (!Function->getBody()) - InstantiateFunctionDefinition(/*FIXME:*/Inst.second, Function); + InstantiateFunctionDefinition(/*FIXME:*/Inst.second, Function, true); // FIXME: instantiate static member variables } |