[cfe-commits] r113391 - in /cfe/trunk: include/clang/AST/Decl.h include/clang/AST/DeclTemplate.h lib/AST/Decl.cpp lib/AST/DeclTemplate.cpp lib/AST/TemplateName.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriterDecl.cpp

Argyrios Kyrtzidis akyrtzi at gmail.com
Wed Sep 8 12:31:22 PDT 2010


Author: akirtzidis
Date: Wed Sep  8 14:31:22 2010
New Revision: 113391

URL: http://llvm.org/viewvc/llvm-project?rev=113391&view=rev
Log:
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.

Modified:
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/AST/DeclTemplate.h
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/AST/DeclTemplate.cpp
    cfe/trunk/lib/AST/TemplateName.cpp
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=113391&r1=113390&r2=113391&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Wed Sep  8 14:31:22 2010
@@ -1136,6 +1136,42 @@
   /// declaration name embedded in the DeclaratorDecl base class.
   DeclarationNameLoc DNLoc;
 
+  /// \brief Specify that this function declaration is actually a function
+  /// template specialization.
+  ///
+  /// \param C the ASTContext.
+  ///
+  /// \param Template the function template that this function template
+  /// specialization specializes.
+  ///
+  /// \param TemplateArgs the template arguments that produced this
+  /// function template specialization from the template.
+  ///
+  /// \param InsertPos If non-NULL, the position in the function template
+  /// specialization set where the function template specialization data will
+  /// be inserted.
+  ///
+  /// \param TSK the kind of template specialization this is.
+  ///
+  /// \param TemplateArgsAsWritten location info of template arguments.
+  ///
+  /// \param PointOfInstantiation point at which the function template
+  /// specialization was first instantiated. 
+  void setFunctionTemplateSpecialization(ASTContext &C,
+                                         FunctionTemplateDecl *Template,
+                                       const TemplateArgumentList *TemplateArgs,
+                                         void *InsertPos,
+                                         TemplateSpecializationKind TSK,
+                          const TemplateArgumentListInfo *TemplateArgsAsWritten,
+                                         SourceLocation PointOfInstantiation);
+
+  /// \brief Specify that this record is an instantiation of the
+  /// member function FD.
+  void setInstantiationOfMemberFunction(ASTContext &C, FunctionDecl *FD,
+                                        TemplateSpecializationKind TSK);
+
+  void setParams(ASTContext &C, ParmVarDecl **NewParamInfo, unsigned NumParams);
+
 protected:
   FunctionDecl(Kind DK, DeclContext *DC, const DeclarationNameInfo &NameInfo,
                QualType T, TypeSourceInfo *TInfo,
@@ -1343,7 +1379,9 @@
     assert(i < getNumParams() && "Illegal param #");
     return ParamInfo[i];
   }
-  void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
+  void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams) {
+    setParams(getASTContext(), NewParamInfo, NumParams);
+  }
 
   /// getMinRequiredArguments - Returns the minimum number of arguments
   /// needed to call this function. This may be fewer than the number of
@@ -1432,7 +1470,9 @@
   /// \brief Specify that this record is an instantiation of the
   /// member function FD.
   void setInstantiationOfMemberFunction(FunctionDecl *FD,
-                                        TemplateSpecializationKind TSK);
+                                        TemplateSpecializationKind TSK) {
+    setInstantiationOfMemberFunction(getASTContext(), FD, TSK);
+  }
 
   /// \brief Retrieves the function template that is described by this
   /// function declaration.
@@ -1526,43 +1566,11 @@
                                          void *InsertPos,
                     TemplateSpecializationKind TSK = TSK_ImplicitInstantiation,
                     const TemplateArgumentListInfo *TemplateArgsAsWritten = 0,
