diff options
Diffstat (limited to 'lib/Frontend/PCHReaderDecl.cpp')
| -rw-r--r-- | lib/Frontend/PCHReaderDecl.cpp | 609 | 
1 files changed, 508 insertions, 101 deletions
diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp index 1ef0441ebf608..742f0e46b92ca 100644 --- a/lib/Frontend/PCHReaderDecl.cpp +++ b/lib/Frontend/PCHReaderDecl.cpp @@ -27,16 +27,19 @@ using namespace clang;  // Declaration deserialization  //===----------------------------------------------------------------------===// -namespace { +namespace clang {    class PCHDeclReader : public DeclVisitor<PCHDeclReader, void> {      PCHReader &Reader;      const PCHReader::RecordData &Record;      unsigned &Idx; +    pch::TypeID TypeIDForTypeDecl;    public:      PCHDeclReader(PCHReader &Reader, const PCHReader::RecordData &Record,                    unsigned &Idx) -      : Reader(Reader), Record(Record), Idx(Idx) { } +      : Reader(Reader), Record(Record), Idx(Idx), TypeIDForTypeDecl(0) { } + +    void Visit(Decl *D);      void VisitDecl(Decl *D);      void VisitTranslationUnitDecl(TranslationUnitDecl *TU); @@ -46,7 +49,7 @@ namespace {      void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);      void VisitTypeDecl(TypeDecl *TD);      void VisitTypedefDecl(TypedefDecl *TD); -    void VisitUnresolvedUsingTypename(UnresolvedUsingTypenameDecl *D); +    void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);      void VisitTagDecl(TagDecl *TD);      void VisitEnumDecl(EnumDecl *ED);      void VisitRecordDecl(RecordDecl *RD); @@ -58,7 +61,7 @@ namespace {      void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);      void VisitValueDecl(ValueDecl *VD);      void VisitEnumConstantDecl(EnumConstantDecl *ECD); -    void VisitUnresolvedUsingValue(UnresolvedUsingValueDecl *D); +    void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);      void VisitDeclaratorDecl(DeclaratorDecl *DD);      void VisitFunctionDecl(FunctionDecl *FD);      void VisitCXXMethodDecl(CXXMethodDecl *D); @@ -72,19 +75,21 @@ namespace {      void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);      void VisitTemplateDecl(TemplateDecl *D);      void VisitClassTemplateDecl(ClassTemplateDecl *D); -    void visitFunctionTemplateDecl(FunctionTemplateDecl *D); +    void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);      void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D); -    void VisitUsing(UsingDecl *D); -    void VisitUsingShadow(UsingShadowDecl *D); +    void VisitUsingDecl(UsingDecl *D); +    void VisitUsingShadowDecl(UsingShadowDecl *D);      void VisitLinkageSpecDecl(LinkageSpecDecl *D);      void VisitFileScopeAsmDecl(FileScopeAsmDecl *AD); +    void VisitAccessSpecDecl(AccessSpecDecl *D); +    void VisitFriendDecl(FriendDecl *D);      void VisitFriendTemplateDecl(FriendTemplateDecl *D);      void VisitStaticAssertDecl(StaticAssertDecl *D);      void VisitBlockDecl(BlockDecl *BD);      std::pair<uint64_t, uint64_t> VisitDeclContext(DeclContext *DC); -    // FIXME: Reorder according to DeclNodes.def? +    // FIXME: Reorder according to DeclNodes.td?      void VisitObjCMethodDecl(ObjCMethodDecl *D);      void VisitObjCContainerDecl(ObjCContainerDecl *D);      void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D); @@ -103,6 +108,19 @@ namespace {    };  } +void PCHDeclReader::Visit(Decl *D) { +  DeclVisitor<PCHDeclReader, void>::Visit(D); + +  if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) { +    // if we have a fully initialized TypeDecl, we can safely read its type now. +    TD->setTypeForDecl(Reader.GetType(TypeIDForTypeDecl).getTypePtr()); +  } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { +    // FunctionDecl's body was written last after all other Stmts/Exprs. +    if (Record[Idx++]) +      FD->setLazyBody(Reader.getDeclsCursor().GetCurrentBitNo()); +  } +} +  void PCHDeclReader::VisitDecl(Decl *D) {    D->setDeclContext(cast_or_null<DeclContext>(Reader.GetDecl(Record[Idx++])));    D->setLexicalDeclContext( @@ -110,7 +128,7 @@ void PCHDeclReader::VisitDecl(Decl *D) {    D->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));    D->setInvalidDecl(Record[Idx++]);    if (Record[Idx++]) -    D->addAttr(Reader.ReadAttributes()); +    D->initAttrs(Reader.ReadAttributes());    D->setImplicit(Record[Idx++]);    D->setUsed(Record[Idx++]);    D->setAccess((AccessSpecifier)Record[Idx++]); @@ -130,21 +148,18 @@ void PCHDeclReader::VisitNamedDecl(NamedDecl *ND) {  void PCHDeclReader::VisitTypeDecl(TypeDecl *TD) {    VisitNamedDecl(TD); -  TD->setTypeForDecl(Reader.GetType(Record[Idx++]).getTypePtr()); +  // Delay type reading until after we have fully initialized the decl. +  TypeIDForTypeDecl = Record[Idx++];  }  void PCHDeclReader::VisitTypedefDecl(TypedefDecl *TD) { -  // Note that we cannot use VisitTypeDecl here, because we need to -  // set the underlying type of the typedef *before* we try to read -  // the type associated with the TypedefDecl. -  VisitNamedDecl(TD); -  uint64_t TypeData = Record[Idx++]; +  VisitTypeDecl(TD);    TD->setTypeSourceInfo(Reader.GetTypeSourceInfo(Record, Idx)); -  TD->setTypeForDecl(Reader.GetType(TypeData).getTypePtr());  }  void PCHDeclReader::VisitTagDecl(TagDecl *TD) {    VisitTypeDecl(TD); +  TD->IdentifierNamespace = Record[Idx++];    TD->setPreviousDeclaration(                          cast_or_null<TagDecl>(Reader.GetDecl(Record[Idx++])));    TD->setTagKind((TagDecl::TagKind)Record[Idx++]); @@ -163,7 +178,8 @@ void PCHDeclReader::VisitEnumDecl(EnumDecl *ED) {    ED->setPromotionType(Reader.GetType(Record[Idx++]));    ED->setNumPositiveBits(Record[Idx++]);    ED->setNumNegativeBits(Record[Idx++]); -  // FIXME: C++ InstantiatedFrom +  ED->setInstantiationOfMemberEnum( +                         cast_or_null<EnumDecl>(Reader.GetDecl(Record[Idx++])));  }  void PCHDeclReader::VisitRecordDecl(RecordDecl *RD) { @@ -181,7 +197,7 @@ void PCHDeclReader::VisitValueDecl(ValueDecl *VD) {  void PCHDeclReader::VisitEnumConstantDecl(EnumConstantDecl *ECD) {    VisitValueDecl(ECD);    if (Record[Idx++]) -    ECD->setInitExpr(Reader.ReadDeclExpr()); +    ECD->setInitExpr(Reader.ReadExpr());    ECD->setInitVal(Reader.ReadAPSInt(Record, Idx));  } @@ -195,9 +211,83 @@ void PCHDeclReader::VisitDeclaratorDecl(DeclaratorDecl *DD) {  void PCHDeclReader::VisitFunctionDecl(FunctionDecl *FD) {    VisitDeclaratorDecl(FD); -  if (Record[Idx++]) -    FD->setLazyBody(Reader.getDeclsCursor().GetCurrentBitNo()); -  FD->setPreviousDeclaration( + +  FD->IdentifierNamespace = Record[Idx++]; +  switch ((FunctionDecl::TemplatedKind)Record[Idx++]) { +  default: assert(false && "Unhandled TemplatedKind!"); +    break; +  case FunctionDecl::TK_NonTemplate: +    break; +  case FunctionDecl::TK_FunctionTemplate: +    FD->setDescribedFunctionTemplate( +                     cast<FunctionTemplateDecl>(Reader.GetDecl(Record[Idx++]))); +    break; +  case FunctionDecl::TK_MemberSpecialization: { +    FunctionDecl *InstFD = cast<FunctionDecl>(Reader.GetDecl(Record[Idx++])); +    TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++]; +    SourceLocation POI = Reader.ReadSourceLocation(Record, Idx); +    FD->setInstantiationOfMemberFunction(InstFD, TSK); +    FD->getMemberSpecializationInfo()->setPointOfInstantiation(POI); +    break; +  } +  case FunctionDecl::TK_FunctionTemplateSpecialization: { +    FunctionTemplateDecl *Template +      = cast<FunctionTemplateDecl>(Reader.GetDecl(Record[Idx++])); +    TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++]; +     +    // Template arguments. +    llvm::SmallVector<TemplateArgument, 8> TemplArgs; +    Reader.ReadTemplateArgumentList(TemplArgs, Record, Idx); +     +    // Template args as written. +    llvm::SmallVector<TemplateArgumentLoc, 8> TemplArgLocs; +    SourceLocation LAngleLoc, RAngleLoc; +    if (Record[Idx++]) {  // TemplateArgumentsAsWritten != 0 +      unsigned NumTemplateArgLocs = Record[Idx++]; +      TemplArgLocs.reserve(NumTemplateArgLocs); +      for (unsigned i=0; i != NumTemplateArgLocs; ++i) +        TemplArgLocs.push_back(Reader.ReadTemplateArgumentLoc(Record, Idx)); +   +      LAngleLoc = Reader.ReadSourceLocation(Record, Idx); +      RAngleLoc = Reader.ReadSourceLocation(Record, Idx); +    } +     +    SourceLocation POI = Reader.ReadSourceLocation(Record, Idx); + +    FD->setFunctionTemplateSpecialization(Template, TemplArgs.size(), +                                          TemplArgs.data(), TSK, +                                          TemplArgLocs.size(), +                                          TemplArgLocs.data(), +                                          LAngleLoc, RAngleLoc, POI); +    break; +  } +  case FunctionDecl::TK_DependentFunctionTemplateSpecialization: { +    // Templates. +    UnresolvedSet<8> TemplDecls; +    unsigned NumTemplates = Record[Idx++]; +    while (NumTemplates--) +      TemplDecls.addDecl(cast<NamedDecl>(Reader.GetDecl(Record[Idx++]))); +     +    // Templates args. +    TemplateArgumentListInfo TemplArgs; +    unsigned NumArgs = Record[Idx++]; +    while (NumArgs--) +      TemplArgs.addArgument(Reader.ReadTemplateArgumentLoc(Record, Idx)); +    TemplArgs.setLAngleLoc(Reader.ReadSourceLocation(Record, Idx)); +    TemplArgs.setRAngleLoc(Reader.ReadSourceLocation(Record, Idx)); +     +    FD->setDependentTemplateSpecialization(*Reader.getContext(), +                                           TemplDecls, TemplArgs); +    break; +  } +  } + +  // FunctionDecl's body is handled last at PCHReaderDecl::Visit, +  // after everything else is read. + +  // Avoid side effects and invariant checking of FunctionDecl's +  // setPreviousDeclaration. +  FD->redeclarable_base::setPreviousDeclaration(                     cast_or_null<FunctionDecl>(Reader.GetDecl(Record[Idx++])));    FD->setStorageClass((FunctionDecl::StorageClass)Record[Idx++]);    FD->setStorageClassAsWritten((FunctionDecl::StorageClass)Record[Idx++]); @@ -211,7 +301,6 @@ void PCHDeclReader::VisitFunctionDecl(FunctionDecl *FD) {    FD->setCopyAssignment(Record[Idx++]);    FD->setHasImplicitReturnZero(Record[Idx++]);    FD->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++])); -  // FIXME: C++ TemplateOrInstantiation    // Read in the parameters.    unsigned NumParams = Record[Idx++]; @@ -220,11 +309,6 @@ void PCHDeclReader::VisitFunctionDecl(FunctionDecl *FD) {    for (unsigned I = 0; I != NumParams; ++I)      Params.push_back(cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));    FD->setParams(Params.data(), NumParams); - -  // FIXME: order this properly w.r.t. friendness -  // FIXME: this same thing needs to happen for function templates -  if (FD->isOverloadedOperator() && !FD->getDeclContext()->isRecord()) -    FD->setNonMemberOperator();  }  void PCHDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) { @@ -232,7 +316,7 @@ void PCHDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {    if (Record[Idx++]) {      // In practice, this won't be executed (since method definitions      // don't occur in header files). -    MD->setBody(Reader.ReadDeclStmt()); +    MD->setBody(Reader.ReadStmt());      MD->setSelfDecl(cast<ImplicitParamDecl>(Reader.GetDecl(Record[Idx++])));      MD->setCmdDecl(cast<ImplicitParamDecl>(Reader.GetDecl(Record[Idx++])));    } @@ -374,10 +458,12 @@ void PCHDeclReader::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) {  void PCHDeclReader::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {    VisitNamedDecl(D);    D->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); -  D->setType(Reader.GetType(Record[Idx++])); +  D->setType(Reader.GetTypeSourceInfo(Record, Idx));    // FIXME: stable encoding    D->setPropertyAttributes(                        (ObjCPropertyDecl::PropertyAttributeKind)Record[Idx++]); +  D->setPropertyAttributesAsWritten( +                      (ObjCPropertyDecl::PropertyAttributeKind)Record[Idx++]);    // FIXME: stable encoding    D->setPropertyImplementation(                              (ObjCPropertyDecl::PropertyControl)Record[Idx++]); @@ -424,7 +510,12 @@ void PCHDeclReader::VisitFieldDecl(FieldDecl *FD) {    VisitDeclaratorDecl(FD);    FD->setMutable(Record[Idx++]);    if (Record[Idx++]) -    FD->setBitWidth(Reader.ReadDeclExpr()); +    FD->setBitWidth(Reader.ReadExpr()); +  if (!FD->getDeclName()) { +    FieldDecl *Tmpl = cast_or_null<FieldDecl>(Reader.GetDecl(Record[Idx++])); +    if (Tmpl) +      Reader.getContext()->setInstantiatedFromUnnamedFieldDecl(FD, Tmpl); +  }  }  void PCHDeclReader::VisitVarDecl(VarDecl *VD) { @@ -439,7 +530,14 @@ void PCHDeclReader::VisitVarDecl(VarDecl *VD) {    VD->setPreviousDeclaration(                           cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++])));    if (Record[Idx++]) -    VD->setInit(Reader.ReadDeclExpr()); +    VD->setInit(Reader.ReadExpr()); + +  if (Record[Idx++]) { // HasMemberSpecializationInfo. +    VarDecl *Tmpl = cast<VarDecl>(Reader.GetDecl(Record[Idx++])); +    TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++]; +    SourceLocation POI = Reader.ReadSourceLocation(Record, Idx); +    Reader.getContext()->setInstantiatedFromStaticDataMember(VD, Tmpl, TSK,POI); +  }  }  void PCHDeclReader::VisitImplicitParamDecl(ImplicitParamDecl *PD) { @@ -450,16 +548,19 @@ void PCHDeclReader::VisitParmVarDecl(ParmVarDecl *PD) {    VisitVarDecl(PD);    PD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]);    PD->setHasInheritedDefaultArg(Record[Idx++]); +  if (Record[Idx++]) // hasUninstantiatedDefaultArg. +    PD->setUninstantiatedDefaultArg(Reader.ReadExpr());  }  void PCHDeclReader::VisitFileScopeAsmDecl(FileScopeAsmDecl *AD) {    VisitDecl(AD); -  AD->setAsmString(cast<StringLiteral>(Reader.ReadDeclExpr())); +  AD->setAsmString(cast<StringLiteral>(Reader.ReadExpr()));  }  void PCHDeclReader::VisitBlockDecl(BlockDecl *BD) {    VisitDecl(BD); -  BD->setBody(cast_or_null<CompoundStmt>(Reader.ReadDeclStmt())); +  BD->setBody(cast_or_null<CompoundStmt>(Reader.ReadStmt())); +  BD->setSignatureAsWritten(Reader.GetTypeSourceInfo(Record, Idx));    unsigned NumParams = Record[Idx++];    llvm::SmallVector<ParmVarDecl *, 16> Params;    Params.reserve(NumParams); @@ -481,13 +582,9 @@ void PCHDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {    D->setNextNamespace(                      cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++]))); -  // Only read one reference--the original or anonymous namespace.    bool IsOriginal = Record[Idx++]; -  if (IsOriginal) -    D->setAnonymousNamespace( -                    cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++]))); -  else -    D->setOriginalNamespace( +  D->OrigOrAnonNamespace.setInt(IsOriginal); +  D->OrigOrAnonNamespace.setPointer(                      cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));  } @@ -501,7 +598,7 @@ void PCHDeclReader::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {    D->setAliasedNamespace(cast<NamedDecl>(Reader.GetDecl(Record[Idx++])));  } -void PCHDeclReader::VisitUsing(UsingDecl *D) { +void PCHDeclReader::VisitUsingDecl(UsingDecl *D) {    VisitNamedDecl(D);    D->setUsingLocation(Reader.ReadSourceLocation(Record, Idx));    D->setNestedNameRange(Reader.ReadSourceRange(Record, Idx)); @@ -512,15 +609,24 @@ void PCHDeclReader::VisitUsing(UsingDecl *D) {    // would avoid existence checks.    unsigned NumShadows = Record[Idx++];    for(unsigned I = 0; I != NumShadows; ++I) { -    D->addShadowDecl(cast<UsingShadowDecl>(Reader.GetDecl(Record[Idx++]))); +    // Avoid invariant checking of UsingDecl::addShadowDecl, the decl may still +    // be initializing. +    D->Shadows.insert(cast<UsingShadowDecl>(Reader.GetDecl(Record[Idx++])));    }    D->setTypeName(Record[Idx++]); +  NamedDecl *Pattern = cast_or_null<NamedDecl>(Reader.GetDecl(Record[Idx++])); +  if (Pattern) +    Reader.getContext()->setInstantiatedFromUsingDecl(D, Pattern);  } -void PCHDeclReader::VisitUsingShadow(UsingShadowDecl *D) { +void PCHDeclReader::VisitUsingShadowDecl(UsingShadowDecl *D) {    VisitNamedDecl(D);    D->setTargetDecl(cast<NamedDecl>(Reader.GetDecl(Record[Idx++])));    D->setUsingDecl(cast<UsingDecl>(Reader.GetDecl(Record[Idx++]))); +  UsingShadowDecl *Pattern +      = cast_or_null<UsingShadowDecl>(Reader.GetDecl(Record[Idx++])); +  if (Pattern) +    Reader.getContext()->setInstantiatedFromUsingShadowDecl(D, Pattern);  }  void PCHDeclReader::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { @@ -534,14 +640,14 @@ void PCHDeclReader::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {                                                  Reader.GetDecl(Record[Idx++])));  } -void PCHDeclReader::VisitUnresolvedUsingValue(UnresolvedUsingValueDecl *D) { +void PCHDeclReader::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {    VisitValueDecl(D);    D->setTargetNestedNameRange(Reader.ReadSourceRange(Record, Idx));    D->setUsingLoc(Reader.ReadSourceLocation(Record, Idx));    D->setTargetNestedNameSpecifier(Reader.ReadNestedNameSpecifier(Record, Idx));  } -void PCHDeclReader::VisitUnresolvedUsingTypename( +void PCHDeclReader::VisitUnresolvedUsingTypenameDecl(                                                 UnresolvedUsingTypenameDecl *D) {    VisitTypeDecl(D);    D->setTargetNestedNameRange(Reader.ReadSourceRange(Record, Idx)); @@ -551,28 +657,196 @@ void PCHDeclReader::VisitUnresolvedUsingTypename(  }  void PCHDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) { -  // assert(false && "cannot read CXXRecordDecl"); +  ASTContext &C = *Reader.getContext(); + +  // We need to allocate the DefinitionData struct ahead of VisitRecordDecl +  // so that the other CXXRecordDecls can get a pointer even when the owner +  // is still initializing. +  bool OwnsDefinitionData = false; +  enum DataOwnership { Data_NoDefData, Data_Owner, Data_NotOwner }; +  switch ((DataOwnership)Record[Idx++]) { +  default: +    assert(0 && "Out of sync with PCHDeclWriter or messed up reading"); +  case Data_NoDefData: +    break; +  case Data_Owner: +    OwnsDefinitionData = true; +    D->DefinitionData = new (C) struct CXXRecordDecl::DefinitionData(D); +    break; +  case Data_NotOwner: +    D->DefinitionData +        = cast<CXXRecordDecl>(Reader.GetDecl(Record[Idx++]))->DefinitionData; +    break; +  } +    VisitRecordDecl(D); + +  if (OwnsDefinitionData) { +    assert(D->DefinitionData); +    struct CXXRecordDecl::DefinitionData &Data = *D->DefinitionData; + +    Data.UserDeclaredConstructor = Record[Idx++]; +    Data.UserDeclaredCopyConstructor = Record[Idx++]; +    Data.UserDeclaredCopyAssignment = Record[Idx++]; +    Data.UserDeclaredDestructor = Record[Idx++]; +    Data.Aggregate = Record[Idx++]; +    Data.PlainOldData = Record[Idx++]; +    Data.Empty = Record[Idx++]; +    Data.Polymorphic = Record[Idx++]; +    Data.Abstract = Record[Idx++]; +    Data.HasTrivialConstructor = Record[Idx++]; +    Data.HasTrivialCopyConstructor = Record[Idx++]; +    Data.HasTrivialCopyAssignment = Record[Idx++]; +    Data.HasTrivialDestructor = Record[Idx++]; +    Data.ComputedVisibleConversions = Record[Idx++]; +    Data.DeclaredDefaultConstructor = Record[Idx++]; +    Data.DeclaredCopyConstructor = Record[Idx++]; +    Data.DeclaredCopyAssignment = Record[Idx++]; +    Data.DeclaredDestructor = Record[Idx++]; + +    // setBases() is unsuitable since it may try to iterate the bases of an +    // unitialized base. +    Data.NumBases = Record[Idx++]; +    Data.Bases = new(C) CXXBaseSpecifier [Data.NumBases]; +    for (unsigned i = 0; i != Data.NumBases; ++i) +      Data.Bases[i] = Reader.ReadCXXBaseSpecifier(Record, Idx); + +    // FIXME: Make VBases lazily computed when needed to avoid storing them. +    Data.NumVBases = Record[Idx++]; +    Data.VBases = new(C) CXXBaseSpecifier [Data.NumVBases]; +    for (unsigned i = 0; i != Data.NumVBases; ++i) +      Data.VBases[i] = Reader.ReadCXXBaseSpecifier(Record, Idx); + +    Reader.ReadUnresolvedSet(Data.Conversions, Record, Idx); +    Reader.ReadUnresolvedSet(Data.VisibleConversions, Record, Idx); +    assert(Data.Definition && "Data.Definition should be already set!"); +    Data.FirstFriend +        = cast_or_null<FriendDecl>(Reader.GetDecl(Record[Idx++])); +  } + +  enum CXXRecKind { +    CXXRecNotTemplate = 0, CXXRecTemplate, CXXRecMemberSpecialization +  }; +  switch ((CXXRecKind)Record[Idx++]) { +  default: +    assert(false && "Out of sync with PCHDeclWriter::VisitCXXRecordDecl?"); +  case CXXRecNotTemplate: +    break; +  case CXXRecTemplate: +    D->setDescribedClassTemplate( +                        cast<ClassTemplateDecl>(Reader.GetDecl(Record[Idx++]))); +    break; +  case CXXRecMemberSpecialization: { +    CXXRecordDecl *RD = cast<CXXRecordDecl>(Reader.GetDecl(Record[Idx++])); +    TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++]; +    SourceLocation POI = Reader.ReadSourceLocation(Record, Idx); +    D->setInstantiationOfMemberClass(RD, TSK); +    D->getMemberSpecializationInfo()->setPointOfInstantiation(POI); +    break; +  } +  }  }  void PCHDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) { -  // assert(false && "cannot read CXXMethodDecl");    VisitFunctionDecl(D); +  unsigned NumOverridenMethods = Record[Idx++]; +  while (NumOverridenMethods--) { +    CXXMethodDecl *MD = cast<CXXMethodDecl>(Reader.GetDecl(Record[Idx++])); +    // Avoid invariant checking of CXXMethodDecl::addOverriddenMethod, +    // MD may be initializing. +    Reader.getContext()->addOverriddenMethod(D, MD); +  }  }  void PCHDeclReader::VisitCXXConstructorDecl(CXXConstructorDecl *D) { -  // assert(false && "cannot read CXXConstructorDecl");    VisitCXXMethodDecl(D); +   +  D->IsExplicitSpecified = Record[Idx++]; +  D->ImplicitlyDefined = Record[Idx++]; +   +  unsigned NumInitializers = Record[Idx++]; +  D->NumBaseOrMemberInitializers = NumInitializers; +  if (NumInitializers) { +    ASTContext &C = *Reader.getContext(); + +    D->BaseOrMemberInitializers +        = new (C) CXXBaseOrMemberInitializer*[NumInitializers]; +    for (unsigned i=0; i != NumInitializers; ++i) { +      TypeSourceInfo *BaseClassInfo = 0; +      bool IsBaseVirtual = false; +      FieldDecl *Member = 0; +   +      bool IsBaseInitializer = Record[Idx++]; +      if (IsBaseInitializer) { +        BaseClassInfo = Reader.GetTypeSourceInfo(Record, Idx); +        IsBaseVirtual = Record[Idx++]; +      } else { +        Member = cast<FieldDecl>(Reader.GetDecl(Record[Idx++])); +      } +      SourceLocation MemberLoc = Reader.ReadSourceLocation(Record, Idx); +      Expr *Init = Reader.ReadExpr(); +      FieldDecl *AnonUnionMember +          = cast_or_null<FieldDecl>(Reader.GetDecl(Record[Idx++])); +      SourceLocation LParenLoc = Reader.ReadSourceLocation(Record, Idx); +      SourceLocation RParenLoc = Reader.ReadSourceLocation(Record, Idx); +      bool IsWritten = Record[Idx++]; +      unsigned SourceOrderOrNumArrayIndices; +      llvm::SmallVector<VarDecl *, 8> Indices; +      if (IsWritten) { +        SourceOrderOrNumArrayIndices = Record[Idx++]; +      } else { +        SourceOrderOrNumArrayIndices = Record[Idx++]; +        Indices.reserve(SourceOrderOrNumArrayIndices); +        for (unsigned i=0; i != SourceOrderOrNumArrayIndices; ++i) +          Indices.push_back(cast<VarDecl>(Reader.GetDecl(Record[Idx++]))); +      } +       +      CXXBaseOrMemberInitializer *BOMInit; +      if (IsBaseInitializer) { +        BOMInit = new (C) CXXBaseOrMemberInitializer(C, BaseClassInfo, +                                                     IsBaseVirtual, LParenLoc, +                                                     Init, RParenLoc); +      } else if (IsWritten) { +        BOMInit = new (C) CXXBaseOrMemberInitializer(C, Member, MemberLoc, +                                                     LParenLoc, Init, RParenLoc); +      } else { +        BOMInit = CXXBaseOrMemberInitializer::Create(C, Member, MemberLoc, +                                                     LParenLoc, Init, RParenLoc, +                                                     Indices.data(), +                                                     Indices.size()); +      } + +      BOMInit->setAnonUnionMember(AnonUnionMember); +      D->BaseOrMemberInitializers[i] = BOMInit; +    } +  }  }  void PCHDeclReader::VisitCXXDestructorDecl(CXXDestructorDecl *D) { -  // assert(false && "cannot read CXXDestructorDecl");    VisitCXXMethodDecl(D); + +  D->ImplicitlyDefined = Record[Idx++]; +  D->OperatorDelete = cast_or_null<FunctionDecl>(Reader.GetDecl(Record[Idx++]));  }  void PCHDeclReader::VisitCXXConversionDecl(CXXConversionDecl *D) { -  // assert(false && "cannot read CXXConversionDecl");    VisitCXXMethodDecl(D); +  D->IsExplicitSpecified = Record[Idx++]; +} + +void PCHDeclReader::VisitAccessSpecDecl(AccessSpecDecl *D) { +  VisitDecl(D); +  D->setColonLoc(Reader.ReadSourceLocation(Record, Idx)); +} + +void PCHDeclReader::VisitFriendDecl(FriendDecl *D) { +  VisitDecl(D); +  if (Record[Idx++]) +    D->Friend = Reader.GetTypeSourceInfo(Record, Idx); +  else +    D->Friend = cast<NamedDecl>(Reader.GetDecl(Record[Idx++])); +  D->NextFriend = cast_or_null<FriendDecl>(Reader.GetDecl(Record[Idx++])); +  D->FriendLoc = Reader.ReadSourceLocation(Record, Idx);  }  void PCHDeclReader::VisitFriendTemplateDecl(FriendTemplateDecl *D) { @@ -580,37 +854,171 @@ void PCHDeclReader::VisitFriendTemplateDecl(FriendTemplateDecl *D) {  }  void PCHDeclReader::VisitTemplateDecl(TemplateDecl *D) { -  assert(false && "cannot read TemplateDecl"); +  VisitNamedDecl(D); + +  NamedDecl *TemplatedDecl +    = cast_or_null<NamedDecl>(Reader.GetDecl(Record[Idx++])); +  TemplateParameterList* TemplateParams +      = Reader.ReadTemplateParameterList(Record, Idx);  +  D->init(TemplatedDecl, TemplateParams);  }  void PCHDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) { -  assert(false && "cannot read ClassTemplateDecl"); +  VisitTemplateDecl(D); + +  D->IdentifierNamespace = Record[Idx++]; +  ClassTemplateDecl *PrevDecl = +      cast_or_null<ClassTemplateDecl>(Reader.GetDecl(Record[Idx++])); +  D->setPreviousDeclaration(PrevDecl); +  if (PrevDecl == 0) { +    // This ClassTemplateDecl owns a CommonPtr; read it. + +    // FoldingSets are filled in VisitClassTemplateSpecializationDecl. +    unsigned size = Record[Idx++]; +    while (size--) +      cast<ClassTemplateSpecializationDecl>(Reader.GetDecl(Record[Idx++])); + +    size = Record[Idx++]; +    while (size--) +      cast<ClassTemplatePartialSpecializationDecl>( +                                                 Reader.GetDecl(Record[Idx++])); + +    // InjectedClassNameType is computed. + +    if (ClassTemplateDecl *CTD +          = cast_or_null<ClassTemplateDecl>(Reader.GetDecl(Record[Idx++]))) { +      D->setInstantiatedFromMemberTemplate(CTD); +      if (Record[Idx++]) +        D->setMemberSpecialization(); +    } +  }  }  void PCHDeclReader::VisitClassTemplateSpecializationDecl(                                             ClassTemplateSpecializationDecl *D) { -  assert(false && "cannot read ClassTemplateSpecializationDecl"); +  VisitCXXRecordDecl(D); + +  if (Decl *InstD = Reader.GetDecl(Record[Idx++])) { +    if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(InstD)) { +      D->setInstantiationOf(CTD); +    } else { +      llvm::SmallVector<TemplateArgument, 8> TemplArgs; +      Reader.ReadTemplateArgumentList(TemplArgs, Record, Idx); +      D->setInstantiationOf(cast<ClassTemplatePartialSpecializationDecl>(InstD), +                            TemplArgs.data(), TemplArgs.size()); +    } +  } + +  // Explicit info. +  if (TypeSourceInfo *TyInfo = Reader.GetTypeSourceInfo(Record, Idx)) { +    D->setTypeAsWritten(TyInfo); +    D->setExternLoc(Reader.ReadSourceLocation(Record, Idx)); +    D->setTemplateKeywordLoc(Reader.ReadSourceLocation(Record, Idx)); +  } + +  llvm::SmallVector<TemplateArgument, 8> TemplArgs; +  Reader.ReadTemplateArgumentList(TemplArgs, Record, Idx); +  D->initTemplateArgs(TemplArgs.data(), TemplArgs.size()); +  SourceLocation POI = Reader.ReadSourceLocation(Record, Idx); +  if (POI.isValid()) +    D->setPointOfInstantiation(POI); +  D->setSpecializationKind((TemplateSpecializationKind)Record[Idx++]); + +  if (Record[Idx++]) { // IsKeptInFoldingSet. +    ClassTemplateDecl *CanonPattern +                       = cast<ClassTemplateDecl>(Reader.GetDecl(Record[Idx++])); +    if (ClassTemplatePartialSpecializationDecl *Partial +            = dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) { +      CanonPattern->getPartialSpecializations().InsertNode(Partial); +    } else { +      CanonPattern->getSpecializations().InsertNode(D); +    } +  }  }  void PCHDeclReader::VisitClassTemplatePartialSpecializationDecl(                                      ClassTemplatePartialSpecializationDecl *D) { -  assert(false && "cannot read ClassTemplatePartialSpecializationDecl"); +  VisitClassTemplateSpecializationDecl(D); + +  D->initTemplateParameters(Reader.ReadTemplateParameterList(Record, Idx)); +   +  TemplateArgumentListInfo ArgInfos; +  unsigned NumArgs = Record[Idx++]; +  while (NumArgs--) +    ArgInfos.addArgument(Reader.ReadTemplateArgumentLoc(Record, Idx)); +  D->initTemplateArgsAsWritten(ArgInfos); +   +  D->setSequenceNumber(Record[Idx++]); + +  // These are read/set from/to the first declaration. +  if (D->getPreviousDeclaration() == 0) { +    D->setInstantiatedFromMember( +        cast_or_null<ClassTemplatePartialSpecializationDecl>( +                                                Reader.GetDecl(Record[Idx++]))); +    if (Record[Idx++]) +      D->setMemberSpecialization(); +  }  } -void PCHDeclReader::visitFunctionTemplateDecl(FunctionTemplateDecl *D) { -  assert(false && "cannot read FunctionTemplateDecl"); +void PCHDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { +  VisitTemplateDecl(D); + +  D->IdentifierNamespace = Record[Idx++]; +  FunctionTemplateDecl *PrevDecl = +      cast_or_null<FunctionTemplateDecl>(Reader.GetDecl(Record[Idx++])); +  D->setPreviousDeclaration(PrevDecl); +  if (PrevDecl == 0) { +    // This FunctionTemplateDecl owns a CommonPtr; read it. + +    // Read the function specialization declarations. +    // FunctionTemplateDecl's FunctionTemplateSpecializationInfos are filled +    // through the specialized FunctionDecl's setFunctionTemplateSpecialization. +    unsigned NumSpecs = Record[Idx++]; +    while (NumSpecs--) +      Reader.GetDecl(Record[Idx++]); + +    if (FunctionTemplateDecl *CTD +          = cast_or_null<FunctionTemplateDecl>(Reader.GetDecl(Record[Idx++]))) { +      D->setInstantiatedFromMemberTemplate(CTD); +      if (Record[Idx++]) +        D->setMemberSpecialization(); +    } +  }  }  void PCHDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { -  assert(false && "cannot read TemplateTypeParmDecl"); +  VisitTypeDecl(D); + +  D->setDeclaredWithTypename(Record[Idx++]); +  D->setParameterPack(Record[Idx++]); + +  bool Inherited = Record[Idx++]; +  TypeSourceInfo *DefArg = Reader.GetTypeSourceInfo(Record, Idx); +  D->setDefaultArgument(DefArg, Inherited);  }  void PCHDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { -  assert(false && "cannot read NonTypeTemplateParmDecl"); +  VisitVarDecl(D); +  // TemplateParmPosition. +  D->setDepth(Record[Idx++]); +  D->setPosition(Record[Idx++]); +  // Rest of NonTypeTemplateParmDecl. +  if (Record[Idx++]) { +    Expr *DefArg = Reader.ReadExpr(); +    bool Inherited = Record[Idx++]; +    D->setDefaultArgument(DefArg, Inherited); + }  }  void PCHDeclReader::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { -  assert(false && "cannot read TemplateTemplateParmDecl"); +  VisitTemplateDecl(D); +  // TemplateParmPosition. +  D->setDepth(Record[Idx++]); +  D->setPosition(Record[Idx++]); +  // Rest of TemplateTemplateParmDecl. +  TemplateArgumentLoc Arg = Reader.ReadTemplateArgumentLoc(Record, Idx); +  bool IsInherited = Record[Idx++]; +  D->setDefaultArgument(Arg, IsInherited);  }  void PCHDeclReader::VisitStaticAssertDecl(StaticAssertDecl *D) { @@ -641,24 +1049,24 @@ Attr *PCHReader::ReadAttributes() {    (void)RecCode;  #define SIMPLE_ATTR(Name)                       \ - case Attr::Name:                               \ + case attr::Name:                               \     New = ::new (*Context) Name##Attr();         \     break  #define STRING_ATTR(Name)                                       \ - case Attr::Name:                                               \ + case attr::Name:                                               \     New = ::new (*Context) Name##Attr(*Context, ReadString(Record, Idx));  \     break  #define UNSIGNED_ATTR(Name)                             \ - case Attr::Name:                                       \ + case attr::Name:                                       \     New = ::new (*Context) Name##Attr(Record[Idx++]);    \     break    Attr *Attrs = 0;    while (Idx < Record.size()) {      Attr *New = 0; -    Attr::Kind Kind = (Attr::Kind)Record[Idx++]; +    attr::Kind Kind = (attr::Kind)Record[Idx++];      bool IsInherited = Record[Idx++];      switch (Kind) { @@ -674,14 +1082,14 @@ Attr *PCHReader::ReadAttributes() {      STRING_ATTR(AsmLabel);      SIMPLE_ATTR(BaseCheck); -    case Attr::Blocks: +    case attr::Blocks:        New = ::new (*Context) BlocksAttr(                                    (BlocksAttr::BlocksAttrTypes)Record[Idx++]);        break;      SIMPLE_ATTR(CDecl); -    case Attr::Cleanup: +    case attr::Cleanup:        New = ::new (*Context) CleanupAttr(                                    cast<FunctionDecl>(GetDecl(Record[Idx++])));        break; @@ -695,7 +1103,7 @@ Attr *PCHReader::ReadAttributes() {      SIMPLE_ATTR(FastCall);      SIMPLE_ATTR(Final); -    case Attr::Format: { +    case attr::Format: {        std::string Type = ReadString(Record, Idx);        unsigned FormatIdx = Record[Idx++];        unsigned FirstArg = Record[Idx++]; @@ -703,13 +1111,13 @@ Attr *PCHReader::ReadAttributes() {        break;      } -    case Attr::FormatArg: { +    case attr::FormatArg: {        unsigned FormatIdx = Record[Idx++];        New = ::new (*Context) FormatArgAttr(FormatIdx);        break;      } -    case Attr::Sentinel: { +    case attr::Sentinel: {        int sentinel = Record[Idx++];        int nullPos = Record[Idx++];        New = ::new (*Context) SentinelAttr(sentinel, nullPos); @@ -719,15 +1127,15 @@ Attr *PCHReader::ReadAttributes() {      SIMPLE_ATTR(GNUInline);      SIMPLE_ATTR(Hiding); -    case Attr::IBActionKind: +    case attr::IBAction:        New = ::new (*Context) IBActionAttr();        break; -    case Attr::IBOutletKind: +    case attr::IBOutlet:        New = ::new (*Context) IBOutletAttr();        break; -    case Attr::IBOutletCollectionKind: { +    case attr::IBOutletCollection: {        ObjCInterfaceDecl *D =          cast_or_null<ObjCInterfaceDecl>(GetDecl(Record[Idx++]));        New = ::new (*Context) IBOutletCollectionAttr(D); @@ -740,7 +1148,7 @@ Attr *PCHReader::ReadAttributes() {      SIMPLE_ATTR(NoReturn);      SIMPLE_ATTR(NoThrow); -    case Attr::NonNull: { +    case attr::NonNull: {        unsigned Size = Record[Idx++];        llvm::SmallVector<unsigned, 16> ArgNums;        ArgNums.insert(ArgNums.end(), &Record[Idx], &Record[Idx] + Size); @@ -749,7 +1157,7 @@ Attr *PCHReader::ReadAttributes() {        break;      } -    case Attr::ReqdWorkGroupSize: { +    case attr::ReqdWorkGroupSize: {        unsigned X = Record[Idx++];        unsigned Y = Record[Idx++];        unsigned Z = Record[Idx++]; @@ -777,7 +1185,7 @@ Attr *PCHReader::ReadAttributes() {      SIMPLE_ATTR(Unused);      SIMPLE_ATTR(Used); -    case Attr::Visibility: +    case attr::Visibility:        New = ::new (*Context) VisibilityAttr(                                (VisibilityAttr::VisibilityTypes)Record[Idx++]);        break; @@ -848,6 +1256,8 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {    // after reading this declaration.    SavedStreamPosition SavedPosition(DeclsCursor); +  ReadingKindTracker ReadingKind(Read_Decl, *this); +    // Note that we are loading a declaration record.    LoadingTypeOrDecl Loading(*this); @@ -872,11 +1282,10 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {      D = TypedefDecl::Create(*Context, 0, SourceLocation(), 0, 0);      break;    case pch::DECL_ENUM: -    D = EnumDecl::Create(*Context, 0, SourceLocation(), 0, SourceLocation(), 0); +    D = EnumDecl::Create(*Context, Decl::EmptyShell());      break;    case pch::DECL_RECORD: -    D = RecordDecl::Create(*Context, TTK_Struct, 0, SourceLocation(), -                           0, SourceLocation(), 0); +    D = RecordDecl::Create(*Context, Decl::EmptyShell());      break;    case pch::DECL_ENUM_CONSTANT:      D = EnumConstantDecl::Create(*Context, 0, SourceLocation(), 0, QualType(), @@ -923,8 +1332,7 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {                                              DeclarationName());      break;    case pch::DECL_CXX_RECORD: -    D = CXXRecordDecl::Create(*Context, TTK_Struct, 0, -                              SourceLocation(), 0, SourceLocation(), 0); +    D = CXXRecordDecl::Create(*Context, Decl::EmptyShell());      break;    case pch::DECL_CXX_METHOD:      D = CXXMethodDecl::Create(*Context, 0, SourceLocation(), DeclarationName(), @@ -939,36 +1347,40 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {    case pch::DECL_CXX_CONVERSION:      D = CXXConversionDecl::Create(*Context, Decl::EmptyShell());      break; +  case pch::DECL_ACCESS_SPEC: +    D = AccessSpecDecl::Create(*Context, AS_none, 0, SourceLocation(), +                               SourceLocation()); +    break;    case pch::DECL_FRIEND: -    assert(false && "cannot read FriendDecl"); +    D = FriendDecl::Create(*Context, Decl::EmptyShell());      break;    case pch::DECL_FRIEND_TEMPLATE:      assert(false && "cannot read FriendTemplateDecl");      break; -  case pch::DECL_TEMPLATE: -    // FIXME: Should TemplateDecl be ABSTRACT_DECL??? -    assert(false && "TemplateDecl should be abstract!"); -    break;    case pch::DECL_CLASS_TEMPLATE: -    assert(false && "cannot read ClassTemplateDecl"); +    D = ClassTemplateDecl::Create(*Context, 0, SourceLocation(), +                                  DeclarationName(), 0, 0, 0);      break;    case pch::DECL_CLASS_TEMPLATE_SPECIALIZATION: -    assert(false && "cannot read ClasstemplateSpecializationDecl"); +    D = ClassTemplateSpecializationDecl::Create(*Context, Decl::EmptyShell());      break;    case pch::DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION: -    assert(false && "cannot read ClassTemplatePartialSpecializationDecl"); +    D = ClassTemplatePartialSpecializationDecl::Create(*Context, +                                                            Decl::EmptyShell());      break;    case pch::DECL_FUNCTION_TEMPLATE: -    assert(false && "cannot read FunctionTemplateDecl"); +    D = FunctionTemplateDecl::Create(*Context, 0, SourceLocation(), +                                     DeclarationName(), 0, 0);      break;    case pch::DECL_TEMPLATE_TYPE_PARM: -    assert(false && "cannot read TemplateTypeParmDecl"); +    D = TemplateTypeParmDecl::Create(*Context, Decl::EmptyShell());      break;    case pch::DECL_NON_TYPE_TEMPLATE_PARM: -    assert(false && "cannot read NonTypeTemplateParmDecl"); +    D = NonTypeTemplateParmDecl::Create(*Context, 0, SourceLocation(), 0,0,0, +                                        QualType(),0);      break;    case pch::DECL_TEMPLATE_TEMPLATE_PARM: -    assert(false && "cannot read TemplateTemplateParmDecl"); +    D = TemplateTemplateParmDecl::Create(*Context, 0, SourceLocation(),0,0,0,0);      break;    case pch::DECL_STATIC_ASSERT:      assert(false && "cannot read StaticAssertDecl"); @@ -1013,7 +1425,7 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {      break;    case pch::DECL_OBJC_PROPERTY:      D = ObjCPropertyDecl::Create(*Context, 0, SourceLocation(), 0, SourceLocation(), -                                 QualType()); +                                 0);      break;    case pch::DECL_OBJC_PROPERTY_IMPL:      D = ObjCPropertyImplDecl::Create(*Context, 0, SourceLocation(), @@ -1062,16 +1474,11 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {    assert(Idx == Record.size());    // If we have deserialized a declaration that has a definition the -  // AST consumer might need to know about, notify the consumer -  // about that definition now or queue it for later. -  if (isConsumerInterestedIn(D)) { -    if (Consumer) { -      DeclGroupRef DG(D); -      Consumer->HandleTopLevelDecl(DG); -    } else { -      InterestingDecls.push_back(D); -    } -  } +  // AST consumer might need to know about, queue it. +  // We don't pass it to the consumer immediately because we may be in recursive +  // loading, and some declarations may still be initializing. +  if (isConsumerInterestedIn(D)) +    InterestingDecls.push_back(D);    return D;  }  | 
