summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-06-30 17:20:14 +0000
committerDouglas Gregor <dgregor@apple.com>2009-06-30 17:20:14 +0000
commitdda7ced32ed79f4d60e89d2b64cd2ee041b66616 (patch)
tree32e37d6a4b2d613fe7a8f07f4647c2b50a133158 /clang/lib
parentb2b37c62d0dc22089889321a5cd1676e4f70f78c (diff)
downloadbcm5719-llvm-dda7ced32ed79f4d60e89d2b64cd2ee041b66616.tar.gz
bcm5719-llvm-dda7ced32ed79f4d60e89d2b64cd2ee041b66616.zip
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. llvm-svn: 74540
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/Sema.h7
-rw-r--r--clang/lib/Sema/SemaExpr.cpp2
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp33
3 files changed, 34 insertions, 8 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
index 42c43291a96..308a78c80c1 100644
--- a/clang/lib/Sema/Sema.h
+++ b/clang/lib/Sema/Sema.h
@@ -29,9 +29,9 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/OwningPtr.h"
+#include <deque>
#include <list>
#include <string>
-#include <queue>
#include <vector>
namespace llvm {
@@ -2581,7 +2581,7 @@ public:
/// \brief The queue of implicit template instantiations that are required
/// but have not yet been performed.
- std::queue<PendingImplicitInstantiation> PendingImplicitInstantiations;
+ std::deque<PendingImplicitInstantiation> PendingImplicitInstantiations;
void PerformPendingImplicitInstantiations();
@@ -2636,7 +2636,8 @@ public:
const TemplateArgumentList &TemplateArgs);
void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
- FunctionDecl *Function);
+ FunctionDecl *Function,
+ bool Recursive = false);
void InstantiateVariableDefinition(VarDecl *Var);
NamedDecl *InstantiateCurrentDeclRef(NamedDecl *D);
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 1c5b76075e0..d66b002578b 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -5641,7 +5641,7 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {
// instantiated, naturally).
if (Function->getInstantiatedFromMemberFunction() ||
Function->getPrimaryTemplate())
- PendingImplicitInstantiations.push(std::make_pair(Function, Loc));
+ PendingImplicitInstantiations.push_back(std::make_pair(Function, Loc));
}
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 7053bba8ede..769e0d222ae 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/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
}
OpenPOWER on IntegriCloud