diff options
Diffstat (limited to 'lib/Serialization')
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 97 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 31 | ||||
-rw-r--r-- | lib/Serialization/Module.cpp | 8 |
3 files changed, 120 insertions, 16 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 48912e362e..d43f8c1f45 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -2062,6 +2062,8 @@ ASTReader::ReadASTBlock(ModuleFile &F) { ContinuousRangeMap<uint32_t, int, 2>::Builder PreprocessedEntityRemap(F.PreprocessedEntityRemap); ContinuousRangeMap<uint32_t, int, 2>::Builder + SubmoduleRemap(F.SubmoduleRemap); + ContinuousRangeMap<uint32_t, int, 2>::Builder SelectorRemap(F.SelectorRemap); ContinuousRangeMap<uint32_t, int, 2>::Builder DeclRemap(F.DeclRemap); ContinuousRangeMap<uint32_t, int, 2>::Builder TypeRemap(F.TypeRemap); @@ -2079,6 +2081,7 @@ ASTReader::ReadASTBlock(ModuleFile &F) { uint32_t SLocOffset = io::ReadUnalignedLE32(Data); uint32_t IdentifierIDOffset = io::ReadUnalignedLE32(Data); uint32_t PreprocessedEntityIDOffset = io::ReadUnalignedLE32(Data); + uint32_t SubmoduleIDOffset = io::ReadUnalignedLE32(Data); uint32_t SelectorIDOffset = io::ReadUnalignedLE32(Data); uint32_t DeclIDOffset = io::ReadUnalignedLE32(Data); uint32_t TypeIndexOffset = io::ReadUnalignedLE32(Data); @@ -2092,6 +2095,8 @@ ASTReader::ReadASTBlock(ModuleFile &F) { PreprocessedEntityRemap.insert( std::make_pair(PreprocessedEntityIDOffset, OM->BasePreprocessedEntityID - PreprocessedEntityIDOffset)); + SubmoduleRemap.insert(std::make_pair(SubmoduleIDOffset, + OM->BaseSubmoduleID - SubmoduleIDOffset)); SelectorRemap.insert(std::make_pair(SelectorIDOffset, OM->BaseSelectorID - SelectorIDOffset)); DeclRemap.insert(std::make_pair(DeclIDOffset, @@ -2828,8 +2833,10 @@ ASTReader::ASTReadResult ASTReader::ReadSubmoduleBlock(ModuleFile &F) { } ModuleMap &ModMap = PP.getHeaderSearchInfo().getModuleMap(); + bool First = true; Module *CurrentModule = 0; RecordData Record; + SubmoduleID CurrentModuleGlobalIndex = 0; while (true) { unsigned Code = F.Stream.ReadCode(); if (Code == llvm::bitc::END_BLOCK) { @@ -2864,31 +2871,41 @@ ASTReader::ASTReadResult ASTReader::ReadSubmoduleBlock(ModuleFile &F) { break; case SUBMODULE_DEFINITION: { + if (First) { + Error("missing submodule metadata record at beginning of block"); + return Failure; + } + StringRef Name(BlobStart, BlobLen); - unsigned Parent = Record[0]; + unsigned Parent = getGlobalSubmoduleID(F, Record[0]); bool IsFramework = Record[1]; bool IsExplicit = Record[2]; Module *ParentModule = 0; - if (Parent) { - if (Parent > F.Submodules.size()) { - Error("malformed submodule parent entry"); - return Failure; - } - - ParentModule = F.Submodules[Parent - 1]; - } + if (Parent) + ParentModule = getSubmodule(Parent); // Retrieve this (sub)module from the module map, creating it if // necessary. CurrentModule = ModMap.findOrCreateModule(Name, ParentModule, IsFramework, IsExplicit).first; - F.Submodules.push_back(CurrentModule); + + if (CurrentModuleGlobalIndex >= SubmodulesLoaded.size() || + SubmodulesLoaded[CurrentModuleGlobalIndex]) { + Error("too many submodules"); + return Failure; + } + SubmodulesLoaded[CurrentModuleGlobalIndex++] = CurrentModule; break; } case SUBMODULE_UMBRELLA: { + if (First) { + Error("missing submodule metadata record at beginning of block"); + return Failure; + } + if (!CurrentModule) break; @@ -2905,6 +2922,11 @@ ASTReader::ASTReadResult ASTReader::ReadSubmoduleBlock(ModuleFile &F) { } case SUBMODULE_HEADER: { + if (First) { + Error("missing submodule metadata record at beginning of block"); + return Failure; + } + if (!CurrentModule) break; @@ -2918,6 +2940,33 @@ ASTReader::ASTReadResult ASTReader::ReadSubmoduleBlock(ModuleFile &F) { } break; } + + case SUBMODULE_METADATA: { + if (!First) { + Error("submodule metadata record not at beginning of block"); + return Failure; + } + First = false; + + F.BaseSubmoduleID = getTotalNumSubmodules(); + CurrentModuleGlobalIndex = F.BaseSubmoduleID; + F.LocalNumSubmodules = Record[0]; + unsigned LocalBaseSubmoduleID = Record[1]; + if (F.LocalNumSubmodules > 0) { + // Introduce the global -> local mapping for submodules within this + // module. + GlobalSubmoduleMap.insert(std::make_pair(getTotalNumSubmodules()+1,&F)); + + // Introduce the local -> global mapping for submodules within this + // module. + F.SubmoduleRemap.insert( + std::make_pair(LocalBaseSubmoduleID, + F.BaseSubmoduleID - LocalBaseSubmoduleID)); + + SubmodulesLoaded.resize(SubmodulesLoaded.size() + F.LocalNumSubmodules); + } + break; + } } } @@ -4652,6 +4701,7 @@ void ASTReader::dump() { dumpModuleIDMap("Global type map", GlobalTypeMap); dumpModuleIDMap("Global declaration map", GlobalDeclMap); dumpModuleIDMap("Global identifier map", GlobalIdentifierMap); + dumpModuleIDMap("Global submodule map", GlobalSubmoduleMap); dumpModuleIDMap("Global selector map", GlobalSelectorMap); dumpModuleIDMap("Global preprocessed entity map", GlobalPreprocessedEntityMap); @@ -5120,6 +5170,33 @@ bool ASTReader::ReadSLocEntry(int ID) { return ReadSLocEntryRecord(ID) != Success; } +serialization::SubmoduleID +ASTReader::getGlobalSubmoduleID(ModuleFile &M, unsigned LocalID) { + if (LocalID < NUM_PREDEF_SUBMODULE_IDS) + return LocalID; + + ContinuousRangeMap<uint32_t, int, 2>::iterator I + = M.SubmoduleRemap.find(LocalID - NUM_PREDEF_SUBMODULE_IDS); + assert(I != M.SubmoduleRemap.end() + && "Invalid index into identifier index remap"); + + return LocalID + I->second; +} + +Module *ASTReader::getSubmodule(SubmoduleID GlobalID) { + if (GlobalID < NUM_PREDEF_SUBMODULE_IDS) { + assert(GlobalID == 0 && "Unhandled global submodule ID"); + return 0; + } + + if (GlobalID > SubmodulesLoaded.size()) { + Error("submodule ID out of range in AST file"); + return 0; + } + + return SubmodulesLoaded[GlobalID - NUM_PREDEF_SUBMODULE_IDS]; +} + Selector ASTReader::getLocalSelector(ModuleFile &M, unsigned LocalID) { return DecodeSelector(getGlobalSelectorID(M, LocalID)); } diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 0acc760ee2..28668904d5 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -1845,6 +1845,18 @@ void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) { } } +/// \brief Compute the number of modules within the given tree (including the +/// given module). +static unsigned getNumberOfModules(Module *Mod) { + unsigned ChildModules = 0; + for (llvm::StringMap<Module *>::iterator Sub = Mod->SubModules.begin(), + SubEnd = Mod->SubModules.end(); + Sub != SubEnd; ++Sub) + ChildModules += getNumberOfModules(Sub->getValue()); + + return ChildModules + 1; +} + void ASTWriter::WriteSubmodules(Module *WritingModule) { // Enter the submodule description block. Stream.EnterSubblock(SUBMODULE_BLOCK_ID, NUM_ALLOWED_ABBREVS_SIZE); @@ -1868,16 +1880,20 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) { Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_HEADER)); Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name unsigned HeaderAbbrev = Stream.EmitAbbrev(Abbrev); - + + // Write the submodule metadata block. + RecordData Record; + Record.push_back(getNumberOfModules(WritingModule)); + Record.push_back(FirstSubmoduleID - NUM_PREDEF_SUBMODULE_IDS); + Stream.EmitRecord(SUBMODULE_METADATA, Record); + // Write all of the submodules. - unsigned SubmoduleID = 1; std::queue<Module *> Q; Q.push(WritingModule); - RecordData Record; while (!Q.empty()) { Module *Mod = Q.front(); Q.pop(); - SubmoduleIDs[Mod] = SubmoduleID++; + SubmoduleIDs[Mod] = NextSubmoduleID++; // Emit the definition of the block. Record.clear(); @@ -2850,6 +2866,8 @@ ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream) FirstDeclID(NUM_PREDEF_DECL_IDS), NextDeclID(FirstDeclID), FirstTypeID(NUM_PREDEF_TYPE_IDS), NextTypeID(FirstTypeID), FirstIdentID(NUM_PREDEF_IDENT_IDS), NextIdentID(FirstIdentID), + FirstSubmoduleID(NUM_PREDEF_SUBMODULE_IDS), + NextSubmoduleID(FirstSubmoduleID), FirstSelectorID(NUM_PREDEF_SELECTOR_IDS), NextSelectorID(FirstSelectorID), CollectedStmts(&StmtsToEmit), NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0), @@ -3137,6 +3155,7 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, // identifier-id:i32 // preprocessed-entity-id:i32 // macro-definition-id:i32 + // submodule-id:i32 // selector-id:i32 // declaration-id:i32 // c++-base-specifiers-id:i32 @@ -3158,6 +3177,7 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, io::Emit32(Out, (*M)->SLocEntryBaseOffset); io::Emit32(Out, (*M)->BaseIdentifierID); io::Emit32(Out, (*M)->BasePreprocessedEntityID); + io::Emit32(Out, (*M)->BaseSubmoduleID); io::Emit32(Out, (*M)->BaseSelectorID); io::Emit32(Out, (*M)->BaseDeclID); io::Emit32(Out, (*M)->BaseTypeIndex); @@ -4055,6 +4075,7 @@ void ASTWriter::ReaderInitialized(ASTReader *Reader) { assert(FirstDeclID == NextDeclID && FirstTypeID == NextTypeID && FirstIdentID == NextIdentID && + FirstSubmoduleID == NextSubmoduleID && FirstSelectorID == NextSelectorID && "Setting chain after writing has started."); @@ -4063,11 +4084,13 @@ void ASTWriter::ReaderInitialized(ASTReader *Reader) { FirstDeclID = NUM_PREDEF_DECL_IDS + Chain->getTotalNumDecls(); FirstTypeID = NUM_PREDEF_TYPE_IDS + Chain->getTotalNumTypes(); FirstIdentID = NUM_PREDEF_IDENT_IDS + Chain->getTotalNumIdentifiers(); + FirstSubmoduleID = NUM_PREDEF_SUBMODULE_IDS + Chain->getTotalNumSubmodules(); FirstSelectorID = NUM_PREDEF_SELECTOR_IDS + Chain->getTotalNumSelectors(); NextDeclID = FirstDeclID; NextTypeID = FirstTypeID; NextIdentID = FirstIdentID; NextSelectorID = FirstSelectorID; + NextSubmoduleID = FirstSubmoduleID; } void ASTWriter::IdentifierRead(IdentID ID, IdentifierInfo *II) { diff --git a/lib/Serialization/Module.cpp b/lib/Serialization/Module.cpp index 241b6ba88c..11e7243cd5 100644 --- a/lib/Serialization/Module.cpp +++ b/lib/Serialization/Module.cpp @@ -30,7 +30,7 @@ ModuleFile::ModuleFile(ModuleKind Kind) PreprocessedEntityOffsets(0), NumPreprocessedEntities(0), LocalNumHeaderFileInfos(0), HeaderFileInfoTableData(0), HeaderFileInfoTable(0), - HeaderFileFrameworkStrings(0), + HeaderFileFrameworkStrings(0), LocalNumSubmodules(0), LocalNumSelectors(0), SelectorOffsets(0), BaseSelectorID(0), SelectorLookupTableData(0), SelectorLookupTable(0), LocalNumDecls(0), DeclOffsets(0), BaseDeclID(0), @@ -88,7 +88,11 @@ void ModuleFile::dump() { llvm::errs() << " Base identifier ID: " << BaseIdentifierID << '\n' << " Number of identifiers: " << LocalNumIdentifiers << '\n'; dumpLocalRemap("Identifier ID local -> global map", IdentifierRemap); - + + llvm::errs() << " Base submodule ID: " << BaseSubmoduleID << '\n' + << " Number of submodules: " << LocalNumSubmodules << '\n'; + dumpLocalRemap("Submodule ID local -> global map", SubmoduleRemap); + llvm::errs() << " Base selector ID: " << BaseSelectorID << '\n' << " Number of selectors: " << LocalNumSelectors << '\n'; dumpLocalRemap("Selector ID local -> global map", SelectorRemap); |