Skip to content

Cherry-picks from upstream llvm.org that make PCH files output path independent #5091

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
5 changes: 2 additions & 3 deletions clang/include/clang/Serialization/ASTWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ class ASTWriter : public ASTDeserializationListener,

void WriteBlockInfoBlock();
void WriteControlBlock(Preprocessor &PP, ASTContext &Context,
StringRef isysroot, const std::string &OutputFile);
StringRef isysroot);

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

ASTFileSignature WriteASTCore(Sema &SemaRef, StringRef isysroot,
const std::string &OutputFile,
Module *WritingModule);

public:
Expand Down Expand Up @@ -569,7 +568,7 @@ class ASTWriter : public ASTDeserializationListener,
///
/// \return the module signature, which eventually will be a hash of
/// the module but currently is merely a random 32-bit number.
ASTFileSignature WriteAST(Sema &SemaRef, const std::string &OutputFile,
ASTFileSignature WriteAST(Sema &SemaRef, StringRef OutputFile,
Module *WritingModule, StringRef isysroot,
bool hasErrors = false,
bool ShouldCacheASTInMemory = false);
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
54 changes: 3 additions & 51 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 @@ -2892,10 +2847,6 @@ ASTReader::ReadControlBlock(ModuleFile &F,
F.OriginalSourceFileID = FileID::get(Record[0]);
break;

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

case MODULE_NAME:
F.ModuleName = std::string(Blob);
Diag(diag::remark_module_import)
Expand Down Expand Up @@ -8701,8 +8652,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
29 changes: 4 additions & 25 deletions clang/lib/Serialization/ASTWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -801,7 +801,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 @@ -1232,8 +1231,7 @@ ASTFileSignature ASTWriter::writeUnhashedControlBlock(Preprocessor &PP,

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

Stream.EnterSubblock(CONTROL_BLOCK_ID, 5);
Expand Down Expand Up @@ -1483,22 +1481,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);

SM.getFileManager().makeAbsolutePath(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 @@ -4471,8 +4453,7 @@ time_t ASTWriter::getTimestampForOutput(const FileEntry *E) const {
return IncludeTimestamps ? E->getModificationTime() : 0;
}

ASTFileSignature ASTWriter::WriteAST(Sema &SemaRef,
const std::string &OutputFile,
ASTFileSignature ASTWriter::WriteAST(Sema &SemaRef, StringRef OutputFile,
Module *WritingModule, StringRef isysroot,
bool hasErrors,
bool ShouldCacheASTInMemory) {
Expand All @@ -4491,8 +4472,7 @@ ASTFileSignature ASTWriter::WriteAST(Sema &SemaRef,
Context = &SemaRef.Context;
PP = &SemaRef.PP;
this->WritingModule = WritingModule;
ASTFileSignature Signature =
WriteASTCore(SemaRef, isysroot, OutputFile, WritingModule);
ASTFileSignature Signature = WriteASTCore(SemaRef, isysroot, WritingModule);
Context = nullptr;
PP = nullptr;
this->WritingModule = nullptr;
Expand All @@ -4518,7 +4498,6 @@ static void AddLazyVectorDecls(ASTWriter &Writer, Vector &Vec,
}

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

Expand Down Expand Up @@ -4672,7 +4651,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
1 change: 1 addition & 0 deletions clang/test/Modules/cxx20-export-import.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

// RUN: rm -rf %t
// RUN: %clang_cc1 -std=c++20 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps -I%S/Inputs -verify %s
export import dummy; // expected-error {{export declaration can only be used within a module interface unit after the module declaration}}
6 changes: 6 additions & 0 deletions clang/test/PCH/pch-output-path-independent.c
Original file line number Diff line number Diff line change
@@ -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
// 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