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
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 42c4329..308a78c 100644
--- a/lib/Sema/Sema.h
+++ b/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 @@
   
   /// \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 @@
                                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/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 1c5b760..d66b002 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -5641,7 +5641,7 @@
       // 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/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 7053bba..769e0d2 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -663,10 +663,19 @@
 /// \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 @@
   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 @@
 
   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 @@
 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
   }