Skip to content

Commit

Permalink
[Serialization] Remove ORIGINAL_PCH_DIR record
Browse files Browse the repository at this point in the history
Use of `ORIGINAL_PCH_DIR` record has been superseeded by making PCH/PCM files with relocatable paths at write time.
Removing this record is useful for producing an output-path-independent PCH file and enable sharing of the same PCH file even
when it was intended for a different output path.

Differential Revision: https://reviews.llvm.org/D131124
  • Loading branch information
akyrtzi committed Aug 5, 2022
1 parent 9ec4ddd commit 6635f48
Show file tree
Hide file tree
Showing 11 changed files with 20 additions and 122 deletions.
3 changes: 0 additions & 3 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -6018,9 +6018,6 @@ 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">>;
Expand Down
13 changes: 2 additions & 11 deletions clang/include/clang/Frontend/FrontendOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -344,15 +344,6 @@ class FrontendOptions {
/// 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;

Expand Down Expand Up @@ -525,8 +516,8 @@ class FrontendOptions {
ASTDumpLookups(false), BuildingImplicitModule(false),
BuildingImplicitModuleUsesLock(true), ModulesEmbedAllFiles(false),
IncludeTimestamps(true), UseTemporary(true),
OutputPathIndependentPCM(false), AllowPCMWithCompilerErrors(false),
ModulesShareFileManager(true), TimeTraceGranularity(500) {}
AllowPCMWithCompilerErrors(false), ModulesShareFileManager(true),
TimeTraceGranularity(500) {}

/// getInputKindForExtension - Return the appropriate input kind for a file
/// extension. For example, "c" would return Language::C.
Expand Down
3 changes: 0 additions & 3 deletions clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -343,9 +343,6 @@ enum ControlRecordTypes {
/// name.
ORIGINAL_FILE,

/// The directory that the PCH was originally created in.
ORIGINAL_PCH_DIR,

/// Record code for file ID of the file or buffer that was used to
/// generate the AST file.
ORIGINAL_FILE_ID,
Expand Down
11 changes: 4 additions & 7 deletions clang/include/clang/Serialization/ASTWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ class ASTWriter : public ASTDeserializationListener,

void WriteBlockInfoBlock();
void WriteControlBlock(Preprocessor &PP, ASTContext &Context,
StringRef isysroot, StringRef OutputFile);
StringRef isysroot);

/// Write out the signature and diagnostic options, and return the signature.
ASTFileSignature writeUnhashedControlBlock(Preprocessor &PP,
Expand Down Expand Up @@ -533,7 +533,7 @@ class ASTWriter : public ASTDeserializationListener,
void WriteDecl(ASTContext &Context, Decl *D);

ASTFileSignature WriteASTCore(Sema &SemaRef, StringRef isysroot,
StringRef OutputFile, Module *WritingModule);
Module *WritingModule);

public:
/// Create a new precompiled header writer that outputs to
Expand Down Expand Up @@ -573,8 +573,7 @@ class ASTWriter : public ASTDeserializationListener,
ASTFileSignature WriteAST(Sema &SemaRef, StringRef OutputFile,
Module *WritingModule, StringRef isysroot,
bool hasErrors = false,
bool ShouldCacheASTInMemory = false,
bool OutputPathIndependent = false);
bool ShouldCacheASTInMemory = false);

/// Emit a token.
void AddToken(const Token &Tok, RecordDataImpl &Record);
Expand Down Expand Up @@ -765,7 +764,6 @@ class PCHGenerator : public SemaConsumer {
ASTWriter Writer;
bool AllowASTWithErrors;
bool ShouldCacheASTInMemory;
bool OutputPathIndependent;

protected:
ASTWriter &getWriter() { return Writer; }
Expand All @@ -778,8 +776,7 @@ class PCHGenerator : public SemaConsumer {
std::shared_ptr<PCHBuffer> Buffer,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
bool AllowASTWithErrors = false, bool IncludeTimestamps = true,
bool ShouldCacheASTInMemory = false,
bool OutputPathIndependent = false);
bool ShouldCacheASTInMemory = false);
~PCHGenerator() override;

void InitializeSema(Sema &S) override { SemaPtr = &S; }
Expand Down
4 changes: 0 additions & 4 deletions clang/include/clang/Serialization/ModuleFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,6 @@ class ModuleFile {
/// build this AST file.
FileID OriginalSourceFileID;

/// The directory that the PCH was originally created in. Used to
/// allow resolving headers even after headers+PCH was moved to a new path.
std::string OriginalDir;

std::string ModuleMapPath;

/// Whether this precompiled header is a relocatable PCH file.
Expand Down
7 changes: 2 additions & 5 deletions clang/lib/Frontend/FrontendActions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,7 @@ GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
CI.getPreprocessor(), CI.getModuleCache(), OutputFile, Sysroot, Buffer,
FrontendOpts.ModuleFileExtensions,
CI.getPreprocessorOpts().AllowPCHWithCompilerErrors,
FrontendOpts.IncludeTimestamps, +CI.getLangOpts().CacheGeneratedPCH,
FrontendOpts.OutputPathIndependentPCM));
FrontendOpts.IncludeTimestamps, +CI.getLangOpts().CacheGeneratedPCH));
Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
CI, std::string(InFile), OutputFile, std::move(OS), Buffer));

