From 69021974073fddaf7ec7345819e46f16e5dcdcde Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Wed, 30 Nov 2011 17:33:56 +0000 Subject: Implement (de-)serialization of the description of a module and its submodules. This information will eventually be used for name hiding when dealing with submodules. For now, we only use it to ensure that the module "key" returned when loading a module will always be a module (rather than occasionally being a FileEntry). llvm-svn: 145497 --- clang/lib/Serialization/ASTWriter.cpp | 85 ++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-) (limited to 'clang/lib/Serialization/ASTWriter.cpp') diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index e225103f72a..cf4ea41dd59 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -1845,6 +1845,88 @@ void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) { } } +void ASTWriter::WriteSubmodules(ModuleMap::Module *WritingModule) { + // Enter the submodule description block. + Stream.EnterSubblock(SUBMODULE_BLOCK_ID, NUM_ALLOWED_ABBREVS_SIZE); + + // Write the abbreviations needed for the submodules block. + using namespace llvm; + BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); + Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_DEFINITION)); + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Parent + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFramework + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsExplicit + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name + unsigned DefinitionAbbrev = Stream.EmitAbbrev(Abbrev); + + Abbrev = new BitCodeAbbrev(); + Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_UMBRELLA)); + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name + unsigned UmbrellaAbbrev = Stream.EmitAbbrev(Abbrev); + + Abbrev = new BitCodeAbbrev(); + Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_HEADER)); + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name + unsigned HeaderAbbrev = Stream.EmitAbbrev(Abbrev); + + // Write all of the submodules. + unsigned SubmoduleID = 1; + std::queue Q; + Q.push(WritingModule); + RecordData Record; + while (!Q.empty()) { + ModuleMap::Module *Mod = Q.front(); + Q.pop(); + SubmoduleIDs[Mod] = SubmoduleID++; + + // Emit the definition of the block. + Record.clear(); + Record.push_back(SUBMODULE_DEFINITION); + if (Mod->Parent) { + assert(SubmoduleIDs[Mod->Parent] && "Submodule parent not written?"); + Record.push_back(SubmoduleIDs[Mod->Parent]); + } else { + Record.push_back(0); + } + Record.push_back(Mod->IsFramework); + Record.push_back(Mod->IsExplicit); + Stream.EmitRecordWithBlob(DefinitionAbbrev, Record, Mod->Name); + + // Emit the umbrella header, if there is one. + if (Mod->UmbrellaHeader) { + Record.clear(); + Record.push_back(SUBMODULE_UMBRELLA); + Stream.EmitRecordWithBlob(UmbrellaAbbrev, Record, + Mod->UmbrellaHeader->getName()); + } + + // Emit the headers. + for (unsigned I = 0, N = Mod->Headers.size(); I != N; ++I) { + Record.clear(); + Record.push_back(SUBMODULE_HEADER); + Stream.EmitRecordWithBlob(HeaderAbbrev, Record, + Mod->Headers[I]->getName()); + } + + // Queue up the submodules of this module. + llvm::SmallVector SubModules; + + // Sort the submodules first, so we get a predictable ordering in the AST + // file. + for (llvm::StringMap::iterator + Sub = Mod->SubModules.begin(), + SubEnd = Mod->SubModules.end(); + Sub != SubEnd; ++Sub) + SubModules.push_back(Sub->getKey()); + llvm::array_pod_sort(SubModules.begin(), SubModules.end()); + + for (unsigned I = 0, N = SubModules.size(); I != N; ++I) + Q.push(Mod->SubModules[SubModules[I]]); + } + + Stream.ExitBlock(); +} + void ASTWriter::WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag) { RecordData Record; for (DiagnosticsEngine::DiagStatePointsTy::const_iterator @@ -3086,7 +3168,8 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, Stream.EmitRecordWithBlob(ModuleOffsetMapAbbrev, Record, Buffer.data(), Buffer.size()); } - + if (WritingModule) + WriteSubmodules(WritingModule); WritePreprocessor(PP, WritingModule != 0); WriteHeaderSearch(PP.getHeaderSearchInfo(), isysroot); WriteSelectors(SemaRef); -- cgit v1.2.3