Index: include/clang/Parse/Parser.h
===================================================================
--- include/clang/Parse/Parser.h	(revision 180140)
+++ include/clang/Parse/Parser.h	(working copy)
@@ -172,6 +172,30 @@
   /// The "depth" of the template parameters currently being parsed.
   unsigned TemplateParameterDepth;
 
+
+  /// \brief RAII class that manages the template parameter depth.
+  class TemplateParameterDepthRAII {
+    unsigned &Depth;
+    unsigned AddedLevels;
+  public:
+    explicit TemplateParameterDepthRAII(unsigned &Depth)
+      : Depth(Depth), AddedLevels(0) {  }
+
+    ~TemplateParameterDepthRAII() {
+      Depth -= AddedLevels;
+    }
+
+    void operator++() {
+        ++Depth;
+        ++AddedLevels;
+    }
+    void addDepth(unsigned D) { 
+      Depth += D;
+      AddedLevels += D;
+    }
+    unsigned getDepth() const { return Depth; }
+  };
+
   /// Factory object for creating AttributeList objects.
   AttributeFactory AttrFactory;
 
Index: lib/Parse/ParseCXXInlineMethods.cpp
===================================================================
--- lib/Parse/ParseCXXInlineMethods.cpp	(revision 180140)
+++ lib/Parse/ParseCXXInlineMethods.cpp	(working copy)
@@ -279,8 +279,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.
@@ -301,9 +304,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);
 
@@ -379,9 +384,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);
@@ -394,9 +401,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,7 +449,14 @@
     }
   } else
     Actions.ActOnDefaultCtorInitializers(LM.D);