-                    SourceLocation PointOfInstantiation = SourceLocation());
-
-  /// \brief Specify that this function declaration is actually a function
-  /// template specialization.
-  ///
-  /// \param Template the function template that this function template
-  /// specialization specializes.
-  ///
-  /// \param NumTemplateArgs number of template arguments that produced this
-  /// function template specialization from the template.
-  ///
-  /// \param TemplateArgs array of template arguments that produced this
-  /// function template specialization from the template.
-  ///
-  /// \param TSK the kind of template specialization this is.
-  ///
-  /// \param NumTemplateArgsAsWritten number of template arguments that produced
-  /// this function template specialization from the template.
-  ///
-  /// \param TemplateArgsAsWritten array of location info for the template
-  /// arguments.
-  ///
-  /// \param LAngleLoc location of left angle token.
-  ///
-  /// \param RAngleLoc location of right angle token.
-  ///
-  /// \param PointOfInstantiation point at which the function template
-  /// specialization was first instantiated. 
-  void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
-                                         unsigned NumTemplateArgs,
-                                         const TemplateArgument *TemplateArgs,
-                                         TemplateSpecializationKind TSK,
-                                         unsigned NumTemplateArgsAsWritten,
-                                     TemplateArgumentLoc *TemplateArgsAsWritten,
-                                          SourceLocation LAngleLoc,
-                                          SourceLocation RAngleLoc,
-                                          SourceLocation PointOfInstantiation);
+                    SourceLocation PointOfInstantiation = SourceLocation()) {
+    setFunctionTemplateSpecialization(getASTContext(), Template, TemplateArgs,
+                                      InsertPos, TSK, TemplateArgsAsWritten,
+                                      PointOfInstantiation);
+  }
 
   /// \brief Specifies that this function declaration is actually a
   /// dependent function template specialization.

Modified: cfe/trunk/include/clang/AST/DeclTemplate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclTemplate.h?rev=113391&r1=113390&r2=113391&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Wed Sep  8 14:31:22 2010
@@ -584,7 +584,7 @@
   /// for the common pointer.
   CommonBase *getCommonPtr();
 
-  virtual CommonBase *newCommon() = 0;
+  virtual CommonBase *newCommon(ASTContext &C) = 0;
 
   // Construct a template decl with name, parameters, and templated element.
   RedeclarableTemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
@@ -789,19 +789,13 @@
                        TemplateParameterList *Params, NamedDecl *Decl)
     : RedeclarableTemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { }
 
-  CommonBase *newCommon();
+  CommonBase *newCommon(ASTContext &C);
 
   Common *getCommonPtr() {
     return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
   }
 
-  friend void FunctionDecl::setFunctionTemplateSpecialization(
-                                       FunctionTemplateDecl *Template,
-                                       const TemplateArgumentList *TemplateArgs,
-                                       void *InsertPos,
-                                       TemplateSpecializationKind TSK,
-                          const TemplateArgumentListInfo *TemplateArgsAsWritten,
-                                       SourceLocation PointOfInstantiation);
+  friend class FunctionDecl;
 
   /// \brief Retrieve the set of function template specializations of this
   /// function template.
@@ -1659,7 +1653,7 @@
                     TemplateParameterList *Params, NamedDecl *Decl)
     : RedeclarableTemplateDecl(ClassTemplate, DC, L, Name, Params, Decl) { }
 
-  CommonBase *newCommon();
+  CommonBase *newCommon(ASTContext &C);
 
   Common *getCommonPtr() {
     return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=113391&r1=113390&r2=113391&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Wed Sep  8 14:31:22 2010
@@ -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) {

Modified: cfe/trunk/lib/AST/DeclTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclTemplate.cpp?rev=113391&r1=113390&r2=113391&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclTemplate.cpp (original)
+++ cfe/trunk/lib/AST/DeclTemplate.cpp Wed Sep  8 14:31:22 2010
@@ -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;
 }
 

