[ASTWriter] Provide capability to output a PCM/PCH file that does not write out information about its output path

This is useful to enable sharing of the same PCH file even when it's intended for a different output path.

The only information this option disables writing is for `ORIGINAL_PCH_DIR` record which is treated as optional and (when present) used as fallback for resolving input file paths relative to it.

Differential Revision: https://reviews.llvm.org/D130710
This commit is contained in:
Argyrios Kyrtzidis 2022-07-28 00:48:56 -07:00
parent 65c9265f41
commit 944a86de7c
7 changed files with 39 additions and 11 deletions

View File

@ -6025,6 +6025,9 @@ def fno_validate_pch : Flag<["-"], "fno-validate-pch">,
HelpText<"Disable validation of precompiled headers">,
MarshallingInfoFlag<PreprocessorOpts<"DisablePCHOrModuleValidation">, "DisableValidationForModuleKind::None">,
Normalizer<"makeFlagToValueNormalizer(DisableValidationForModuleKind::All)">;
def fpcm_output_path_independent : Flag<["-"], "fpcm-output-path-independent">,
HelpText<"Output a PCM/PCH file that does not write out information about its output path">,
MarshallingInfoFlag<FrontendOpts<"OutputPathIndependentPCM">>;
def fallow_pcm_with_errors : Flag<["-"], "fallow-pcm-with-compiler-errors">,
HelpText<"Accept a PCM file that was created with compiler errors">,
MarshallingInfoFlag<FrontendOpts<"AllowPCMWithCompilerErrors">>;

View File

@ -344,6 +344,15 @@ public:
/// When using -emit-module, treat the modulemap as a system module.
unsigned IsSystemModule : 1;
/// Output a PCM/PCH file that does not write out information about its output
/// path.
///
/// FIXME: This only controls whether \p ORIGINAL_PCH_DIR record is written
/// out or not. Consider either removing that record entirely if it's no
/// longer relevant or switching the default to not write it unless an option
/// is set to true.
unsigned OutputPathIndependentPCM : 1;
/// Output (and read) PCM files regardless of compiler errors.
unsigned AllowPCMWithCompilerErrors : 1;
@ -513,7 +522,8 @@ public:
ASTDumpLookups(false), BuildingImplicitModule(false),
BuildingImplicitModuleUsesLock(true), ModulesEmbedAllFiles(false),
IncludeTimestamps(true), UseTemporary(true),
AllowPCMWithCompilerErrors(false), TimeTraceGranularity(500) {}
OutputPathIndependentPCM(false), AllowPCMWithCompilerErrors(false),
TimeTraceGranularity(500) {}
/// getInputKindForExtension - Return the appropriate input kind for a file
/// extension. For example, "c" would return Language::C.

View File

@ -573,7 +573,8 @@ public:
ASTFileSignature WriteAST(Sema &SemaRef, StringRef OutputFile,
Module *WritingModule, StringRef isysroot,
bool hasErrors = false,
bool ShouldCacheASTInMemory = false);
bool ShouldCacheASTInMemory = false,
bool OutputPathIndependent = false);
/// Emit a token.
void AddToken(const Token &Tok, RecordDataImpl &Record);
@ -764,6 +765,7 @@ class PCHGenerator : public SemaConsumer {
ASTWriter Writer;
bool AllowASTWithErrors;
bool ShouldCacheASTInMemory;
bool OutputPathIndependent;
protected:
ASTWriter &getWriter() { return Writer; }
@ -776,7 +778,8 @@ public:
std::shared_ptr<PCHBuffer> Buffer,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
bool AllowASTWithErrors = false, bool IncludeTimestamps = true,
bool ShouldCacheASTInMemory = false);
bool ShouldCacheASTInMemory = false,
bool OutputPathIndependent = false);
~PCHGenerator() override;
void InitializeSema(Sema &S) override { SemaPtr = &S; }

View File

