Fix C++ PCH issues.

PCH got a severe beating by the boost-using test case reported here: http://llvm.org/PR8099
Fix issues like:

-When PCH reading, make sure Decl's getASTContext() doesn't get called since a Decl in the parent hierarchy may be initializing.
-In ASTDeclReader::VisitFunctionDecl VisitRedeclarable should be called before using FunctionDecl's isCanonicalDecl()
-In ASTDeclReader::VisitRedeclarableTemplateDecl CommonOrPrev must be initialized before anything else.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113391 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index b7be02d..b2beb13 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -1093,13 +1093,14 @@
 
 }
 
-void FunctionDecl::setParams(ParmVarDecl **NewParamInfo, unsigned NumParams) {
+void FunctionDecl::setParams(ASTContext &C,
+                             ParmVarDecl **NewParamInfo, unsigned NumParams) {
   assert(ParamInfo == 0 && "Already has param info!");
   assert(NumParams == getNumParams() && "Parameter count mismatch!");
 
   // Zero params -> null pointer.
   if (NumParams) {
-    void *Mem = getASTContext().Allocate(sizeof(ParmVarDecl*)*NumParams);
+    void *Mem = C.Allocate(sizeof(ParmVarDecl*)*NumParams);
     ParamInfo = new (Mem) ParmVarDecl*[NumParams];
     memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
 
@@ -1271,12 +1272,13 @@
 }
 
 void 
-FunctionDecl::setInstantiationOfMemberFunction(FunctionDecl *FD,
+FunctionDecl::setInstantiationOfMemberFunction(ASTContext &C,
+                                               FunctionDecl *FD,
                                                TemplateSpecializationKind TSK) {
   assert(TemplateOrSpecialization.isNull() && 
          "Member function is already a specialization");
   MemberSpecializationInfo *Info 
-    = new (getASTContext()) MemberSpecializationInfo(FD, TSK);
+    = new (C) MemberSpecializationInfo(FD, TSK);
   TemplateOrSpecialization = Info;
 }
 
@@ -1362,7 +1364,8 @@
 }
 
 void
-FunctionDecl::setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
+FunctionDecl::setFunctionTemplateSpecialization(ASTContext &C,
+                                                FunctionTemplateDecl *Template,
                                      const TemplateArgumentList *TemplateArgs,
                                                 void *InsertPos,
                                                 TemplateSpecializationKind TSK,
@@ -1373,7 +1376,7 @@
   FunctionTemplateSpecializationInfo *Info
     = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>();
   if (!Info)
-    Info = new (getASTContext()) FunctionTemplateSpecializationInfo;
+    Info = new (C) FunctionTemplateSpecializationInfo;
 
   Info->Function = this;
   Info->Template.setPointer(Template);
@@ -1401,28 +1404,6 @@
 }
 
 void
-FunctionDecl::setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
-                                                unsigned NumTemplateArgs,
-                                           const TemplateArgument *TemplateArgs,
-                                                 TemplateSpecializationKind TSK,
-                                              unsigned NumTemplateArgsAsWritten,
-                                   TemplateArgumentLoc *TemplateArgsAsWritten,
-                                                SourceLocation LAngleLoc,
-                                                SourceLocation RAngleLoc,
-                                          SourceLocation PointOfInstantiation) {
-  ASTContext &Ctx = getASTContext();
-  TemplateArgumentList *TemplArgs
-    = new (Ctx) TemplateArgumentList(Ctx, TemplateArgs, NumTemplateArgs);
-  TemplateArgumentListInfo *TemplArgsInfo
-    = new (Ctx) TemplateArgumentListInfo(LAngleLoc, RAngleLoc);
-  for (unsigned i=0; i != NumTemplateArgsAsWritten; ++i)
-    TemplArgsInfo->addArgument(TemplateArgsAsWritten[i]);
-
-  setFunctionTemplateSpecialization(Template, TemplArgs, /*InsertPos=*/0, TSK,
-                                    TemplArgsInfo, PointOfInstantiation);
-}
-
-void
 FunctionDecl::setDependentTemplateSpecialization(ASTContext &Context,
                                     const UnresolvedSetImpl &Templates,
                              const TemplateArgumentListInfo &TemplateArgs) {
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index e69338a..66321d3 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -92,7 +92,7 @@
   RedeclarableTemplateDecl *First = getCanonicalDecl();
 
   if (First->CommonOrPrev.isNull()) {
-    CommonBase *CommonPtr = First->newCommon();
+    CommonBase *CommonPtr = First->newCommon(getASTContext());
     First->CommonOrPrev = CommonPtr;
     CommonPtr->Latest = First;
   }
@@ -156,9 +156,10 @@
   return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl);
 }
 
-RedeclarableTemplateDecl::CommonBase *FunctionTemplateDecl::newCommon() {
-  Common *CommonPtr = new (getASTContext()) Common;
-  getASTContext().AddDeallocation(DeallocateCommon, CommonPtr);
+RedeclarableTemplateDecl::CommonBase *
+FunctionTemplateDecl::newCommon(ASTContext &C) {
+  Common *CommonPtr = new (C) Common;
+  C.AddDeallocation(DeallocateCommon, CommonPtr);
   return CommonPtr;
 }
 
@@ -188,9 +189,10 @@
   return New;
 }
 
-RedeclarableTemplateDecl::CommonBase *ClassTemplateDecl::newCommon() {
-  Common *CommonPtr = new (getASTContext()) Common;
-  getASTContext().AddDeallocation(DeallocateCommon, CommonPtr);
+RedeclarableTemplateDecl::CommonBase *
+ClassTemplateDecl::newCommon(ASTContext &C) {
+  Common *CommonPtr = new (C) Common;
+  C.AddDeallocation(DeallocateCommon, CommonPtr);
   return CommonPtr;
 }
 
diff --git a/lib/AST/TemplateName.cpp b/lib/AST/TemplateName.cpp
index ef7b315..439f4e8 100644
--- a/lib/AST/TemplateName.cpp
+++ b/lib/AST/TemplateName.cpp
@@ -44,8 +44,14 @@
 
 bool TemplateName::isDependent() const {
   if (TemplateDecl *Template = getAsTemplateDecl()) {
-    return isa<TemplateTemplateParmDecl>(Template) ||
-      Template->getDeclContext()->isDependentContext();
+    if (isa<TemplateTemplateParmDecl>(Template))
+      return true;
+    // FIXME: Hack, getDeclContext() can be null if Template is still
+    // initializing due to PCH reading, so we check it before using it.
+    // Should probably modify TemplateSpecializationType to allow constructing
+    // it without the isDependent() checking.
+    return Template->getDeclContext() &&
+           Template->getDeclContext()->isDependentContext();
   }
 
   assert(!getAsOverloadedTemplate() &&