Modified: cfe/trunk/lib/AST/TemplateName.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TemplateName.cpp?rev=113391&r1=113390&r2=113391&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TemplateName.cpp (original)
+++ cfe/trunk/lib/AST/TemplateName.cpp Wed Sep  8 14:31:22 2010
@@ -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() &&

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=113391&r1=113390&r2=113391&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Wed Sep  8 14:31:22 2010
@@ -183,8 +183,8 @@
 
 void ASTDeclReader::VisitTagDecl(TagDecl *TD) {
   VisitTypeDecl(TD);
-  TD->IdentifierNamespace = Record[Idx++];
   VisitRedeclarable(TD);
+  TD->IdentifierNamespace = Record[Idx++];
   TD->setTagKind((TagDecl::TagKind)Record[Idx++]);
   TD->setDefinition(Record[Idx++]);
   TD->setEmbeddedInDeclarator(Record[Idx++]);
@@ -234,6 +234,7 @@
 
 void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
   VisitDeclaratorDecl(FD);
+  VisitRedeclarable(FD);
   // FIXME: read DeclarationNameLoc.
 
   FD->IdentifierNamespace = Record[Idx++];
@@ -250,7 +251,7 @@
     FunctionDecl *InstFD = cast<FunctionDecl>(Reader.GetDecl(Record[Idx++]));
     TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
     SourceLocation POI = Reader.ReadSourceLocation(Record, Idx);
-    FD->setInstantiationOfMemberFunction(InstFD, TSK);
+    FD->setInstantiationOfMemberFunction(*Reader.getContext(), InstFD, TSK);
     FD->getMemberSpecializationInfo()->setPointOfInstantiation(POI);
     break;
   }
@@ -279,12 +280,26 @@
     
     SourceLocation POI = Reader.ReadSourceLocation(Record, Idx);
 
-    if (FD->isCanonicalDecl()) // if canonical add to template's set.
-      FD->setFunctionTemplateSpecialization(Template, TemplArgs.size(),
-                                            TemplArgs.data(), TSK,
-                                            TemplArgLocs.size(),
-                                            TemplArgLocs.data(),
-                                            LAngleLoc, RAngleLoc, POI);
+    if (FD->isCanonicalDecl()) { // if canonical add to template's set.
+      ASTContext &C = *Reader.getContext();
+      TemplateArgumentList *TemplArgList
+        = new (C) TemplateArgumentList(C, TemplArgs.data(), TemplArgs.size());
+      TemplateArgumentListInfo *TemplArgsInfo
+        = new (C) TemplateArgumentListInfo(LAngleLoc, RAngleLoc);
+      for (unsigned i=0, e = TemplArgLocs.size(); i != e; ++i)
+        TemplArgsInfo->addArgument(TemplArgLocs[i]);
+
+      llvm::FoldingSetNodeID ID;
+      FunctionTemplateSpecializationInfo::Profile(ID, TemplArgs.data(),
+                                                  TemplArgs.size(), C);
+      void *InsertPos = 0;
+      FunctionTemplateSpecializationInfo *PrevFTInfo =
+          Template->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
+      (void)PrevFTInfo;
+      assert(!PrevFTInfo && "Another specialization already inserted!");
+      FD->setFunctionTemplateSpecialization(C, Template, TemplArgList, InsertPos,
+                                            TSK, TemplArgsInfo, POI);
+    }
     break;
   }
   case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
@@ -311,7 +326,6 @@
   // FunctionDecl's body is handled last at ASTDeclReader::Visit,
   // after everything else is read.
 
-  VisitRedeclarable(FD);
   FD->setStorageClass((StorageClass)Record[Idx++]);
   FD->setStorageClassAsWritten((StorageClass)Record[Idx++]);
   FD->setInlineSpecified(Record[Idx++]);
@@ -331,7 +345,7 @@
   Params.reserve(NumParams);
   for (unsigned I = 0; I != NumParams; ++I)
     Params.push_back(cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
-  FD->setParams(Params.data(), NumParams);
+  FD->setParams(*Reader.getContext(), Params.data(), NumParams);
 }
 
 void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
@@ -567,13 +581,13 @@
 
 void ASTDeclReader::VisitVarDecl(VarDecl *VD) {
   VisitDeclaratorDecl(VD);
+  VisitRedeclarable(VD);
   VD->setStorageClass((StorageClass)Record[Idx++]);
   VD->setStorageClassAsWritten((StorageClass)Record[Idx++]);
   VD->setThreadSpecified(Record[Idx++]);
   VD->setCXXDirectInitializer(Record[Idx++]);
   VD->setExceptionVariable(Record[Idx++]);
   VD->setNRVOVariable(Record[Idx++]);
-  VisitRedeclarable(VD);
   if (Record[Idx++])
     VD->setInit(Reader.ReadExpr(Cursor));
 
@@ -864,9 +878,10 @@
 }
 
 void ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
