[PCH] Avoid using Decl::setAttrs() and Decl::setLexicalDeclContext() from the ASTReaderDecl
directly; they internally call Decl::getASTContext() which may crash if a declaration context
parent is still deserializing.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150137 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index c92e6dd..961f49b 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -389,7 +389,9 @@
   }
 
   bool hasAttrs() const { return HasAttrs; }
-  void setAttrs(const AttrVec& Attrs);
+  void setAttrs(const AttrVec& Attrs) {
+    return setAttrsImpl(Attrs, getASTContext());
+  }
   AttrVec &getAttrs() {
     return const_cast<AttrVec&>(const_cast<const Decl*>(this)->getAttrs());
   }
@@ -852,6 +854,9 @@
 
 private:
   const Attr *getAttrsImpl() const;
+  void setAttrsImpl(const AttrVec& Attrs, ASTContext &Ctx);
+  void setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC,
+                           ASTContext &Ctx);
 
 protected:
   ASTMutationListener *getASTMutationListener() const;
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index da54a44..a507215 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -203,15 +203,24 @@
     return;
 
   if (isInSemaDC()) {
-    MultipleDC *MDC = new (getASTContext()) MultipleDC();
-    MDC->SemanticDC = getDeclContext();
-    MDC->LexicalDC = DC;
-    DeclCtx = MDC;
+    setDeclContextsImpl(getDeclContext(), DC, getASTContext());
   } else {
     getMultipleDC()->LexicalDC = DC;
   }
 }
 
+void Decl::setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC,
+                               ASTContext &Ctx) {
+  if (SemaDC == LexicalDC) {
+    DeclCtx = SemaDC;
+  } else {
+    Decl::MultipleDC *MDC = new (Ctx) Decl::MultipleDC();
+    MDC->SemanticDC = SemaDC;
+    MDC->LexicalDC = LexicalDC;
+    DeclCtx = MDC;
+  }
+}
+
 bool Decl::isInAnonymousNamespace() const {
   const DeclContext *DC = getDeclContext();
   do {
@@ -532,10 +541,10 @@
   llvm_unreachable("Invalid DeclKind!");
 }
 
-void Decl::setAttrs(const AttrVec &attrs) {
+void Decl::setAttrsImpl(const AttrVec &attrs, ASTContext &Ctx) {
   assert(!HasAttrs && "Decl already contains attrs.");
 
-  AttrVec &AttrBlank = getASTContext().getDeclAttrs(this);
+  AttrVec &AttrBlank = Ctx.getDeclAttrs(this);
   assert(AttrBlank.empty() && "HasAttrs was wrong?");
 
   AttrBlank = attrs;
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index fbe861d..690c81c 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -324,12 +324,11 @@
   } else if (D->isTemplateParameter()) {
     // If we have a fully initialized template parameter, we can now
     // set its DeclContext.
-    D->setDeclContext(
-          cast_or_null<DeclContext>(
-                            Reader.GetDecl(DeclContextIDForTemplateParmDecl)));
-    D->setLexicalDeclContext(
-          cast_or_null<DeclContext>(
-                      Reader.GetDecl(LexicalDeclContextIDForTemplateParmDecl)));
+    DeclContext *SemaDC = cast<DeclContext>(
+                              Reader.GetDecl(DeclContextIDForTemplateParmDecl));
+    DeclContext *LexicalDC = cast<DeclContext>(
+                       Reader.GetDecl(LexicalDeclContextIDForTemplateParmDecl));
+    D->setDeclContextsImpl(SemaDC, LexicalDC, Reader.getContext());
   }
 }
 
@@ -343,15 +342,16 @@
     LexicalDeclContextIDForTemplateParmDecl = ReadDeclID(Record, Idx);
     D->setDeclContext(Reader.getContext().getTranslationUnitDecl()); 
   } else {
-    D->setDeclContext(ReadDeclAs<DeclContext>(Record, Idx));
-    D->setLexicalDeclContext(ReadDeclAs<DeclContext>(Record, Idx));
+    DeclContext *SemaDC = ReadDeclAs<DeclContext>(Record, Idx);
+    DeclContext *LexicalDC = ReadDeclAs<DeclContext>(Record, Idx);
+    D->setDeclContextsImpl(SemaDC, LexicalDC, Reader.getContext());
   }
   D->setLocation(Reader.ReadSourceLocation(F, RawLocation));
   D->setInvalidDecl(Record[Idx++]);
   if (Record[Idx++]) { // hasAttrs
     AttrVec Attrs;
     Reader.ReadAttributes(F, Attrs, Record, Idx);
-    D->setAttrs(Attrs);
+    D->setAttrsImpl(Attrs, Reader.getContext());
   }
   D->setImplicit(Record[Idx++]);
   D->setUsed(Record[Idx++]);