Index: lib/Parse/ParseCXXInlineMethods.cpp
===================================================================
--- lib/Parse/ParseCXXInlineMethods.cpp	(revision 187122)
+++ lib/Parse/ParseCXXInlineMethods.cpp	(working copy)
@@ -120,18 +120,13 @@
         TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) && 
         !Actions.IsInsideALocalClassWithinATemplateFunction())) {
 
+    CachedTokens Toks;
+    LexTemplateFunctionForLateParsing(Toks);
+        
     if (FnD) {
-      LateParsedTemplatedFunction *LPT = new LateParsedTemplatedFunction(FnD);
-
       FunctionDecl *FD = getFunctionDecl(FnD);
       Actions.CheckForFunctionRedefinition(FD);
-
-      LateParsedTemplateMap[FD] = LPT;
-      Actions.MarkAsLateParsedTemplate(FD);
-      LexTemplateFunctionForLateParsing(LPT->Toks);
-    } else {
-      CachedTokens Toks;
-      LexTemplateFunctionForLateParsing(Toks);
+      Actions.MarkAsLateParsedTemplate(FD, FnD, Toks);
     }
 
     return FnD;
Index: lib/Parse/Parser.cpp
===================================================================
--- lib/Parse/Parser.cpp	(revision 187122)
+++ lib/Parse/Parser.cpp	(working copy)
@@ -422,11 +422,6 @@
   for (unsigned i = 0, e = NumCachedScopes; i != e; ++i)
     delete ScopeCache[i];
 
-  // Free LateParsedTemplatedFunction nodes.
-  for (LateParsedTemplateMapT::iterator it = LateParsedTemplateMap.begin();
-      it != LateParsedTemplateMap.end(); ++it)
-    delete it->second;
-
   // Remove the pragma handlers we installed.
   PP.RemovePragmaHandler(AlignHandler.get());
   AlignHandler.reset();
@@ -1008,22 +1003,18 @@
     D.complete(DP);
     D.getMutableDeclSpec().abort();
 
+    CachedTokens Toks;
+    LexTemplateFunctionForLateParsing(Toks);
+    
     if (DP) {
-      LateParsedTemplatedFunction *LPT = new LateParsedTemplatedFunction(DP);
-
       FunctionDecl *FnD = 0;
       if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(DP))
         FnD = FunTmpl->getTemplatedDecl();
       else
         FnD = cast<FunctionDecl>(DP);
+      
       Actions.CheckForFunctionRedefinition(FnD);
-
-      LateParsedTemplateMap[FnD] = LPT;
-      Actions.MarkAsLateParsedTemplate(FnD);
-      LexTemplateFunctionForLateParsing(LPT->Toks);
-    } else {
-      CachedTokens Toks;
-      LexTemplateFunctionForLateParsing(Toks);
+      Actions.MarkAsLateParsedTemplate(FnD, DP, Toks);
     }
     return DP;
   }
Index: lib/Parse/ParseTemplate.cpp
===================================================================
--- lib/Parse/ParseTemplate.cpp	(revision 187122)
+++ lib/Parse/ParseTemplate.cpp	(working copy)
@@ -1242,21 +1242,11 @@
   return R;
 }
 
-void Parser::LateTemplateParserCallback(void *P, const FunctionDecl *FD) {
-  ((Parser*)P)->LateTemplateParser(FD);
+void Parser::LateTemplateParserCallback(void *P,
+                                        LateParsedTemplatedFunction &LT) {
+  ((Parser*)P)->ParseLateTemplatedFuncDef(LT);
 }
 
-
-void Parser::LateTemplateParser(const FunctionDecl *FD) {
-  LateParsedTemplatedFunction *LPT = LateParsedTemplateMap[FD];
-  if (LPT) {
-    ParseLateTemplatedFuncDef(*LPT);
-    return;
-  }
-
-  llvm_unreachable("Late templated function without associated lexed tokens");
-}
-
 /// \brief Late parse a C++ function template in Microsoft mode.
 void Parser::ParseLateTemplatedFuncDef(LateParsedTemplatedFunction &LMT) {
   if(!LMT.D)
@@ -1351,7 +1341,7 @@
              "TemplateParameterDepth should be greater than the depth of "
              "current template being instantiated!");
       ParseFunctionStatementBody(LMT.D, FnScope);
-      Actions.MarkAsLateParsedTemplate(FunD, false);
+      Actions.UnmarkAsLateParsedTemplate(FunD);
     } else
       Actions.ActOnFinishFunctionBody(LMT.D, 0);
   }
