Emit an update record if we instantiate the definition of a function template
specialization from a module. (This can also happen for function template
specializations in PCHs if they're instantiated eagerly, because they're
constexpr or have a deduced return type.)

llvm-svn: 204547
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 0aa539e..ed69521 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -4358,6 +4358,7 @@
     OffsetsRecord.push_back(GetDeclRef(D));
     OffsetsRecord.push_back(Stream.GetCurrentBitNo());
 
+    bool HasUpdatedBody = false;
     RecordData Record;
     for (auto &Update : DeclUpdate.second) {
       DeclUpdateKind Kind = (DeclUpdateKind)Update.getKind();
@@ -4374,6 +4375,13 @@
         AddSourceLocation(Update.getLoc(), Record);
         break;
 
+      case UPD_CXX_INSTANTIATED_FUNCTION_DEFINITION:
+        // An updated body is emitted last, so that the reader doesn't need
+        // to skip over the lazy body to reach statements for other records.
+        Record.pop_back();
+        HasUpdatedBody = true;
+        break;
+
       case UPD_CXX_RESOLVED_EXCEPTION_SPEC:
         addExceptionSpec(
             *this,
@@ -4395,6 +4403,14 @@
       }
     }
 
+    if (HasUpdatedBody) {
+      const FunctionDecl *Def = cast<FunctionDecl>(D);
+      Record.push_back(UPD_CXX_INSTANTIATED_FUNCTION_DEFINITION);
+      Record.push_back(Def->isInlined());
+      AddSourceLocation(Def->getInnerLocStart(), Record);
+      AddFunctionDefinition(Def, Record);
+    }
+
     Stream.EmitRecord(DECL_UPDATES, Record);
 
     // Flush any statements that were written as part of this update record.
@@ -5381,6 +5397,17 @@
   RewriteDecl(D);
 }
 
+void ASTWriter::FunctionDefinitionInstantiated(const FunctionDecl *D) {
+  assert(!WritingAST && "Already writing the AST!");
+  if (!D->isFromASTFile())
+    return;
+
+  // Since the actual instantiation is delayed, this really means that we need
+  // to update the instantiation location.
+  DeclUpdates[D].push_back(
+      DeclUpdate(UPD_CXX_INSTANTIATED_FUNCTION_DEFINITION));
+}
+
 void ASTWriter::StaticDataMemberInstantiated(const VarDecl *D) {
   assert(!WritingAST && "Already writing the AST!");
   if (!D->isFromASTFile())