diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 761de497c730..70a323a5c374 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -56,8 +56,9 @@ namespace clang { /// \brief An ID number that refers to a declaration in an AST file. /// /// The ID numbers of declarations are consecutive (in order of - /// discovery) and start at 2. 0 is reserved for NULL, and 1 is - /// reserved for the translation unit declaration. + /// discovery), with values below NUM_PREDEF_DECL_IDS being reserved. + /// At the start of a chain of precompiled headers, declaration ID 1 is + /// used for the translation unit declaration. typedef uint32_t DeclID; /// \brief a Decl::Kind/DeclID pair. @@ -661,6 +662,23 @@ namespace clang { SPECIAL_TYPE_AUTO_RREF_DEDUCT = 18 }; + /// \brief Predefined declaration IDs. + /// + /// These declaration IDs correspond to predefined declarations in the AST + /// context, such as the NULL declaration ID. Such declarations are never + /// actually serialized, since they will be built by the AST context when + /// it is created. + enum PredefinedDeclIDs { + /// \brief The NULL declaration. + PREDEF_DECL_NULL_ID = 0, + }; + + /// \brief The number of declaration IDs that are predefined. + /// + /// For more information about predefined declarations, see the + /// \c PredefinedDeclIDs type and the PREDEF_DECL_*_ID constants. + const unsigned int NUM_PREDEF_DECL_IDS = 1; + /// \brief Record codes for each kind of declaration. /// /// These constants describe the declaration records that can occur within diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 95bc60260c52..14094febe50f 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -4119,26 +4119,32 @@ TranslationUnitDecl *ASTReader::GetTranslationUnitDecl() { serialization::DeclID ASTReader::getGlobalDeclID(Module &F, unsigned LocalID) const { - if (LocalID == 0) + if (LocalID < NUM_PREDEF_DECL_IDS) return LocalID; ContinuousRangeMap::iterator I - = F.DeclRemap.find(LocalID - 1); + = F.DeclRemap.find(LocalID - NUM_PREDEF_DECL_IDS); assert(I != F.DeclRemap.end() && "Invalid index into decl index remap"); return LocalID + I->second; } Decl *ASTReader::GetDecl(DeclID ID) { - if (ID == 0) + if (ID < NUM_PREDEF_DECL_IDS) { + switch ((PredefinedDeclIDs)ID) { + case serialization::PREDEF_DECL_NULL_ID: + return 0; + } + return 0; - + } + if (ID > DeclsLoaded.size()) { Error("declaration ID out-of-range for AST file"); return 0; } - unsigned Index = ID - 1; + unsigned Index = ID - NUM_PREDEF_DECL_IDS; if (!DeclsLoaded[Index]) { ReadDeclRecord(ID); if (DeserializationListener) diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index c3bbecdb0e7f..fe152b119468 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -2039,7 +2039,7 @@ void ASTWriter::WriteTypeDeclOffsets() { Record.clear(); Record.push_back(DECL_OFFSET); Record.push_back(DeclOffsets.size()); - Record.push_back(FirstDeclID - 1); + Record.push_back(FirstDeclID - NUM_PREDEF_DECL_IDS); Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, data(DeclOffsets)); } @@ -2740,7 +2740,7 @@ void ASTWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) { ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream) : Stream(Stream), Chain(0), SerializationListener(0), - FirstDeclID(1), NextDeclID(FirstDeclID), + FirstDeclID(NUM_PREDEF_DECL_IDS), NextDeclID(FirstDeclID), FirstTypeID(NUM_PREDEF_TYPE_IDS), NextTypeID(FirstTypeID), FirstIdentID(1), NextIdentID(FirstIdentID), FirstSelectorID(1), NextSelectorID(FirstSelectorID), FirstMacroID(1), NextMacroID(FirstMacroID),