Index: lib/Serialization/ASTWriter.cpp
===================================================================
--- lib/Serialization/ASTWriter.cpp	(revision 187122)
+++ lib/Serialization/ASTWriter.cpp	(working copy)
@@ -848,6 +848,7 @@
   RECORD(OBJC_CATEGORIES);
   RECORD(MACRO_OFFSET);
   RECORD(MACRO_TABLE);
+  RECORD(LATE_PARSED_TEMPLATE);
 
   // SourceManager Block.
   BLOCK(SOURCE_MANAGER_BLOCK);
@@ -3670,6 +3671,33 @@
   Stream.EmitRecord(MERGED_DECLARATIONS, Record);
 }
 
+void ASTWriter::WriteLateParsedTemplates(Sema &SemaRef) {
+  Sema::LateParsedTemplateMapT& LTMap = SemaRef.LateParsedTemplateMap;
+  
+  if (LTMap.empty())
+    return;
+  
+  RecordData Record;
+  for (Sema::LateParsedTemplateMapT::iterator It = LTMap.begin(),
+       ItEnd = LTMap.end();
+       It != ItEnd; ++It)
+  {
+    LateParsedTemplatedFunction* LPT = It->second;
+    AddDeclRef(It->first, Record);
+    AddDeclRef(LPT->D, Record);
+    Record.push_back(LPT->Toks.size());
+    
+    for (CachedTokens::iterator TokIt = LPT->Toks.begin(),
+         TokEnd = LPT->Toks.end();
+         TokIt != TokEnd;
+         ++TokIt)
+    {
+      AddToken(*TokIt, Record);
+    }
+  }
+  Stream.EmitRecord(LATE_PARSED_TEMPLATE, Record);
+}
+
 //===----------------------------------------------------------------------===//
 // General Serialization Routines
 //===----------------------------------------------------------------------===//
@@ -4237,6 +4265,7 @@
   WriteRedeclarations();
   WriteMergedDecls();
   WriteObjCCategories();
+  WriteLateParsedTemplates(SemaRef);
   
   // Some simple statistics
   Record.clear();
Index: lib/Serialization/ASTReaderDecl.cpp
===================================================================
--- lib/Serialization/ASTReaderDecl.cpp	(revision 187122)
+++ lib/Serialization/ASTReaderDecl.cpp	(working copy)
@@ -535,6 +535,7 @@
   FD->HasImplicitReturnZero = Record[Idx++];
   FD->IsConstexpr = Record[Idx++];
   FD->HasSkippedBody = Record[Idx++];
+  FD->IsLateTemplateParsed = Record[Idx++];
   FD->setCachedLinkage(Linkage(Record[Idx++]));
   FD->EndRangeLoc = ReadSourceLocation(Record, Idx);
 
Index: lib/Serialization/ASTReader.cpp
===================================================================
--- lib/Serialization/ASTReader.cpp	(revision 187122)
+++ lib/Serialization/ASTReader.cpp	(working copy)
@@ -1103,7 +1103,7 @@
   }
 }
 
-Token ASTReader::ReadToken(ModuleFile &F, const RecordData &Record,
+Token ASTReader::ReadToken(ModuleFile &F, const RecordDataImpl &Record,
                            unsigned &Idx) {
   Token Tok;
   Tok.startToken();
@@ -2751,7 +2751,12 @@
       // FIXME: Not used yet.
       break;
     }
+      
+    case LATE_PARSED_TEMPLATE: {
+      LateParsedTemplates.append(Record.begin(), Record.end());
+      break;
     }
+    }
   }
 }
 
