Modules: Use hash of PCM content for SIGNATURE
Change ASTFileSignature from a random 32-bit number to the hash of the
PCM content.
- Move definition ASTFileSignature to Basic/Module.h so Module and
ASTSourceDescriptor can use it.
- Change the signature from uint64_t to std::array<uint32_t,5>.
- Stop using (saving/reading) the size and modification time of PCM
files when there is a valid SIGNATURE.
- Add UNHASHED_CONTROL_BLOCK, and use it to store the SIGNATURE record
and other records that shouldn't affect the hash. Because implicit
modules reuses the same file for multiple levels of -Werror, this
includes DIAGNOSTIC_OPTIONS and DIAG_PRAGMA_MAPPINGS.
This helps to solve a PCH + implicit Modules dependency issue: PCH files
are handled by the external build system, whereas implicit modules are
handled by internal compiler build system. This prevents invalidating a
PCH when the compiler overwrites a PCM file with the same content
(modulo the diagnostic differences).
Design and original patch by Manman Ren!
llvm-svn: 297655
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp
index db19804..ac5c7ca 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/lib/Frontend/ASTUnit.cpp
@@ -185,7 +185,7 @@
llvm::BitstreamWriter Stream;
ASTWriter Writer;
- ASTWriterData() : Stream(Buffer), Writer(Stream, { }) { }
+ ASTWriterData() : Stream(Buffer), Writer(Stream, Buffer, {}) {}
};
void ASTUnit::clearFileLevelDecls() {
@@ -2523,7 +2523,7 @@
SmallString<128> Buffer;
llvm::BitstreamWriter Stream(Buffer);
- ASTWriter Writer(Stream, { });
+ ASTWriter Writer(Stream, Buffer, {});
return serializeUnit(Writer, Buffer, getSema(), hasErrors, OS);
}
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index 39fe777..a0e81f0 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -1029,7 +1029,7 @@
// Remove any macro definitions that are explicitly ignored by the module.
// They aren't supposed to affect how the module is built anyway.
- const HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts();
+ HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts();
PPOpts.Macros.erase(
std::remove_if(PPOpts.Macros.begin(), PPOpts.Macros.end(),
[&HSOpts](const std::pair<std::string, bool> &def) {
@@ -1060,6 +1060,8 @@
FrontendOpts.DisableFree = false;
FrontendOpts.GenerateGlobalModuleIndex = false;
FrontendOpts.BuildingImplicitModule = true;
+ // Force implicitly-built modules to hash the content of the module file.
+ HSOpts.ModulesHashContent = true;
FrontendOpts.Inputs.clear();
InputKind IK = getSourceInputKindFromOptions(*Invocation->getLangOpts());
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 2352974..d5ad3df 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1434,6 +1434,7 @@
for (const Arg *A : Args.filtered(OPT_fprebuilt_module_path))
Opts.AddPrebuiltModulePath(A->getValue());
Opts.DisableModuleHash = Args.hasArg(OPT_fdisable_module_hash);
+ Opts.ModulesHashContent = Args.hasArg(OPT_fmodules_hash_content);
Opts.ModulesValidateDiagnosticOptions =
!Args.hasArg(OPT_fmodules_disable_diagnostic_validation);
Opts.ImplicitModuleMaps = Args.hasArg(OPT_fimplicit_module_maps);