@ -140,7 +140,8 @@ GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
CI.getPreprocessor(), CI.getModuleCache(), OutputFile, Sysroot, Buffer,
FrontendOpts.ModuleFileExtensions,
CI.getPreprocessorOpts().AllowPCHWithCompilerErrors,
FrontendOpts.IncludeTimestamps, +CI.getLangOpts().CacheGeneratedPCH));
FrontendOpts.IncludeTimestamps, +CI.getLangOpts().CacheGeneratedPCH,
FrontendOpts.OutputPathIndependentPCM));
Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
CI, std::string(InFile), OutputFile, std::move(OS), Buffer));
@ -203,7 +204,9 @@ GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI,
/*IncludeTimestamps=*/
+CI.getFrontendOpts().BuildingImplicitModule,
/*ShouldCacheASTInMemory=*/
+CI.getFrontendOpts().BuildingImplicitModule));
+CI.getFrontendOpts().BuildingImplicitModule,
/*OutputPathIndependent=*/
+CI.getFrontendOpts().OutputPathIndependentPCM));
Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
CI, std::string(InFile), OutputFile, std::move(OS), Buffer));
return std::make_unique<MultiplexConsumer>(std::move(Consumers));

View File

@ -4483,7 +4483,8 @@ time_t ASTWriter::getTimestampForOutput(const FileEntry *E) const {
ASTFileSignature ASTWriter::WriteAST(Sema &SemaRef, StringRef OutputFile,
Module *WritingModule, StringRef isysroot,
bool hasErrors,
bool ShouldCacheASTInMemory) {
bool ShouldCacheASTInMemory,
bool OutputPathIndependent) {
WritingAST = true;
ASTHasCompilerErrors = hasErrors;
@ -4499,8 +4500,9 @@ ASTFileSignature ASTWriter::WriteAST(Sema &SemaRef, StringRef OutputFile,
Context = &SemaRef.Context;
PP = &SemaRef.PP;
this->WritingModule = WritingModule;
ASTFileSignature Signature =
WriteASTCore(SemaRef, isysroot, OutputFile, WritingModule);
ASTFileSignature Signature = WriteASTCore(
SemaRef, isysroot, OutputPathIndependent ? StringRef() : OutputFile,
WritingModule);
Context = nullptr;
PP = nullptr;
this->WritingModule = nullptr;

View File

@ -25,13 +25,14 @@ PCHGenerator::PCHGenerator(
StringRef OutputFile, StringRef isysroot, std::shared_ptr<PCHBuffer> Buffer,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
bool AllowASTWithErrors, bool IncludeTimestamps,
bool ShouldCacheASTInMemory)
bool ShouldCacheASTInMemory, bool OutputPathIndependent)
: PP(PP), OutputFile(OutputFile), isysroot(isysroot.str()),
SemaPtr(nullptr), Buffer(std::move(Buffer)), Stream(this->Buffer->Data),
Writer(Stream, this->Buffer->Data, ModuleCache, Extensions,
IncludeTimestamps),
AllowASTWithErrors(AllowASTWithErrors),
ShouldCacheASTInMemory(ShouldCacheASTInMemory) {
ShouldCacheASTInMemory(ShouldCacheASTInMemory),
OutputPathIndependent(OutputPathIndependent) {
this->Buffer->IsComplete = false;
}
@ -70,7 +71,7 @@ void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) {
// For serialization we are lenient if the errors were
// only warn-as-error kind.
PP.getDiagnostics().hasUncompilableErrorOccurred(),
ShouldCacheASTInMemory);
ShouldCacheASTInMemory, OutputPathIndependent);
Buffer->IsComplete = true;
}

View File

@ -0,0 +1,6 @@
// RUN: rm -rf %t && mkdir -p %t/a %t/b
// RUN: %clang_cc1 -triple x86_64-apple-macos11 -emit-pch %s -o %t/a/t1.pch -fpcm-output-path-independent
// RUN: %clang_cc1 -triple x86_64-apple-macos11 -emit-pch %s -o %t/b/t2.pch -fpcm-output-path-independent
// RUN: diff %t/a/t1.pch %t/b/t2.pch