@@ -6475,6 +6480,30 @@
   PendingInstantiations.clear();
 }
 
+void ASTReader::ReadLateParsedTemplateFunctions(
+                                          llvm::DenseMap<const FunctionDecl*,
+                                           LateParsedTemplatedFunction*> &LPT) {
+  for (unsigned Idx = 0, N = LateParsedTemplates.size(); Idx < N;
+                                                                /* In loop */) {
+    FunctionDecl *FD = cast<FunctionDecl>(GetDecl(LateParsedTemplates[Idx++]));
+    
+    LateParsedTemplatedFunction *LT = new LateParsedTemplatedFunction;
+    LT->D = GetDecl(LateParsedTemplates[Idx++]);
+    
+    ModuleFile *F = getOwningModuleFile(LT->D);
+    assert(F && "No module");
+    
+    unsigned TokN = LateParsedTemplates[Idx++];
+    LT->Toks.reserve(TokN);
+    for (unsigned T = 0; T < TokN; ++T)
+      LT->Toks.push_back(ReadToken(*F, LateParsedTemplates, Idx));
+    
+    LPT[FD] = LT;
+  }
+  
+  LateParsedTemplates.clear();
+}
+
 void ASTReader::LoadSelector(Selector Sel) {
   // It would be complicated to avoid reading the methods anyway. So don't.
   ReadMethodPool(Sel);
Index: lib/Serialization/ASTWriterDecl.cpp
===================================================================
--- lib/Serialization/ASTWriterDecl.cpp	(revision 187122)
+++ lib/Serialization/ASTWriterDecl.cpp	(working copy)
@@ -338,6 +338,7 @@
   Record.push_back(D->hasImplicitReturnZero());
   Record.push_back(D->isConstexpr());
   Record.push_back(D->HasSkippedBody);
+  Record.push_back(D->isLateTemplateParsed());
   Record.push_back(D->getLinkageInternal());
   Writer.AddSourceLocation(D->getLocEnd(), Record);
 
Index: lib/Sema/SemaTemplate.cpp
===================================================================
--- lib/Sema/SemaTemplate.cpp	(revision 187122)
+++ lib/Sema/SemaTemplate.cpp	(working copy)
@@ -7379,12 +7379,27 @@
   return Out.str();
 }
 
-void Sema::MarkAsLateParsedTemplate(FunctionDecl *FD, bool Flag) {
+void Sema::MarkAsLateParsedTemplate(FunctionDecl *FD, Decl *FnD,
+                                    CachedTokens& Toks) {
   if (!FD)
     return;
-  FD->setLateTemplateParsed(Flag);
-} 
+  
+  LateParsedTemplatedFunction *LPT = new LateParsedTemplatedFunction;
+  
+  // Take tokens to avoid allocations
+  LPT->Toks.swap(Toks);
+  LPT->D = FnD;
+  LateParsedTemplateMap[FD] = LPT;
+  
+  FD->setLateTemplateParsed(true);
+}
 
+void Sema::UnmarkAsLateParsedTemplate(FunctionDecl *FD) {
+  if (!FD)
+    return;
+  FD->setLateTemplateParsed(false);
+}
+
 bool Sema::IsInsideALocalClassWithinATemplateFunction() {
   DeclContext *DC = CurContext;
 
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiateDecl.cpp	(revision 187122)
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp	(working copy)
@@ -2898,7 +2898,12 @@
   // a templated function definition.
   if (!Pattern && PatternDecl->isLateTemplateParsed() &&
       LateTemplateParser) {
-    LateTemplateParser(OpaqueParser, PatternDecl);
+    if (PatternDecl->isFromASTFile())
+      ExternalSource->ReadLateParsedTemplateFunctions(LateParsedTemplateMap);
+    
+    LateParsedTemplatedFunction *LT = LateParsedTemplateMap.lookup(PatternDecl);
+    assert(LT && "missing LateParsedTemplatedFunction");
+    LateTemplateParser(OpaqueParser, *LT);
     Pattern = PatternDecl->getBody(PatternDecl);
   }
 
Index: lib/Sema/MultiplexExternalSemaSource.cpp
===================================================================
--- lib/Sema/MultiplexExternalSemaSource.cpp	(revision 187122)
+++ lib/Sema/MultiplexExternalSemaSource.cpp	(working copy)
@@ -267,3 +267,10 @@
   for(size_t i = 0; i < Sources.size(); ++i)
     Sources[i]->ReadPendingInstantiations(Pending);
 }
