dang created this revision. dang added a reviewer: Bigcheese. Herald added subscribers: cfe-commits, dexonsmith. Herald added a project: clang.
This lets users of PCM get a clean hash of the AST for uniquing based on that. This required looking up implicit modules in the module offset map to be looked up by name instead of by file path. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D79998 Files: clang/include/clang/Serialization/ASTBitCodes.h clang/include/clang/Serialization/ASTWriter.h clang/include/clang/Serialization/ModuleFile.h clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp
Index: clang/lib/Serialization/ASTWriter.cpp =================================================================== --- clang/lib/Serialization/ASTWriter.cpp +++ clang/lib/Serialization/ASTWriter.cpp @@ -64,6 +64,7 @@ #include "clang/Sema/ObjCMethodList.h" #include "clang/Sema/Sema.h" #include "clang/Sema/Weak.h" +#include "clang/Serialization/ASTBitCodes.h" #include "clang/Serialization/ASTReader.h" #include "clang/Serialization/ASTRecordWriter.h" #include "clang/Serialization/InMemoryModuleCache.h" @@ -961,6 +962,7 @@ BLOCK(UNHASHED_CONTROL_BLOCK); RECORD(SIGNATURE); + RECORD(AST_SIGNATURE); RECORD(DIAGNOSTIC_OPTIONS); RECORD(DIAG_PRAGMA_MAPPINGS); @@ -1045,7 +1047,8 @@ } ASTFileSignature ASTWriter::writeUnhashedControlBlock(Preprocessor &PP, - ASTContext &Context) { + ASTContext &Context, + StringRef ASTBlockBytes) { // Flush first to prepare the PCM hash (signature). Stream.FlushToWord(); auto StartOfUnhashedControl = Stream.GetCurrentBitNo() >> 3; @@ -1062,6 +1065,10 @@ Record.append(Signature.begin(), Signature.end()); Stream.EmitRecord(SIGNATURE, Record); Record.clear(); + ASTFileSignature ASTSignature = createSignature(ASTBlockBytes); + Record.append(ASTSignature.begin(), ASTSignature.end()); + Stream.EmitRecord(AST_SIGNATURE, Record); + Record.clear(); } // Diagnostic options. @@ -4548,6 +4555,8 @@ populateInputFileIDs(Context.SourceMgr); // Write the remaining AST contents. + Stream.FlushToWord(); + auto StartOfASTBlock = Stream.GetCurrentBitNo() >> 3; Stream.EnterSubblock(AST_BLOCK_ID, 5); // This is so that older clang versions, before the introduction @@ -4679,9 +4688,9 @@ // c++-base-specifiers-id:i32 // type-id:i32) // - // module-kind is the ModuleKind enum value. If it is MK_PrebuiltModule or - // MK_ExplicitModule, then the module-name is the module name. Otherwise, - // it is the module file name. + // module-kind is the ModuleKind enum value. If it is MK_PrebuiltModule, + // MK_ExplicitModule or MK_ImplicitModule, then the module-name is the + // module name. Otherwise, it is the module file name. auto Abbrev = std::make_shared<BitCodeAbbrev>(); Abbrev->Add(BitCodeAbbrevOp(MODULE_OFFSET_MAP)); Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); @@ -4694,10 +4703,11 @@ endian::Writer LE(Out, little); LE.write<uint8_t>(static_cast<uint8_t>(M.Kind)); - StringRef Name = - M.Kind == MK_PrebuiltModule || M.Kind == MK_ExplicitModule - ? M.ModuleName - : M.FileName; + StringRef Name = M.Kind == MK_PrebuiltModule || + M.Kind == MK_ExplicitModule || + M.Kind == MK_ImplicitModule + ? M.ModuleName + : M.FileName; LE.write<uint16_t>(Name.size()); Out.write(Name.data(), Name.size()); @@ -4909,6 +4919,11 @@ NumStatements, NumMacros, NumLexicalDeclContexts, NumVisibleDeclContexts}; Stream.EmitRecord(STATISTICS, Record); Stream.ExitBlock(); + Stream.FlushToWord(); + auto EndOfASTBlock = Stream.GetCurrentBitNo() >> 3; + + StringRef ASTBlockBytes(Buffer.begin() + StartOfASTBlock, + EndOfASTBlock - StartOfASTBlock); // Write the control block WriteControlBlock(PP, Context, isysroot, OutputFile); @@ -4917,7 +4932,7 @@ for (const auto &ExtWriter : ModuleFileExtensionWriters) WriteModuleFileExtension(SemaRef, *ExtWriter); - return writeUnhashedControlBlock(PP, Context); + return writeUnhashedControlBlock(PP, Context, ASTBlockBytes); } void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) { Index: clang/lib/Serialization/ASTReader.cpp =================================================================== --- clang/lib/Serialization/ASTReader.cpp +++ clang/lib/Serialization/ASTReader.cpp @@ -3832,17 +3832,18 @@ while (Data < DataEnd) { // FIXME: Looking up dependency modules by filename is horrible. Let's - // start fixing this with prebuilt and explicit modules and see how it - // goes... + // start fixing this with prebuilt, explicit and implicit modules and see + // how it goes... using namespace llvm::support; ModuleKind Kind = static_cast<ModuleKind>( endian::readNext<uint8_t, little, unaligned>(Data)); uint16_t Len = endian::readNext<uint16_t, little, unaligned>(Data); StringRef Name = StringRef((const char*)Data, Len); Data += Len; - ModuleFile *OM = (Kind == MK_PrebuiltModule || Kind == MK_ExplicitModule - ? ModuleMgr.lookupByModuleName(Name) - : ModuleMgr.lookupByFileName(Name)); + ModuleFile *OM = (Kind == MK_PrebuiltModule || Kind == MK_ExplicitModule || + Kind == MK_ImplicitModule + ? ModuleMgr.lookupByModuleName(Name) + : ModuleMgr.lookupByFileName(Name)); if (!OM) { std::string Msg = "SourceLocation remap refers to unknown module, cannot find "; @@ -4734,6 +4735,10 @@ if (F) std::copy(Record.begin(), Record.end(), F->Signature.data()); break; + case AST_SIGNATURE: + if (F) + std::copy(Record.begin(), Record.end(), F->ASTSignature.data()); + break; case DIAGNOSTIC_OPTIONS: { bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0; if (Listener && ValidateDiagnosticOptions && Index: clang/include/clang/Serialization/ModuleFile.h =================================================================== --- clang/include/clang/Serialization/ModuleFile.h +++ clang/include/clang/Serialization/ModuleFile.h @@ -168,6 +168,10 @@ /// and modification time to identify this particular file. ASTFileSignature Signature; + /// The signature of the AST block of the module file, this can be used to + /// unique module files based on AST contents. + ASTFileSignature ASTSignature; + /// Whether this module has been directly imported by the /// user. bool DirectlyImported = false; Index: clang/include/clang/Serialization/ASTWriter.h =================================================================== --- clang/include/clang/Serialization/ASTWriter.h +++ clang/include/clang/Serialization/ASTWriter.h @@ -472,7 +472,8 @@ /// Write out the signature and diagnostic options, and return the signature. ASTFileSignature writeUnhashedControlBlock(Preprocessor &PP, - ASTContext &Context); + ASTContext &Context, + StringRef ASTBlockBytes); /// Calculate hash of the pcm content. static ASTFileSignature createSignature(StringRef Bytes); Index: clang/include/clang/Serialization/ASTBitCodes.h =================================================================== --- clang/include/clang/Serialization/ASTBitCodes.h +++ clang/include/clang/Serialization/ASTBitCodes.h @@ -394,6 +394,9 @@ /// Record code for the signature that identifiers this AST file. SIGNATURE = 1, + /// Record code for the signature of the AST block. + AST_SIGNATURE, + /// Record code for the diagnostic options table. DIAGNOSTIC_OPTIONS,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits