Reimplement much of the way that we track nested classes in the
parser. Rather than placing all of the delayed member function
declarations and inline definitions into a single bucket corresponding
to the top-level class, we instead mirror the nesting structure of the
nested classes and place the delayed member functions into their
appropriate place. Then, when we actually parse the delayed member
function declarations, set up the scope stack the same way as it was
when we originally saw the declaration, so that we can find, e.g.,
template parameters that are in scope.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72502 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 3825b7c..0a285bd 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -1731,6 +1731,7 @@
                                                  SourceLocation LBrac,
                                                  SourceLocation RBrac);
 
+  virtual void ActOnReenterTemplateScope(Scope *S, DeclPtrTy Template);
   virtual void ActOnStartDelayedCXXMethodDeclaration(Scope *S,
                                                      DeclPtrTy Method);
   virtual void ActOnDelayedCXXMethodParameter(Scope *S, DeclPtrTy Param);
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 6edb290..0bf97f5 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -1205,6 +1205,23 @@
   }
 }
 
+void Sema::ActOnReenterTemplateScope(Scope *S, DeclPtrTy TemplateD) {
+  TemplateDecl *Template = TemplateD.getAs<TemplateDecl>();
+  if (!Template)
+    return;
+
+  TemplateParameterList *Params = Template->getTemplateParameters();
+  for (TemplateParameterList::iterator Param = Params->begin(),
+                                    ParamEnd = Params->end();
+       Param != ParamEnd; ++Param) {
+    NamedDecl *Named = cast<NamedDecl>(*Param);
+    if (Named->getDeclName()) {
+      S->AddDecl(DeclPtrTy::make(Named));
+      IdResolver.AddDecl(Named);
+    }
+  }
+}
+
 /// ActOnStartDelayedCXXMethodDeclaration - We have completed
 /// parsing a top-level (non-nested) C++ class, and we are now
 /// parsing those parts of the given Method declaration that could
diff --git a/lib/Sema/SemaTemplateInstantiateStmt.cpp b/lib/Sema/SemaTemplateInstantiateStmt.cpp
index 6d2e28a..a62607d 100644
--- a/lib/Sema/SemaTemplateInstantiateStmt.cpp
+++ b/lib/Sema/SemaTemplateInstantiateStmt.cpp
@@ -69,8 +69,7 @@
       return SemaRef.StmtError();
 
     Decls.push_back(Instantiated);
-    SemaRef.CurrentInstantiationScope->InstantiatedLocal(cast<VarDecl>(*D),
-                                                  cast<VarDecl>(Instantiated));
+    SemaRef.CurrentInstantiationScope->InstantiatedLocal(*D, Instantiated);
   }
 
   return SemaRef.Owned(new (SemaRef.Context) DeclStmt(