Keep the parser's template depth up to date when parsing local templates and
late-parsed templates. Patch by Faisal Vali!


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@180708 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp
index 5d77f81..5fc4189 100644
--- a/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/lib/Parse/ParseCXXInlineMethods.cpp
@@ -278,8 +278,11 @@
 void Parser::ParseLexedMethodDeclarations(ParsingClass &Class) {
   bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
   ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, HasTemplateScope);
-  if (HasTemplateScope)
+  TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
+  if (HasTemplateScope) {
     Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate);
+    ++CurTemplateDepthTracker;
+  }
 
   // The current scope is still active if we're the top-level class.
   // Otherwise we'll need to push and enter a new scope.
@@ -300,9 +303,11 @@
 void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
   // If this is a member template, introduce the template parameter scope.
   ParseScope TemplateScope(this, Scope::TemplateParamScope, LM.TemplateScope);
-  if (LM.TemplateScope)
+  TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
+  if (LM.TemplateScope) {
     Actions.ActOnReenterTemplateScope(getCurScope(), LM.Method);
-
+    ++CurTemplateDepthTracker;
+  }
   // Start the delayed C++ method declaration
   Actions.ActOnStartDelayedCXXMethodDeclaration(getCurScope(), LM.Method);
 
@@ -378,9 +383,11 @@
 void Parser::ParseLexedMethodDefs(ParsingClass &Class) {
   bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
   ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, HasTemplateScope);
-  if (HasTemplateScope)
+  TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
+  if (HasTemplateScope) {
     Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate);
-
+    ++CurTemplateDepthTracker;
+  }
   bool HasClassScope = !Class.TopLevelClass;
   ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope,
                         HasClassScope);
@@ -393,9 +400,11 @@
 void Parser::ParseLexedMethodDef(LexedMethod &LM) {
   // If this is a member template, introduce the template parameter scope.
   ParseScope TemplateScope(this, Scope::TemplateParamScope, LM.TemplateScope);
-  if (LM.TemplateScope)
+  TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
+  if (LM.TemplateScope) {
     Actions.ActOnReenterTemplateScope(getCurScope(), LM.D);
-
+    ++CurTemplateDepthTracker;
+  }
   // Save the current token position.
   SourceLocation origLoc = Tok.getLocation();
 
@@ -440,6 +449,13 @@
   } else
     Actions.ActOnDefaultCtorInitializers(LM.D);
 
+  assert((Actions.getDiagnostics().hasErrorOccurred() ||
+          !isa<FunctionTemplateDecl>(LM.D) ||
+          cast<FunctionTemplateDecl>(LM.D)->getTemplateParameters()->getDepth()
+            < TemplateParameterDepth) &&
+         "TemplateParameterDepth should be greater than the depth of "
+         "current template being instantiated!");
+
   ParseFunctionStatementBody(LM.D, FnScope);
 
   // Clear the late-template-parsed bit if we set it before.
@@ -465,9 +481,11 @@
   bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
   ParseScope ClassTemplateScope(this, Scope::TemplateParamScope,
                                 HasTemplateScope);
-  if (HasTemplateScope)
+  TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
+  if (HasTemplateScope) {
     Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate);
-
+    ++CurTemplateDepthTracker;
+  }
   // Set or update the scope flags.
   bool AlreadyHasClassScope = Class.TopLevelClass;
   unsigned ScopeFlags = Scope::ClassScope|Scope::DeclScope;