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
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index e6be538..98619f3 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1653,8 +1653,14 @@
   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 @@
   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 @@
 
 /// \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)) {