+
+void MultiplexExternalSemaSource::ReadLateParsedTemplateFunctions(
+                                        llvm::DenseMap<const FunctionDecl*,
+                                           LateParsedTemplatedFunction*> &LPT) {
+  for(size_t i = 0; i < Sources.size(); ++i)
+    Sources[i]->ReadLateParsedTemplateFunctions(LPT);
+}
\ No newline at end of file
Index: lib/Sema/Sema.cpp
===================================================================
--- lib/Sema/Sema.cpp	(revision 187122)
+++ lib/Sema/Sema.cpp	(working copy)
@@ -173,6 +173,10 @@
 }
 
 Sema::~Sema() {
+  for (LateParsedTemplateMapT::iterator I = LateParsedTemplateMap.begin(),
+       E = LateParsedTemplateMap.end();
+       I != E; ++I)
+    delete I->second;
   if (PackContext) FreePackedContext();
   if (VisContext) FreeVisContext();
   delete TheTargetAttributesSema;
Index: test/PCH/cxx-templates.cpp
===================================================================
--- test/PCH/cxx-templates.cpp	(revision 187122)
+++ test/PCH/cxx-templates.cpp	(working copy)
@@ -12,6 +12,11 @@
 // RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -fmodules -include-pch %t -verify %s -ast-dump  -o -
 // RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -fmodules -include-pch %t %s -emit-llvm -o - -error-on-deserialized-decl doNotDeserialize | FileCheck %s
 
+// Test with pch and delayed template parsing.
+// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fdelayed-template-parsing -fexceptions -x c++-header -emit-pch -o %t %S/cxx-templates.h
+// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fdelayed-template-parsing -fexceptions -include-pch %t -verify %s -ast-dump  -o -
+// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fdelayed-template-parsing -fexceptions -include-pch %t %s -emit-llvm -o - | FileCheck %s
+
 // expected-no-diagnostics
 
 // CHECK: define weak_odr void @_ZN2S4IiE1mEv
Index: include/clang/Sema/ExternalSemaSource.h
===================================================================
--- include/clang/Sema/ExternalSemaSource.h	(revision 187122)
+++ include/clang/Sema/ExternalSemaSource.h	(working copy)
@@ -30,6 +30,7 @@
 class TypedefNameDecl;
 class ValueDecl;
 class VarDecl;
+struct LateParsedTemplatedFunction;
   
 /// \brief A simple structure that captures a vtable use for the purposes of
 /// the \c ExternalSemaSource.
@@ -177,6 +178,16 @@
                  SmallVectorImpl<std::pair<ValueDecl *, 
                                            SourceLocation> > &Pending) {}
 