Expand Down Expand Up @@ -204,9 +203,7 @@ GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI,
/*IncludeTimestamps=*/
+CI.getFrontendOpts().BuildingImplicitModule,
/*ShouldCacheASTInMemory=*/
+CI.getFrontendOpts().BuildingImplicitModule,
/*OutputPathIndependent=*/
+CI.getFrontendOpts().OutputPathIndependentPCM));
+CI.getFrontendOpts().BuildingImplicitModule));
Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
CI, std::string(InFile), OutputFile, std::move(OS), Buffer));
return std::make_unique<MultiplexConsumer>(std::move(Consumers));
Expand Down
55 changes: 3 additions & 52 deletions clang/lib/Serialization/ASTReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1395,41 +1395,6 @@ llvm::Error ASTReader::ReadSourceManagerBlock(ModuleFile &F) {
}
}

/// If a header file is not found at the path that we expect it to be
/// and the PCH file was moved from its original location, try to resolve the
/// file by assuming that header+PCH were moved together and the header is in
/// the same place relative to the PCH.
static std::string
resolveFileRelativeToOriginalDir(const std::string &Filename,
const std::string &OriginalDir,
const std::string &CurrDir) {
assert(OriginalDir != CurrDir &&
"No point trying to resolve the file if the PCH dir didn't change");

using namespace llvm::sys;

SmallString<128> filePath(Filename);
fs::make_absolute(filePath);
assert(path::is_absolute(OriginalDir));
SmallString<128> currPCHPath(CurrDir);

path::const_iterator fileDirI = path::begin(path::parent_path(filePath)),
fileDirE = path::end(path::parent_path(filePath));
path::const_iterator origDirI = path::begin(OriginalDir),
origDirE = path::end(OriginalDir);
// Skip the common path components from filePath and OriginalDir.
while (fileDirI != fileDirE && origDirI != origDirE &&
*fileDirI == *origDirI) {
++fileDirI;
++origDirI;
}
for (; origDirI != origDirE; ++origDirI)
path::append(currPCHPath, "..");
path::append(currPCHPath, fileDirI, fileDirE);
path::append(currPCHPath, path::filename(Filename));
return std::string(currPCHPath.str());
}

