diff --git a/clang/include/clang/Basic/Module.h b/clang/include/clang/Basic/Module.h --- a/clang/include/clang/Basic/Module.h +++ b/clang/include/clang/Basic/Module.h @@ -20,9 +20,9 @@ #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator_range.h" @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -52,12 +53,33 @@ using ModuleId = SmallVector, 2>; /// The signature of a module, which is a hash of the AST content. -struct ASTFileSignature : std::array { - ASTFileSignature(std::array S = {{0}}) - : std::array(std::move(S)) {} +struct ASTFileSignature : std::array { + using BaseT = std::array; + + static constexpr size_t size = std::tuple_size::value; + + ASTFileSignature(BaseT S = {{0}}) : BaseT(std::move(S)) {} + + explicit operator bool() const { return *this != BaseT({{0}}); } + + static ASTFileSignature create(StringRef Bytes) { + return create(Bytes.bytes_begin(), Bytes.bytes_end()); + } + + static ASTFileSignature createDISentinel() { + ASTFileSignature Sentinel; + Sentinel.fill(0xFF); + return Sentinel; + } + + template + static ASTFileSignature create(InputIt First, InputIt Last) { + assert(std::distance(First, Last) == size && + "Wrong amount of bytes to create an ASTFileSignature"); - explicit operator bool() const { - return *this != std::array({{0}}); + ASTFileSignature Signature; + std::copy(First, Last, Signature.begin()); + return Signature; } }; diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -2535,10 +2535,14 @@ // PCH files don't have a signature field in the control block, // but LLVM detects skeleton CUs by looking for a non-zero DWO id. // We use the lower 64 bits for debug info. - uint64_t Signature = - Mod.getSignature() - ? (uint64_t)Mod.getSignature()[1] << 32 | Mod.getSignature()[0] - : ~1ULL; + + uint64_t Signature = 0; + if (const auto &ModSig = Mod.getSignature()) { + for (unsigned I = 0; I != sizeof(Signature); ++I) + Signature |= (uint64_t)ModSig[I] << (I * 8); + } else { + Signature = ~1ULL; + } llvm::DIBuilder DIB(CGM.getModule()); SmallString<0> PCM; if (!llvm::sys::path::is_absolute(Mod.getASTFile())) diff --git a/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp b/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp --- a/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp +++ b/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp @@ -173,8 +173,8 @@ // Prepare CGDebugInfo to emit debug info for a clang module. auto *DI = Builder->getModuleDebugInfo(); StringRef ModuleName = llvm::sys::path::filename(MainFileName); - DI->setPCHDescriptor({ModuleName, "", OutputFileName, - ASTFileSignature{{{~0U, ~0U, ~0U, ~0U, ~1U}}}}); + DI->setPCHDescriptor( + {ModuleName, "", OutputFileName, ASTFileSignature::createDISentinel()}); DI->setModuleMap(MMap); } diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -2791,10 +2791,10 @@ ReadUntranslatedSourceLocation(Record[Idx++]); off_t StoredSize = (off_t)Record[Idx++]; time_t StoredModTime = (time_t)Record[Idx++]; - ASTFileSignature StoredSignature = { - {{(uint32_t)Record[Idx++], (uint32_t)Record[Idx++], - (uint32_t)Record[Idx++], (uint32_t)Record[Idx++], - (uint32_t)Record[Idx++]}}}; + auto FirstSignatureByte = Record.begin() + Idx; + ASTFileSignature StoredSignature = ASTFileSignature::create( + FirstSignatureByte, FirstSignatureByte + ASTFileSignature::size); + Idx += ASTFileSignature::size; std::string ImportedName = ReadString(Record, Idx); std::string ImportedFile; @@ -4734,7 +4734,7 @@ switch ((UnhashedControlBlockRecordTypes)MaybeRecordType.get()) { case SIGNATURE: if (F) - std::copy(Record.begin(), Record.end(), F->Signature.data()); + F->Signature = ASTFileSignature::create(Record.begin(), Record.end()); break; case DIAGNOSTIC_OPTIONS: { bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0; @@ -5023,8 +5023,8 @@ return ASTFileSignature(); } if (SIGNATURE == MaybeRecord.get()) - return {{{(uint32_t)Record[0], (uint32_t)Record[1], (uint32_t)Record[2], - (uint32_t)Record[3], (uint32_t)Record[4]}}}; + return ASTFileSignature::create(Record.begin(), + Record.begin() + ASTFileSignature::size); } } @@ -5322,7 +5322,9 @@ unsigned Idx = 0, N = Record.size(); while (Idx < N) { // Read information about the AST file. - Idx += 1+1+1+1+5; // Kind, ImportLoc, Size, ModTime, Signature + Idx += + 1 + 1 + 1 + 1 + + ASTFileSignature::size; // Kind, ImportLoc, Size, ModTime, Signature std::string ModuleName = ReadString(Record, Idx); std::string Filename = ReadString(Record, Idx); ResolveImportedPath(Filename, ModuleDir); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -1032,16 +1032,7 @@ Hasher.update(ArrayRef(Bytes.bytes_begin(), Bytes.size())); auto Hash = Hasher.result(); - // Convert to an array [5*i32]. - ASTFileSignature Signature; - auto LShift = [&](unsigned char Val, unsigned Shift) { - return (uint32_t)Val << Shift; - }; - for (int I = 0; I != 5; ++I) - Signature[I] = LShift(Hash[I * 4 + 0], 24) | LShift(Hash[I * 4 + 1], 16) | - LShift(Hash[I * 4 + 2], 8) | LShift(Hash[I * 4 + 3], 0); - - return Signature; + return ASTFileSignature::create(Hash); } ASTFileSignature ASTWriter::writeUnhashedControlBlock(Preprocessor &PP, diff --git a/clang/lib/Serialization/GlobalModuleIndex.cpp b/clang/lib/Serialization/GlobalModuleIndex.cpp --- a/clang/lib/Serialization/GlobalModuleIndex.cpp +++ b/clang/lib/Serialization/GlobalModuleIndex.cpp @@ -643,10 +643,10 @@ // Skip the stored signature. // FIXME: we could read the signature out of the import and validate it. - ASTFileSignature StoredSignature = { - {{(uint32_t)Record[Idx++], (uint32_t)Record[Idx++], - (uint32_t)Record[Idx++], (uint32_t)Record[Idx++], - (uint32_t)Record[Idx++]}}}; + auto FirstSignatureByte = Record.begin() + Idx; + ASTFileSignature StoredSignature = ASTFileSignature::create( + FirstSignatureByte, FirstSignatureByte + ASTFileSignature::size); + Idx += ASTFileSignature::size; // Skip the module name (currently this is only used for prebuilt // modules while here we are only dealing with cached). @@ -704,9 +704,8 @@ // Get Signature. if (State == DiagnosticOptionsBlock && Code == SIGNATURE) - getModuleFileInfo(File).Signature = { - {{(uint32_t)Record[0], (uint32_t)Record[1], (uint32_t)Record[2], - (uint32_t)Record[3], (uint32_t)Record[4]}}}; + getModuleFileInfo(File).Signature = ASTFileSignature::create( + Record.begin(), Record.begin() + ASTFileSignature::size); // We don't care about this record. }