+  /// \brief Read the set of late parsed template functions for this source.
+  ///
+  /// The external source should insert its own late parsed template functions
+  /// into the map. Note that this routine may be invoked multiple times; the
+  /// external source should take care not to introduce the same map entries
+  /// repeatedly.
+  virtual void ReadLateParsedTemplateFunctions(
+                 llvm::DenseMap<const FunctionDecl*,
+                                          LateParsedTemplatedFunction*> &LPT) {}
+  
   // isa/cast/dyn_cast support
   static bool classof(const ExternalASTSource *Source) {
     return Source->SemaSource;
Index: include/clang/Sema/MultiplexExternalSemaSource.h
===================================================================
--- include/clang/Sema/MultiplexExternalSemaSource.h	(revision 187122)
+++ include/clang/Sema/MultiplexExternalSemaSource.h	(working copy)
@@ -321,6 +321,16 @@
   /// repeatedly.
   virtual void ReadPendingInstantiations(
               SmallVectorImpl<std::pair<ValueDecl*, SourceLocation> >& Pending);
+  
+  /// \brief Read the set of late parsed template functions for this source.
+  ///
+  /// The external source should insert its own late parsed template functions
+  /// into the map. Note that this routine may be invoked multiple times; the
+  /// external source should take care not to introduce the same map entries
+  /// repeatedly.
+  virtual void ReadLateParsedTemplateFunctions(
+                                          llvm::DenseMap<const FunctionDecl*,
+                                            LateParsedTemplatedFunction*> &LPT);
 
   // isa/cast/dyn_cast support
   static bool classof(const MultiplexExternalSemaSource*) { return true; }
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h	(revision 187122)
+++ include/clang/Sema/Sema.h	(working copy)
@@ -391,9 +391,13 @@
   /// we can't do that until the nesting set of class definitions is complete.
   SmallVector<std::pair<CXXMethodDecl*, const FunctionProtoType*>, 2>
     DelayedDefaultedMemberExceptionSpecs;
-
+  
+  typedef llvm::DenseMap<const FunctionDecl*, LateParsedTemplatedFunction*>
+  LateParsedTemplateMapT;
+  LateParsedTemplateMapT LateParsedTemplateMap;
+  
   /// \brief Callback to the parser to parse templated functions when needed.
-  typedef void LateTemplateParserCB(void *P, const FunctionDecl *FD);
+  typedef void LateTemplateParserCB(void *P, LateParsedTemplatedFunction &LT);
   LateTemplateParserCB *LateTemplateParser;
   void *OpaqueParser;
 
@@ -4667,7 +4671,9 @@
   void ActOnFinishDelayedMemberDeclarations(Scope *S, Decl *Record);
   void ActOnFinishDelayedCXXMethodDeclaration(Scope *S, Decl *Method);
   void ActOnFinishDelayedMemberInitializers(Decl *Record);
-  void MarkAsLateParsedTemplate(FunctionDecl *FD, bool Flag = true);
+  void MarkAsLateParsedTemplate(FunctionDecl *FD, Decl *FnD,
+                                CachedTokens &Toks);
+  void UnmarkAsLateParsedTemplate(FunctionDecl *FD);
   bool IsInsideALocalClassWithinATemplateFunction();
 
   Decl *ActOnStaticAssertDeclaration(SourceLocation StaticAssertLoc,
@@ -7745,6 +7751,14 @@
 MakeDeductionFailureInfo(ASTContext &Context, Sema::TemplateDeductionResult TDK,
                          sema::TemplateDeductionInfo &Info);
 
+/// \brief Contains a late templated function.
+/// Will be parsed at the end of the translation unit, used by Sema & Parser.
+struct LateParsedTemplatedFunction {
+  CachedTokens Toks;
+  /// \brief The template function declaration to be late parsed.
+  Decl *D;
+};
+
 }  // end namespace clang
 
 #endif
Index: include/clang/Parse/Parser.h
===================================================================
--- include/clang/Parse/Parser.h	(revision 187122)
+++ include/clang/Parse/Parser.h	(working copy)
@@ -1051,26 +1051,11 @@
     SourceRange getSourceRange() const LLVM_READONLY;
   };
 
-  /// \brief Contains a late templated function.
-  /// Will be parsed at the end of the translation unit.
-  struct LateParsedTemplatedFunction {
-    explicit LateParsedTemplatedFunction(Decl *MD)
-      : D(MD) {}
-
-    CachedTokens Toks;
-
-    /// \brief The template function declaration to be late parsed.
-    Decl *D;
-  };
-
   void LexTemplateFunctionForLateParsing(CachedTokens &Toks);
-  void ParseLateTemplatedFuncDef(LateParsedTemplatedFunction &LMT);
-  typedef llvm::DenseMap<const FunctionDecl*, LateParsedTemplatedFunction*>
-    LateParsedTemplateMapT;
-  LateParsedTemplateMapT LateParsedTemplateMap;
+  void ParseLateTemplatedFuncDef(LateParsedTemplatedFunction &LT);
 
-  static void LateTemplateParserCallback(void *P, const FunctionDecl *FD);
-  void LateTemplateParser(const FunctionDecl *FD);
+  static void LateTemplateParserCallback(void *P,
+                                         LateParsedTemplatedFunction &LT);
 
   Sema::ParsingClassState
   PushParsingClass(Decl *TagOrTemplate, bool TopLevelClass, bool IsInterface);
Index: include/clang/Serialization/ASTBitCodes.h
===================================================================
--- include/clang/Serialization/ASTBitCodes.h	(revision 187122)
+++ include/clang/Serialization/ASTBitCodes.h	(working copy)
@@ -535,7 +535,10 @@
 
       /// \brief Record code for undefined but used functions and variables that
       /// need a definition in this TU.
-      UNDEFINED_BUT_USED = 49
+      UNDEFINED_BUT_USED = 49,
+      
+      /// \brief Record code for late parsed template functions.
+      LATE_PARSED_TEMPLATE = 50
     };
 
     /// \brief Record types used within a source manager block.
Index: include/clang/Serialization/ASTWriter.h
===================================================================
--- include/clang/Serialization/ASTWriter.h	(revision 187122)
+++ include/clang/Serialization/ASTWriter.h	(working copy)
@@ -457,6 +457,7 @@
   void WriteObjCCategories();
   void WriteRedeclarations();
   void WriteMergedDecls();
+  void WriteLateParsedTemplates(Sema &SemaRef);
                         
   unsigned DeclParmVarAbbrev;
   unsigned DeclContextLexicalAbbrev;
Index: include/clang/Serialization/ASTReader.h
===================================================================
--- include/clang/Serialization/ASTReader.h	(revision 187122)
+++ include/clang/Serialization/ASTReader.h	(working copy)
@@ -240,6 +240,7 @@
 {
 public:
   typedef SmallVector<uint64_t, 64> RecordData;
+  typedef SmallVectorImpl<uint64_t> RecordDataImpl;
 
   /// \brief The result of reading the control block of an AST file, which
   /// can fail for various reasons.
@@ -709,6 +710,9 @@
   /// \brief A list of undefined decls with internal linkage followed by the
   /// SourceLocation of a matching ODR-use.
   SmallVector<uint64_t, 8> UndefinedButUsed;
+  
+  // \brief A list of late parsed template function data.
+  SmallVector<uint64_t, 1> LateParsedTemplates;
 
   /// \brief A list of modules that were imported by precompiled headers or
   /// any other non-module AST file.
@@ -1609,6 +1613,10 @@
   virtual void ReadPendingInstantiations(
                  SmallVectorImpl<std::pair<ValueDecl *,
                                            SourceLocation> > &Pending);
+  
+  virtual void ReadLateParsedTemplateFunctions(
+                 llvm::DenseMap<const FunctionDecl*,
+                                            LateParsedTemplatedFunction*> &LPT);
 
   /// \brief Load a selector from disk, registering its ID if it exists.
   void LoadSelector(Selector Sel);
@@ -1760,7 +1768,7 @@
 
   /// \brief Read a source location.
   SourceLocation ReadSourceLocation(ModuleFile &ModuleFile,
-                                    const RecordData &Record, unsigned &Idx) {
+                                    const RecordDataImpl &Record, unsigned &Idx) {
     return ReadSourceLocation(ModuleFile, Record[Idx++]);
   }
 
@@ -1811,7 +1819,7 @@
   Expr *ReadSubExpr();
 
   /// \brief Reads a token out of a record.
-  Token ReadToken(ModuleFile &M, const RecordData &Record, unsigned &Idx);
+  Token ReadToken(ModuleFile &M, const RecordDataImpl &Record, unsigned &Idx);
 
   /// \brief Reads the macro record located at the given offset.
   MacroInfo *ReadMacroRecord(ModuleFile &F, uint64_t Offset);