bool ASTReader::ReadSLocEntry(int ID) {
if (ID == 0)
return false;
Expand Down Expand Up @@ -2332,16 +2297,6 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
OptionalFileEntryRefDegradesToFileEntryPtr File =
expectedToOptional(FileMgr.getFileRef(Filename, /*OpenFile=*/false));

// If we didn't find the file, resolve it relative to the
// original directory from which this AST file was created.
if (!File && !F.OriginalDir.empty() && !F.BaseDirectory.empty() &&
F.OriginalDir != F.BaseDirectory) {
std::string Resolved = resolveFileRelativeToOriginalDir(
std::string(Filename), F.OriginalDir, F.BaseDirectory);
if (!Resolved.empty())
File = expectedToOptional(FileMgr.getFileRef(Resolved));
}

// For an overridden file, create a virtual file with the stored
// size/timestamp.
if ((Overridden || Transient) && !File)
Expand Down Expand Up @@ -2896,11 +2851,6 @@ ASTReader::ReadControlBlock(ModuleFile &F,
F.OriginalSourceFileID = FileID::get(Record[0]);
break;

case ORIGINAL_PCH_DIR:
F.OriginalDir = std::string(Blob);
ResolveImportedPath(F, F.OriginalDir);
break;

case MODULE_NAME:
F.ModuleName = std::string(Blob);
Diag(diag::remark_module_import)
Expand Down Expand Up @@ -8704,8 +8654,9 @@ ASTReader::getSourceDescriptor(unsigned ID) {
ModuleFile &MF = ModuleMgr.getPrimaryModule();
StringRef ModuleName = llvm::sys::path::filename(MF.OriginalSourceFileName);
StringRef FileName = llvm::sys::path::filename(MF.FileName);
return ASTSourceDescriptor(ModuleName, MF.OriginalDir, FileName,
MF.Signature);
return ASTSourceDescriptor(ModuleName,
llvm::sys::path::parent_path(MF.FileName),
FileName, MF.Signature);
}
return None;
}
Expand Down
28 changes: 4 additions & 24 deletions clang/lib/Serialization/ASTWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,6 @@ void ASTWriter::WriteBlockInfoBlock() {
RECORD(MODULE_MAP_FILE);
RECORD(IMPORTS);
RECORD(ORIGINAL_FILE);
RECORD(ORIGINAL_PCH_DIR);
RECORD(ORIGINAL_FILE_ID);
RECORD(INPUT_FILE_OFFSETS);

Expand Down Expand Up @@ -1187,7 +1186,7 @@ ASTFileSignature ASTWriter::writeUnhashedControlBlock(Preprocessor &PP,

/// Write the control block.
void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
StringRef isysroot, StringRef OutputFile) {
StringRef isysroot) {
using namespace llvm;

Stream.EnterSubblock(CONTROL_BLOCK_ID, 5);
Expand Down Expand Up @@ -1470,21 +1469,6 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
Record.push_back(SM.getMainFileID().getOpaqueValue());
Stream.EmitRecord(ORIGINAL_FILE_ID, Record);

// Original PCH directory
if (!OutputFile.empty() && OutputFile != "-") {
auto Abbrev = std::make_shared<BitCodeAbbrev>();
Abbrev->Add(BitCodeAbbrevOp(ORIGINAL_PCH_DIR));
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name
unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));

SmallString<128> OutputPath(OutputFile);
PreparePathForOutput(OutputPath);
StringRef origDir = llvm::sys::path::parent_path(OutputPath);

RecordData::value_type Record[] = {ORIGINAL_PCH_DIR};
Stream.EmitRecordWithBlob(AbbrevCode, Record, origDir);
}

std::set<const FileEntry *> AffectingModuleMaps;
if (WritingModule) {
AffectingModuleMaps =
Expand Down Expand Up @@ -4483,8 +4467,7 @@ time_t ASTWriter::getTimestampForOutput(const FileEntry *E) const {
ASTFileSignature ASTWriter::WriteAST(Sema &SemaRef, StringRef OutputFile,
Module *WritingModule, StringRef isysroot,
bool hasErrors,
bool ShouldCacheASTInMemory,
bool OutputPathIndependent) {
bool ShouldCacheASTInMemory) {
WritingAST = true;

ASTHasCompilerErrors = hasErrors;
Expand All @@ -4500,9 +4483,7 @@ ASTFileSignature ASTWriter::WriteAST(Sema &SemaRef, StringRef OutputFile,
Context = &SemaRef.Context;
PP = &SemaRef.PP;
this->WritingModule = WritingModule;
ASTFileSignature Signature = WriteASTCore(
SemaRef, isysroot, OutputPathIndependent ? StringRef() : OutputFile,
WritingModule);
ASTFileSignature Signature = WriteASTCore(SemaRef, isysroot, WritingModule);
Context = nullptr;
PP = nullptr;
this->WritingModule = nullptr;
Expand All @@ -4528,7 +4509,6 @@ static void AddLazyVectorDecls(ASTWriter &Writer, Vector &Vec,
}

ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
StringRef OutputFile,
Module *WritingModule) {
using namespace llvm;

Expand Down Expand Up @@ -4682,7 +4662,7 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
}

// Write the control block
WriteControlBlock(PP, Context, isysroot, OutputFile);
WriteControlBlock(PP, Context, isysroot);

// Write the remaining AST contents.
Stream.FlushToWord();
Expand Down
7 changes: 3 additions & 4 deletions clang/lib/Serialization/GeneratePCH.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,13 @@ PCHGenerator::PCHGenerator(
StringRef OutputFile, StringRef isysroot, std::shared_ptr<PCHBuffer> Buffer,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
bool AllowASTWithErrors, bool IncludeTimestamps,
bool ShouldCacheASTInMemory, bool OutputPathIndependent)
bool ShouldCacheASTInMemory)
: 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),
OutputPathIndependent(OutputPathIndependent) {
ShouldCacheASTInMemory(ShouldCacheASTInMemory) {
this->Buffer->IsComplete = false;
}

Expand Down Expand Up @@ -71,7 +70,7 @@ void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) {
// For serialization we are lenient if the errors were
// only warn-as-error kind.
PP.getDiagnostics().hasUncompilableErrorOccurred(),
ShouldCacheASTInMemory, OutputPathIndependent);
ShouldCacheASTInMemory);

Buffer->IsComplete = true;
}
Expand Down
7 changes: 0 additions & 7 deletions clang/test/Modules/relative-original-dir.m

This file was deleted.

4 changes: 2 additions & 2 deletions clang/test/PCH/pch-output-path-independent.c
Original file line number Diff line number Diff line change
@@ -1,6 +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: %clang_cc1 -triple x86_64-apple-macos11 -emit-pch %s -o %t/a/t1.pch
// RUN: %clang_cc1 -triple x86_64-apple-macos11 -emit-pch %s -o %t/b/t2.pch

// RUN: diff %t/a/t1.pch %t/b/t2.pch

0 comments on commit 6635f48

Please sign in to comment.