-
+ 
+  assert( Actions.getDiagnostics().hasErrorOccurred() || 
+        (!dyn_cast<FunctionTemplateDecl>(LM.D) || 
+          (dyn_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.
@@ -466,9 +482,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;
Index: lib/Parse/ParseTemplate.cpp
===================================================================
--- lib/Parse/ParseTemplate.cpp	(revision 180140)
+++ lib/Parse/ParseTemplate.cpp	(working copy)
@@ -28,6 +28,7 @@
                                              SourceLocation &DeclEnd,
                                              AccessSpecifier AS,
                                              AttributeList *AccessAttrs) {
+
   ObjCDeclContextSwitch ObjCDC(*this);
   
   if (Tok.is(tok::kw_template) && NextToken().isNot(tok::less)) {
@@ -39,29 +40,8 @@
                                                   AccessAttrs);
 }
 
-/// \brief RAII class that manages the template parameter depth.
-namespace {
-  class TemplateParameterDepthCounter {
-    unsigned &Depth;
-    unsigned AddedLevels;
 
-  public:
-    explicit TemplateParameterDepthCounter(unsigned &Depth)
-      : Depth(Depth), AddedLevels(0) { }
 
-    ~TemplateParameterDepthCounter() {
-      Depth -= AddedLevels;
-    }
-
-    void operator++() {
-      ++Depth;
-      ++AddedLevels;
-    }
-
-    operator unsigned() const { return Depth; }
-  };
-}
-
 /// \brief Parse a template declaration or an explicit specialization.
 ///
 /// Template declarations include one or more template parameter lists
@@ -82,6 +62,7 @@
                                                  SourceLocation &DeclEnd,
                                                  AccessSpecifier AS,
                                                  AttributeList *AccessAttrs) {
+                                                 
   assert((Tok.is(tok::kw_export) || Tok.is(tok::kw_template)) &&
          "Token does not start a template declaration.");
 
@@ -117,7 +98,8 @@
   bool isSpecialization = true;
   bool LastParamListWasEmpty = false;
   TemplateParameterLists ParamLists;
-  TemplateParameterDepthCounter Depth(TemplateParameterDepth);
+  TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
+
   do {
     // Consume the 'export', if any.
     SourceLocation ExportLoc;
@@ -137,8 +119,8 @@
     // Parse the '<' template-parameter-list '>'
     SourceLocation LAngleLoc, RAngleLoc;
     SmallVector<Decl*, 4> TemplateParams;
-    if (ParseTemplateParameters(Depth, TemplateParams, LAngleLoc,
-                                RAngleLoc)) {
+    if (ParseTemplateParameters(CurTemplateDepthTracker.getDepth(), 
+            TemplateParams, LAngleLoc, RAngleLoc)) {
       // Skip until the semi-colon or a }.
       SkipUntil(tok::r_brace, true, true);
       if (Tok.is(tok::semi))
@@ -147,14 +129,15 @@
     }
 
     ParamLists.push_back(
-      Actions.ActOnTemplateParameterList(Depth, ExportLoc,
+      Actions.ActOnTemplateParameterList(CurTemplateDepthTracker.getDepth(), 
+                                         ExportLoc,
                                          TemplateLoc, LAngleLoc,
                                          TemplateParams.data(),
                                          TemplateParams.size(), RAngleLoc));
 
     if (!TemplateParams.empty()) {
       isSpecialization = false;
-      ++Depth;
+      ++CurTemplateDepthTracker;
     } else {
       LastParamListWasEmpty = true;
     }
@@ -1249,25 +1232,38 @@
      return;
 
   // Get the FunctionDecl.
-  FunctionDecl *FD = 0;
-  if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(LMT.D))
-    FD = FunTmpl->getTemplatedDecl();
-  else
-    FD = cast<FunctionDecl>(LMT.D);
-
+  FunctionTemplateDecl *const FunTmplD = 
+                        dyn_cast<FunctionTemplateDecl>(LMT.D);
+  FunctionDecl *const FunD = FunTmplD ? FunTmplD->getTemplatedDecl() :
+                                  cast<FunctionDecl>(LMT.D);
+  // Track template parameter depth.
+  TemplateParameterDepthRAII CurTemplateDepthTracker(
+                                                  TemplateParameterDepth);
   // To restore the context after late parsing.
   Sema::ContextRAII GlobalSavedContext(Actions, Actions.CurContext);
 
   SmallVector<ParseScope*, 4> TemplateParamScopeStack;
-  DeclaratorDecl* Declarator = dyn_cast<DeclaratorDecl>(FD);
+  DeclaratorDecl* Declarator = dyn_cast<DeclaratorDecl>(FunD);
   if (Declarator && Declarator->getNumTemplateParameterLists() != 0) {
+    
+    // getNumTemplateParameterLists returns the number of TPLs 
+    // minus the TPL of the actual function being instantiated
+    // i.e. consider a nested member class template with
+    // a template member of a function defined out of class ... its
+    // associated TPLs
+    // Therefore we add 1 to the depth for the Declarator itself
+    // and the rest for the outer TPLs returned by getNumTPLs
+    const unsigned NumTPLs = Declarator->getNumTemplateParameterLists();
+    CurTemplateDepthTracker.addDepth( 1 + NumTPLs );
+
     TemplateParamScopeStack.push_back(new ParseScope(this, Scope::TemplateParamScope));
     Actions.ActOnReenterDeclaratorTemplateScope(getCurScope(), Declarator);
-    Actions.ActOnReenterTemplateScope(getCurScope(), LMT.D);
+    Actions.ActOnReenterTemplateScope(getCurScope(), LMT.D);
+    
   } else {
     // Get the list of DeclContext to reenter.
     SmallVector<DeclContext*, 4> DeclContextToReenter;
-    DeclContext *DD = FD->getLexicalParent();
+    DeclContext *DD = FunD->getLexicalParent();
     while (DD && !DD->isTranslationUnit()) {
       DeclContextToReenter.push_back(DD);
       DD = DD->getLexicalParent();
@@ -1282,12 +1278,14 @@
         TemplateParamScopeStack.push_back(new ParseScope(this,
                                                    Scope::TemplateParamScope));
         Actions.ActOnReenterTemplateScope(getCurScope(), MD);
+        ++CurTemplateDepthTracker;
       } else if (CXXRecordDecl* MD = dyn_cast_or_null<CXXRecordDecl>(*II)) {
         TemplateParamScopeStack.push_back(new ParseScope(this,
                                                     Scope::TemplateParamScope,
                                        MD->getDescribedClassTemplate() != 0 ));
         Actions.ActOnReenterTemplateScope(getCurScope(),
                                           MD->getDescribedClassTemplate());
+        ++CurTemplateDepthTracker;
       }
       TemplateParamScopeStack.push_back(new ParseScope(this, Scope::DeclScope));
       Actions.PushDeclContext(Actions.getCurScope(), *II);
@@ -1295,6 +1293,7 @@
     TemplateParamScopeStack.push_back(new ParseScope(this,
                                       Scope::TemplateParamScope));
     Actions.ActOnReenterTemplateScope(getCurScope(), LMT.D);
+    ++CurTemplateDepthTracker;
   }
 
   assert(!LMT.Toks.empty() && "Empty body!");
@@ -1314,16 +1313,10 @@
   ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope);
 
   // Recreate the containing function DeclContext.
-  Sema::ContextRAII FunctionSavedContext(Actions, Actions.getContainingDC(FD));
+  Sema::ContextRAII FunctionSavedContext(Actions, Actions.getContainingDC(FunD));
 
-  if (FunctionTemplateDecl *FunctionTemplate
-        = dyn_cast_or_null<FunctionTemplateDecl>(LMT.D))
-    Actions.ActOnStartOfFunctionDef(getCurScope(),
-                                   FunctionTemplate->getTemplatedDecl());
-  if (FunctionDecl *Function = dyn_cast_or_null<FunctionDecl>(LMT.D))
-    Actions.ActOnStartOfFunctionDef(getCurScope(), Function);
+  Actions.ActOnStartOfFunctionDef(getCurScope(), FunD);
 
-
   if (Tok.is(tok::kw_try)) {
     ParseFunctionTryBlock(LMT.D, FnScope);
   } else {
@@ -1333,8 +1326,13 @@
       Actions.ActOnDefaultCtorInitializers(LMT.D);
 
     if (Tok.is(tok::l_brace)) {
+      assert( (!FunTmplD || 
+          (FunTmplD->getTemplateParameters()->getDepth() 
+              < TemplateParameterDepth)) && "TemplateParameterDepth should "
+              " be greater than the depth of current template being "
+              "instantiated!");
       ParseFunctionStatementBody(LMT.D, FnScope);
-      Actions.MarkAsLateParsedTemplate(FD, false);
+      Actions.MarkAsLateParsedTemplate(FunD, false);
     } else
       Actions.ActOnFinishFunctionBody(LMT.D, 0);
   }
Index: test/SemaTemplate/local-member-templates.cpp
===================================================================
--- test/SemaTemplate/local-member-templates.cpp	(revision 0)
+++ test/SemaTemplate/local-member-templates.cpp	(working copy)
@@ -0,0 +1,92 @@
+// RUN: %clang_cc1 -std=c++1y -verify %s
+// RUN: %clang_cc1 -std=c++1y -verify %s -fdelayed-template-parsing
+
+namespace nested_local_templates_1 {
+
+template<class T> 
+struct Outer {
+  template<class U> 
+  int outer_mem(T t, U u) {
+    struct Inner {
+      template<class V> 
+      int inner_mem(T t,U u, V v) {
+	      struct InnerInner {
+          template<class W> 
+          int inner_inner_mem(W w, T t, U u, V v) {
+            return 0;
+          }
+        };
+        InnerInner().inner_inner_mem("abc", t, u, v);
+        return 0;
+	    }
+    };
+    Inner i;
+    i.inner_mem(t, u, 3.14);    
+    return 0;
+  }
+  
+  template<class U> 
+  int outer_mem(T t, U* u);
+  
+};
+
+template int Outer<int>::outer_mem(int, char);
+
+template<class T> template<class U> 
+int Outer<T>::outer_mem(T t, U* u) {
+  struct Inner {
+    template<class V> 
+    int inner_mem(T t,U u, V v) { //expected-note{{candidate function}}
+      struct InnerInner {
+        template<class W> 
+        int inner_inner_mem(W w, T t, U u, V v) { 
+          return 0;
+        }
+      };
+      InnerInner().inner_inner_mem("abc", t, u, v);
+      return 0;
+    }
+  };
+  Inner i;
+  i.inner_mem(t, U{}, i);
+  i.inner_mem(t, u, 3.14);  //expected-error{{no matching member function for call to 'inner}}  
+  return 0;
+}
+
+template int Outer<int>::outer_mem(int, char*);   //expected-note{{in instantiation of function}}
+
+
+} // end ns
+
+
+
+namespace nested_local_templates_2 {
+
+template<class T> 
+struct Outer {
+  template<class U> 
+  void outer_mem(T t, U u) {
+    struct Inner {
+      template<class V> 
+      struct InnerTemplateClass {
+        template<class W> 
+        void itc_mem(T t, U u, V v, W w) { //expected-note{{candidate function}}
+          struct InnerInnerInner {
+            template<class X>
+            void iii_mem(X x) { }
+          };
+          InnerInnerInner i;
+          i.iii_mem("abc");
+        }
+      };
+    };  
+    Inner i;
+    typename Inner::template InnerTemplateClass<Inner> ii;
+    ii.itc_mem(t, u, i, "jim");
+    ii.itc_mem(t, u, 0, "abd");//expected-error{{no matching member function}}
+  }
+
+};
+
+template void Outer<int>::outer_mem(int, char);//expected-note{{in instantiation of}}
+}
\ No newline at end of file