-  VisitTemplateDecl(D);
+  // Initialize CommonOrPrev before VisitTemplateDecl so that getCommonPtr()
+  // can be used while this is still initializing.
 
-  D->IdentifierNamespace = Record[Idx++];
+  assert(D->CommonOrPrev.isNull() && "getCommonPtr was called earlier on this");
   RedeclarableTemplateDecl *PrevDecl =
       cast_or_null<RedeclarableTemplateDecl>(Reader.GetDecl(Record[Idx++]));
   assert((PrevDecl == 0 || PrevDecl->getKind() == D->getKind()) &&
@@ -874,6 +889,7 @@
   if (PrevDecl)
     D->CommonOrPrev = PrevDecl;
   if (PrevDecl == 0) {
+    D->CommonOrPrev = D->newCommon(*Reader.getContext());
     if (RedeclarableTemplateDecl *RTD
           = cast_or_null<RedeclarableTemplateDecl>(Reader.GetDecl(Record[Idx++]))) {
       assert(RTD->getKind() == D->getKind() &&
@@ -907,6 +923,9 @@
     assert(LatestDecl->getKind() == D->getKind() && "Latest kind mismatch");
     D->getCommonPtr()->Latest = LatestDecl;
   }
+
+  VisitTemplateDecl(D);
+  D->IdentifierNamespace = Record[Idx++];
 }
 
 void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {

Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=113391&r1=113390&r2=113391&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Wed Sep  8 14:31:22 2010
@@ -163,8 +163,8 @@
 
 void ASTDeclWriter::VisitTagDecl(TagDecl *D) {
   VisitTypeDecl(D);
-  Record.push_back(D->getIdentifierNamespace());
   VisitRedeclarable(D);
+  Record.push_back(D->getIdentifierNamespace());
   Record.push_back((unsigned)D->getTagKind()); // FIXME: stable encoding
   Record.push_back(D->isDefinition());
   Record.push_back(D->isEmbeddedInDeclarator());
@@ -214,6 +214,7 @@
 
 void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
   VisitDeclaratorDecl(D);
+  VisitRedeclarable(D);
   // FIXME: write DeclarationNameLoc.
 
   Record.push_back(D->getIdentifierNamespace());
@@ -281,7 +282,6 @@
   // FunctionDecl's body is handled last at ASTWriterDecl::Visit,
   // after everything else is written.
 
-  VisitRedeclarable(D);
   Record.push_back(D->getStorageClass()); // FIXME: stable encoding
   Record.push_back(D->getStorageClassAsWritten());
   Record.push_back(D->isInlineSpecified());
@@ -513,13 +513,13 @@
 
 void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
   VisitDeclaratorDecl(D);
+  VisitRedeclarable(D);
   Record.push_back(D->getStorageClass()); // FIXME: stable encoding
   Record.push_back(D->getStorageClassAsWritten());
   Record.push_back(D->isThreadSpecified());
   Record.push_back(D->hasCXXDirectInitializer());
   Record.push_back(D->isExceptionVariable());
   Record.push_back(D->isNRVOVariable());
-  VisitRedeclarable(D);
   Record.push_back(D->getInit() ? 1 : 0);
   if (D->getInit())
     Writer.AddStmt(D->getInit());
@@ -840,9 +840,9 @@
 }
 
 void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
-  VisitTemplateDecl(D);
+  // Emit data to initialize CommonOrPrev before VisitTemplateDecl so that
+  // getCommonPtr() can be used while this is still initializing.
 
-  Record.push_back(D->getIdentifierNamespace());
   Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
   if (D->getPreviousDeclaration() == 0) {
     // This TemplateDecl owns the CommonPtr; write it.
@@ -866,6 +866,9 @@
       Writer.FirstLatestDecls[First] = D;
     }
   }
+
+  VisitTemplateDecl(D);
+  Record.push_back(D->getIdentifierNamespace());
 }
 
 void ASTDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) {





More information about the cfe-commits mailing list