https://github.com/vvereschaka created https://github.com/llvm/llvm-project/pull/203662
This commit extends a path prefix mapping provided by `-ffile-prefix-map` (`-fmacro-prefix-map`) options to PCH/PCM files in order to support the reproducable builds. It uses the prefix map passedvia `-fmacro-prefix-map` option to remap the pathes stored within those files. These changes affect `ORIGINAL_FILE`, `INPUT_FILE` and `MODULE_DIRECTORY` AST entries within the PCH/PCM files. The same prefix maps must be used when emitting the PCH/PCM files (`--emit-pch`/`--emit-module`) and during their usage (`--include-pch`/ `-fmodule-file`). Also updated `LangOptions::remapPathPrefix()` method to support a reverse mapping for the path prefixes. >From af1990ff20c05be5844bdda439ed5abc554a755b Mon Sep 17 00:00:00 2001 From: Vladimir Vereschaka <[email protected]> Date: Wed, 3 Jun 2026 17:17:03 -0700 Subject: [PATCH] [clang][AST] Add path prefix mapping support for PCH/PCM files. This commit extends a path prefix mapping provided by `-ffile-prefix-map` (`-fmacro-prefix-map`) options to PCH/PCM files in order to support the reproducable builds. It uses the prefix map passedvia `-fmacro-prefix-map` option to remap the pathes stored within those files. These changes affect `ORIGINAL_FILE`, `INPUT_FILE` and `MODULE_DIRECTORY` AST entries within the PCH/PCM files. The same prefix maps must be used when emitting the PCH/PCM files (`--emit-pch`/`--emit-module`) and during their usage (`--include-pch`/ `-fmodule-file`). Also updated `LangOptions::remapPathPrefix()` method to support a reverse mapping for the path prefixes. --- clang/include/clang/Basic/LangOptions.h | 7 +- clang/include/clang/Serialization/ASTReader.h | 37 ++++++-- clang/lib/Basic/LangOptions.cpp | 13 ++- .../DependencyScannerImpl.cpp | 4 +- clang/lib/Frontend/ASTUnit.cpp | 2 +- clang/lib/Frontend/CompilerInstance.cpp | 2 +- clang/lib/Frontend/FrontendActions.cpp | 2 +- clang/lib/Serialization/ASTReader.cpp | 86 +++++++++++++------ clang/lib/Serialization/ASTWriter.cpp | 9 +- clang/test/Modules/module-path-prefix-map.cpp | 45 ++++++++++ clang/test/PCH/pch-path-prefix-map.cpp | 48 +++++++++++ 11 files changed, 207 insertions(+), 48 deletions(-) create mode 100644 clang/test/Modules/module-path-prefix-map.cpp create mode 100644 clang/test/PCH/pch-path-prefix-map.cpp diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 9af036156b1ad..b4ca32b42bcc1 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -796,8 +796,11 @@ class LangOptions : public LangOptionsBase { bool allowArrayReturnTypes() const { return HLSL; } - /// Remap path prefix according to -fmacro-prefix-path option. - void remapPathPrefix(SmallVectorImpl<char> &Path) const; + /// Remap path prefix according to -fmacro-prefix-map option. + /// If 'reverse' is true the swapped prefix pair will be used. + /// Returns true if Path was changed. + bool remapPathPrefix(SmallVectorImpl<char> &Path, + const bool reverse = false) const; RoundingMode getDefaultRoundingMode() const { return RoundingMath ? RoundingMode::Dynamic diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index 61bd3d0748988..2809ac2b4e9b5 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -1460,15 +1460,35 @@ class ASTReader : public ExternalPreprocessorSource, /// value must go out of scope before the next call to \c ResolveImportedPath. static TemporarilyOwnedStringRef ResolveImportedPath(SmallString<0> &Buf, StringRef Path, StringRef Prefix); + /// Resolve \c Path in the context of module file \c M with substitution + /// of the path prefixes in case provided them by `-ffile-prefix-map` or + /// `-fmacro-prefix-map` options. + /// The return value must go out of scope before the next call to + /// \c ResolveImportedPath. + static TemporarilyOwnedStringRef + ResolveImportedPath(SmallString<0> &Buf, StringRef Path, ModuleFile &ModF, + const LangOptions &LangOpts); + /// Resolve \c Path in the context of the \c Prefix directory with + /// substitution of the path prefixes in case provided them by + /// `-ffile-prefix-map` or `-fmacro-prefix-map` options. + /// The return value must go out of scope before the next call to + /// \c ResolveImportedPath. + static TemporarilyOwnedStringRef + ResolveImportedPath(SmallString<0> &Buf, StringRef Path, StringRef Prefix, + const LangOptions &LangOpts); /// Resolve \c Path in the context of module file \c M. - static std::string ResolveImportedPathAndAllocate(SmallString<0> &Buf, - StringRef Path, - ModuleFile &ModF); + /// The module path could be remapped with the path prefixes provided by + /// `-ffile-prefix-map` or `-fmacro-prefix-map` options. + static std::string + ResolveImportedPathAndAllocate(SmallString<0> &Buf, StringRef Path, + ModuleFile &ModF, const LangOptions &LangOpts); /// Resolve \c Path in the context of the \c Prefix directory. - static std::string ResolveImportedPathAndAllocate(SmallString<0> &Buf, - StringRef Path, - StringRef Prefix); + /// The path could be remapped with the path prefixes provided by + /// `-ffile-prefix-map` or `-fmacro-prefix-map` options. + static std::string + ResolveImportedPathAndAllocate(SmallString<0> &Buf, StringRef Path, + StringRef Prefix, const LangOptions &LangOpts); /// Returns the first key declaration for the given declaration. This /// is one that is formerly-canonical (or still canonical) and whose module @@ -1998,8 +2018,9 @@ class ASTReader : public ExternalPreprocessorSource, /// \returns true if an error occurred, false otherwise. static bool readASTFileControlBlock( StringRef Filename, FileManager &FileMgr, const ModuleCache &ModCache, - const PCHContainerReader &PCHContainerRdr, bool FindModuleFileExtensions, - ASTReaderListener &Listener, bool ValidateDiagnosticOptions, + const PCHContainerReader &PCHContainerRdr, const LangOptions &LangOpts, + bool FindModuleFileExtensions, ASTReaderListener &Listener, + bool ValidateDiagnosticOptions, unsigned ClientLoadCapabilities = ARR_ConfigurationMismatch | ARR_OutOfDate); diff --git a/clang/lib/Basic/LangOptions.cpp b/clang/lib/Basic/LangOptions.cpp index 7e75bf1221eb7..3c351ea7a985c 100644 --- a/clang/lib/Basic/LangOptions.cpp +++ b/clang/lib/Basic/LangOptions.cpp @@ -74,10 +74,15 @@ unsigned LangOptions::getOpenCLCompatibleVersion() const { llvm_unreachable("Unknown OpenCL version"); } -void LangOptions::remapPathPrefix(SmallVectorImpl<char> &Path) const { - for (const auto &Entry : MacroPrefixMap) - if (llvm::sys::path::replace_path_prefix(Path, Entry.first, Entry.second)) - break; +bool LangOptions::remapPathPrefix(SmallVectorImpl<char> &Path, + const bool reverse /*=false*/) const { + for (const auto &Entry : MacroPrefixMap) { + const std::string& From = reverse ? Entry.second : Entry.first; + const std::string& To = reverse ? Entry.first : Entry.second; + if (llvm::sys::path::replace_path_prefix(Path, From, To)) + return true; + } + return false; } std::string LangOptions::getOpenCLVersionString() const { diff --git a/clang/lib/DependencyScanning/DependencyScannerImpl.cpp b/clang/lib/DependencyScanning/DependencyScannerImpl.cpp index dc3dbe3603c01..eb34ae2656f09 100644 --- a/clang/lib/DependencyScanning/DependencyScannerImpl.cpp +++ b/clang/lib/DependencyScanning/DependencyScannerImpl.cpp @@ -189,7 +189,7 @@ static bool visitPrebuiltModule(StringRef PrebuiltModuleFilename, /*DirectlyImported=*/true); if (ASTReader::readASTFileControlBlock( PrebuiltModuleFilename, CI.getFileManager(), CI.getModuleCache(), - CI.getPCHContainerReader(), + CI.getPCHContainerReader(), CI.getLangOpts(), /*FindModuleFileExtensions=*/false, Listener, /*ValidateDiagnosticOptions=*/false, ASTReader::ARR_OutOfDate)) return true; @@ -205,7 +205,7 @@ static bool visitPrebuiltModule(StringRef PrebuiltModuleFilename, /*DirectlyImported=*/false); if (ASTReader::readASTFileControlBlock( Worklist.pop_back_val(), CI.getFileManager(), CI.getModuleCache(), - CI.getPCHContainerReader(), + CI.getPCHContainerReader(), CI.getLangOpts(), /*FindModuleFileExtensions=*/false, Listener, /*ValidateDiagnosticOptions=*/false)) return true; diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index 2974cf2660184..01cefc1f18ede 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -734,7 +734,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile( *AST->LangOpts, *AST->CodeGenOpts, *AST->TargetOpts, Counter); if (ASTReader::readASTFileControlBlock( - Filename, TmpFileMgr, *AST->ModCache, PCHContainerRdr, + Filename, TmpFileMgr, *AST->ModCache, PCHContainerRdr, *AST->LangOpts, /*FindModuleFileExtensions=*/true, Collector, /*ValidateDiagnosticOptions=*/true, ASTReader::ARR_None)) { AST->getDiagnostics().Report(diag::err_fe_unable_to_load_ast_file); diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index 8aee45b5dc644..1f19e7ac252f8 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -265,7 +265,7 @@ static void collectIncludePCH(CompilerInstance &CI, // but only to check whether this is a file containing an AST. if (!ASTReader::readASTFileControlBlock( Dir->path(), FileMgr, CI.getModuleCache(), - CI.getPCHContainerReader(), + CI.getPCHContainerReader(), CI.getLangOpts(), /*FindModuleFileExtensions=*/false, Validator, /*ValidateDiagnosticOptions=*/false)) MDC->addFile(Dir->path()); diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index ba3487d52e380..fac3088a5ad91 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -1010,7 +1010,7 @@ void DumpModuleInfoAction::ExecuteAction() { // FileCcontrolBlock is (re-)parsed. ASTReader::readASTFileControlBlock( getCurrentFile(), FileMgr, CI.getModuleCache(), - CI.getPCHContainerReader(), + CI.getPCHContainerReader(), CI.getLangOpts(), /*FindModuleFileExtensions=*/true, Listener, HSOpts.ModulesValidateDiagnosticOptions); } diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index f8a6a38bb9b5c..6e2ce4ead79df 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -2341,8 +2341,8 @@ HeaderFileInfoTrait::getFile(const internal_key_type &Key) { if (!Key.Imported) return FileMgr.getOptionalFileRef(Key.Filename); - auto Resolved = - ASTReader::ResolveImportedPath(Reader.getPathBuf(), Key.Filename, M); + auto Resolved = Reader.ResolveImportedPath( + Reader.getPathBuf(), Key.Filename, M, Reader.getContext().getLangOpts()); return FileMgr.getOptionalFileRef(*Resolved); } @@ -2872,8 +2872,8 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) { time_t StoredTime = FI.StoredTime; bool Overridden = FI.Overridden; bool Transient = FI.Transient; - auto Filename = - ResolveImportedPath(PathBuf, FI.UnresolvedImportedFilenameAsRequested, F); + auto Filename = ResolveImportedPath( + PathBuf, FI.UnresolvedImportedFilenameAsRequested, F, PP.getLangOpts()); uint64_t StoredContentHash = FI.ContentHash; // For standard C++ modules, we don't need to check the inputs. @@ -3056,16 +3056,36 @@ ASTReader::ResolveImportedPath(SmallString<0> &Buf, StringRef Path, return {ResolvedPath, Buf}; } -std::string ASTReader::ResolveImportedPathAndAllocate(SmallString<0> &Buf, - StringRef P, - ModuleFile &ModF) { - return ResolveImportedPathAndAllocate(Buf, P, ModF.BaseDirectory); +ASTReader::TemporarilyOwnedStringRef +ASTReader::ResolveImportedPath(SmallString<0> &Buf, StringRef Path, + StringRef Prefix, const LangOptions &LangOpts) { + auto Resolved = ResolveImportedPath(Buf, Path, Prefix); + + Buf.assign(*Resolved); + if (LangOpts.remapPathPrefix(Buf, true)) + return {StringRef{Buf.data(), Buf.size()}, Buf}; + + return Resolved; +} + +ASTReader::TemporarilyOwnedStringRef +ASTReader::ResolveImportedPath(SmallString<0> &Buf, StringRef Path, + ModuleFile &ModF, const LangOptions &LangOpts) { + return ResolveImportedPath(Buf, Path, ModF.BaseDirectory, LangOpts); } -std::string ASTReader::ResolveImportedPathAndAllocate(SmallString<0> &Buf, - StringRef P, - StringRef Prefix) { - auto ResolvedPath = ResolveImportedPath(Buf, P, Prefix); +std::string +ASTReader::ResolveImportedPathAndAllocate(SmallString<0> &Buf, StringRef P, + ModuleFile &ModF, + const LangOptions &LangOpts) { + return ResolveImportedPathAndAllocate(Buf, P, ModF.BaseDirectory, LangOpts); +} + +std::string +ASTReader::ResolveImportedPathAndAllocate(SmallString<0> &Buf, StringRef P, + StringRef Prefix, + const LangOptions &LangOpts) { + auto ResolvedPath = ResolveImportedPath(Buf, P, Prefix, LangOpts); return ResolvedPath->str(); } @@ -3339,7 +3359,8 @@ ASTReader::ReadControlBlock(ModuleFile &F, bool IsSystem = I >= NumUserInputs; InputFileInfo FI = getInputFileInfo(F, I + 1); auto FilenameAsRequested = ResolveImportedPath( - PathBuf, FI.UnresolvedImportedFilenameAsRequested, F); + PathBuf, FI.UnresolvedImportedFilenameAsRequested, F, + PP.getLangOpts()); Listener->visitInputFile( *FilenameAsRequested, IsSystem, FI.Overridden, F.Kind == MK_ExplicitModule || F.Kind == MK_PrebuiltModule); @@ -3417,6 +3438,7 @@ ASTReader::ReadControlBlock(ModuleFile &F, // Read and process a record. Record.clear(); StringRef Blob; + SmallString<0> RPath; Expected<unsigned> MaybeRecordType = Stream.readRecord(Entry.ID, Record, &Blob); if (!MaybeRecordType) { @@ -3603,7 +3625,7 @@ ASTReader::ReadControlBlock(ModuleFile &F, F.OriginalSourceFileID = FileID::get(Record[0]); F.ActualOriginalSourceFileName = std::string(Blob); F.OriginalSourceFileName = ResolveImportedPathAndAllocate( - PathBuf, F.ActualOriginalSourceFileName, F); + PathBuf, F.ActualOriginalSourceFileName, F, PP.getLangOpts()); break; case ORIGINAL_FILE_ID: @@ -3627,10 +3649,15 @@ ASTReader::ReadControlBlock(ModuleFile &F, case MODULE_DIRECTORY: { // Save the BaseDirectory as written in the PCM for computing the module - // filename for the ModuleCache. + // filename for the ModuleCache. Remap path prefixes if specified. + RPath.assign(Blob.begin(), Blob.end()); + if (PP.getLangOpts().remapPathPrefix(RPath, true)) + Blob = StringRef(RPath.begin(), RPath.size()); + BaseDirectoryAsWritten = Blob; assert(!F.ModuleName.empty() && "MODULE_DIRECTORY found before MODULE_NAME"); + F.BaseDirectory = std::string(Blob); auto [MaybeM, IgnoreError] = @@ -4032,8 +4059,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, case MODULAR_CODEGEN_DECLS: // FIXME: Skip reading this record if our ASTConsumer doesn't care about // them (ie: if we're not codegenerating this module). - if (F.Kind == MK_MainFile || - getContext().getLangOpts().BuildingPCHWithObjectFile) + if (F.Kind == MK_MainFile || PP.getLangOpts().BuildingPCHWithObjectFile) for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/) EagerlyDeserializedDecls.push_back(ReadDeclID(F, Record, I)); break; @@ -5974,9 +6000,9 @@ namespace { bool ASTReader::readASTFileControlBlock( StringRef Filename, FileManager &FileMgr, const ModuleCache &ModCache, - const PCHContainerReader &PCHContainerRdr, bool FindModuleFileExtensions, - ASTReaderListener &Listener, bool ValidateDiagnosticOptions, - unsigned ClientLoadCapabilities) { + const PCHContainerReader &PCHContainerRdr, const LangOptions &LangOpts, + bool FindModuleFileExtensions, ASTReaderListener &Listener, + bool ValidateDiagnosticOptions, unsigned ClientLoadCapabilities) { // Open the AST file. off_t Size; time_t ModTime; @@ -6124,7 +6150,7 @@ bool ASTReader::readASTFileControlBlock( case MODULE_MAP_FILE: { unsigned Idx = 0; std::string PathStr = ReadString(Record, Idx); - auto Path = ResolveImportedPath(PathBuf, PathStr, ModuleDir); + auto Path = ResolveImportedPath(PathBuf, PathStr, ModuleDir, LangOpts); Listener.ReadModuleMapFile(*Path); break; } @@ -6176,13 +6202,13 @@ bool ASTReader::readASTFileControlBlock( auto [UnresolvedFilenameAsRequested, UnresolvedFilename] = getUnresolvedInputFilenames(Record, Blob); auto FilenameAsRequestedBuf = ResolveImportedPath( - PathBuf, UnresolvedFilenameAsRequested, ModuleDir); + PathBuf, UnresolvedFilenameAsRequested, ModuleDir, LangOpts); StringRef Filename; if (UnresolvedFilename.empty()) Filename = *FilenameAsRequestedBuf; else { auto FilenameBuf = ResolveImportedPath( - AdditionalPathBuf, UnresolvedFilename, ModuleDir); + AdditionalPathBuf, UnresolvedFilename, ModuleDir, LangOpts); Filename = *FilenameBuf; } shouldContinue = Listener.visitInputFileAsRequested( @@ -6226,7 +6252,8 @@ bool ASTReader::readASTFileControlBlock( Blob = Blob.substr(ASTFileSignature::size); StringRef FilenameStr = ReadStringBlob(Record, Idx, Blob); - auto Filename = ResolveImportedPath(PathBuf, FilenameStr, ModuleDir); + auto Filename = + ResolveImportedPath(PathBuf, FilenameStr, ModuleDir, LangOpts); Listener.visitImport(ModuleName, *Filename); break; } @@ -6313,6 +6340,7 @@ bool ASTReader::isAcceptableASTFile( SpecificModuleCachePath, FileMgr, RequireStrictOptionMatches); return !readASTFileControlBlock(Filename, FileMgr, ModCache, PCHContainerRdr, + LangOpts, /*FindModuleFileExtensions=*/false, validator, /*ValidateDiagnosticOptions=*/true); } @@ -6548,13 +6576,13 @@ Module *ASTReader::getSubmodule(uint32_t GlobalID) { break; case SUBMODULE_TOPHEADER: { - auto HeaderName = ResolveImportedPath(PathBuf, Blob, F); + auto HeaderName = ResolveImportedPath(PathBuf, Blob, F, PP.getLangOpts()); CurrentModule->addTopHeaderFilename(*HeaderName); break; } case SUBMODULE_UMBRELLA_DIR: { - auto Dirname = ResolveImportedPath(PathBuf, Blob, F); + auto Dirname = ResolveImportedPath(PathBuf, Blob, F, PP.getLangOpts()); if (auto Umbrella = PP.getFileManager().getOptionalDirectoryRef(*Dirname)) { if (!CurrentModule->getUmbrellaDirAsWritten()) { @@ -10464,14 +10492,16 @@ std::string ASTReader::ReadPath(ModuleFile &F, const RecordData &Record, std::string ASTReader::ReadPath(StringRef BaseDirectory, const RecordData &Record, unsigned &Idx) { std::string Filename = ReadString(Record, Idx); - return ResolveImportedPathAndAllocate(PathBuf, Filename, BaseDirectory); + return ResolveImportedPathAndAllocate(PathBuf, Filename, BaseDirectory, + PP.getLangOpts()); } std::string ASTReader::ReadPathBlob(StringRef BaseDirectory, const RecordData &Record, unsigned &Idx, StringRef &Blob) { StringRef Filename = ReadStringBlob(Record, Idx, Blob); - return ResolveImportedPathAndAllocate(PathBuf, Filename, BaseDirectory); + return ResolveImportedPathAndAllocate(PathBuf, Filename, BaseDirectory, + PP.getLangOpts()); } VersionTuple ASTReader::ReadVersionTuple(const RecordData &Record, diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 21dda6f3733e4..1a43aba60ed41 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -1505,7 +1505,12 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, StringRef isysroot) { unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev)); RecordData::value_type Record[] = {MODULE_DIRECTORY}; - Stream.EmitRecordWithBlob(AbbrevCode, Record, *BaseDir); + + // Remap the path with the prefixes if specified. Write out only + // remapped directory, but keep working with the unmodified path. + SmallString<0> RPath(*BaseDir); + getLangOpts().remapPathPrefix(RPath); + Stream.EmitRecordWithBlob(AbbrevCode, Record, RPath); } // Write out all other paths relative to the base directory if possible. @@ -5417,6 +5422,8 @@ bool ASTWriter::PreparePathForOutput(SmallVectorImpl<char> &Path) { Path.erase(Path.begin(), Path.begin() + (PathPtr - PathBegin)); Changed = true; } + // Remap with the path prefixes if provided. + Changed |= getLangOpts().remapPathPrefix(Path); return Changed; } diff --git a/clang/test/Modules/module-path-prefix-map.cpp b/clang/test/Modules/module-path-prefix-map.cpp new file mode 100644 index 0000000000000..475e82dbe8f49 --- /dev/null +++ b/clang/test/Modules/module-path-prefix-map.cpp @@ -0,0 +1,45 @@ +//NOTE: this test reuses the existing include/module files. + +// RUN: rm -rf %t +// RUN: mkdir -p %t/merge-vtable-codegen +// RUN: cp -r %S/Inputs/merge-vtable-codegen %t/ + +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fimplicit-module-maps -fmodule-name=b -fmodules-cache-path=%t -o %t/b1.pcm \ +// RUN: -emit-module %t/merge-vtable-codegen/merge-vtable-codegen.modulemap \ +// RUN: -I%t//merge-vtable-codegen -fmacro-prefix-map=%S=x:/PREFIX-MAP-IN -fmacro-prefix-map=%t=x:/PREFIX-MAP-OUT +// RUN: llvm-bcanalyzer -dump --disable-histogram %t/b1.pcm | FileCheck -check-prefix=CHECK-PREFIX-MAP-OUT %s + +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fimplicit-module-maps -fmodule-name=b -fmodules-cache-path=%t -o %t/b1.pcm \ +// RUN: -emit-module %t/merge-vtable-codegen/merge-vtable-codegen.modulemap \ +// RUN: -I%t/./merge-vtable-codegen -fmacro-prefix-map=%S=x:/PREFIX-MAP-IN -fmacro-prefix-map=%t=x:/PREFIX-MAP-OUT +// RUN: llvm-bcanalyzer -dump --disable-histogram %t/b1.pcm | FileCheck -check-prefix=CHECK-PREFIX-MAP-OUT %s + +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fimplicit-module-maps -fmodule-name=b -fmodules-cache-path=%t -o %t/b1.pcm \ +// RUN: -emit-module %t/merge-vtable-codegen/merge-vtable-codegen.modulemap \ +// RUN: -I%t/../merge-vtable-codegen -fmacro-prefix-map=%S=x:/PREFIX-MAP-IN -fmacro-prefix-map=%t=x:/PREFIX-MAP-OUT +// RUN: llvm-bcanalyzer -dump --disable-histogram %t/b1.pcm | FileCheck -check-prefix=CHECK-PREFIX-MAP-OUT %s + + +// First, build two modules that both re-export the same header. +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fimplicit-module-maps -fmodule-name=b -o %t/b.pcm \ +// RUN: -emit-module %S/Inputs/merge-vtable-codegen/merge-vtable-codegen.modulemap \ +// RUN: -I%S/Inputs/merge-vtable-codegen -fmacro-prefix-map=%S=x:/PREFIX-MAP-IN -fmacro-prefix-map=%t=x:/PREFIX-MAP-OUT +// RUN: llvm-bcanalyzer -dump --disable-histogram %t/b.pcm | FileCheck -check-prefix=CHECK-PREFIX-MAP-IN %s + +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fimplicit-module-maps -fmodule-name=c -o %t/c.pcm \ +// RUN: -emit-module %S/Inputs/merge-vtable-codegen/merge-vtable-codegen.modulemap \ +// RUN: -I%S/Inputs/merge-vtable-codegen -fmacro-prefix-map=%S=x:/PREFIX-MAP-IN -fmacro-prefix-map=%t=x:/PREFIX-MAP-OUT +// RUN: llvm-bcanalyzer -dump --disable-histogram %t/c.pcm | FileCheck -check-prefix=CHECK-PREFIX-MAP-IN %s + +// Use the two modules in a single compile. +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fimplicit-module-maps -fmodule-file=%t/b.pcm -fmodule-file=%t/c.pcm \ +// RUN: -fmodule-map-file=%S/Inputs/merge-vtable-codegen/merge-vtable-codegen.modulemap -fmacro-prefix-map=%S=x:/PREFIX-MAP-IN -fmacro-prefix-map=%t=x:/PREFIX-MAP-OUT \ +// RUN: -emit-llvm -o %t/test.o %s + + +// CHECK-PREFIX-MAP-IN: <MODULE_DIRECTORY {{.*}}/> blob data = 'x:/PREFIX-MAP-IN{{[/\\]}}Inputs{{[/\\]}}merge-vtable-codegen' + +// CHECK-PREFIX-MAP-OUT: <MODULE_DIRECTORY {{.*}}/> blob data = 'x:/PREFIX-MAP-OUT{{[/\\]}}merge-vtable-codegen' + +#include "Inputs/merge-vtable-codegen/c.h" +#include "Inputs/merge-vtable-codegen/b.h" diff --git a/clang/test/PCH/pch-path-prefix-map.cpp b/clang/test/PCH/pch-path-prefix-map.cpp new file mode 100644 index 0000000000000..eeb520691dace --- /dev/null +++ b/clang/test/PCH/pch-path-prefix-map.cpp @@ -0,0 +1,48 @@ +//NOTE: this test reuses the existing include files. + +// Create PCH with mappend path prefixes +// RUN: mkdir -p %t-dir +// RUN: cp %S/Inputs/pch-through3.h %t-dir +// RUN: cp %S/Inputs/pch-through4.h %t-dir + +// RUN: %clang_cc1 -I %S -I %t-dir -x c++-header -emit-pch -fmacro-prefix-map=%S=x:/PREFIX-MAP-IN -fmacro-prefix-map=%t-dir=x:/PREFIX-MAP-OUT \ +// RUN: -o %t.pch %s +// RUN: llvm-bcanalyzer -dump --disable-histogram %t.pch | FileCheck -check-prefix=CHECK-PREFIX-MAP-ORIGINAL %s +// RUN: llvm-bcanalyzer -dump --disable-histogram %t.pch | FileCheck -check-prefix=CHECK-PREFIX-MAP-IN %s +// RUN: rm -f %t.pch + +// RUN: %clang_cc1 -I %S -I %t-dir -x c++-header -emit-pch -fmacro-prefix-map=%S=x:/PREFIX-MAP-IN -fmacro-prefix-map=%t-dir=x:/PREFIX-MAP-OUT \ +// RUN: -include %S/cmdline-include1.h -include cmdline-include2.h -o %t.pch %s +// RUN: llvm-bcanalyzer -dump --disable-histogram %t.pch | FileCheck -check-prefix=CHECK-PREFIX-MAP-ORIGINAL %s +// RUN: llvm-bcanalyzer -dump --disable-histogram %t.pch | FileCheck -check-prefix=CHECK-PREFIX-MAP-IN-CMD %s + +// Use PCH with mapped path prefixes. +// RUN: %clang_cc1 -I %S -I %t-dir -include-pch %t.pch -fmacro-prefix-map=%S=x:/PREFIX-MAP-IN -fmacro-prefix-map=%t-dir=x:/PREFIX-MAP-OUT %s +// RUN: rm -f %t.pch + +// RUN: %clang_cl -Werror /I %S /I %t-dir /Yc%s /FI%s /c /Fo%t.pch.obj /Fp%t.pch /pathmap:%S=x:/PREFIX-MAP-IN /pathmap:%t-dir=x:/PREFIX-MAP-OUT -- %s +// RUN: llvm-bcanalyzer -dump --disable-histogram %t.pch | FileCheck -check-prefix=CHECK-PREFIX-MAP-ORIGINAL %s +// RUN: llvm-bcanalyzer -dump --disable-histogram %t.pch | FileCheck -check-prefix=CHECK-PREFIX-MAP-IN %s + +// use {{[/\\]}} to follow LLVM_WINDOWS_PREFER_FORWARD_SLASH=ON|OFF on Windows. + +// CHECK-PREFIX-MAP-ORIGINAL: <ORIGINAL_FILE {{.*}}/> blob data = 'x:/PREFIX-MAP-IN{{[/\\]}}pch-path-prefix-map.cpp' +// CHECK-PREFIX-MAP-IN: <INPUT_FILE {{.*}}/> blob data = 'x:/PREFIX-MAP-IN{{[/\\]}}pch-path-prefix-map.cpp' +// CHECK-PREFIX-MAP-IN: <INPUT_FILE {{.*}}/> blob data = 'x:/PREFIX-MAP-IN{{[/\\]}}Inputs{{[/\\]}}pch-through{{[12]}}.h' +// CHECK-PREFIX-MAP-IN: <INPUT_FILE {{.*}}/> blob data = 'x:/PREFIX-MAP-IN{{[/\\]}}Inputs{{[/\\]}}pch-through{{[12]}}.h' +// CHECK-PREFIX-MAP-IN: <INPUT_FILE {{.*}}/> blob data = 'x:/PREFIX-MAP-OUT{{[/\\]}}pch-through{{[34]}}.h' +// CHECK-PREFIX-MAP-IN: <INPUT_FILE {{.*}}/> blob data = 'x:/PREFIX-MAP-OUT{{[/\\]}}pch-through{{[34]}}.h' + +// CHECK-PREFIX-MAP-IN-CMD: <INPUT_FILE {{.*}}/> blob data = 'x:/PREFIX-MAP-IN{{[/\\]}}pch-path-prefix-map.cpp' +// CHECK-PREFIX-MAP-IN-CMD: <INPUT_FILE {{.*}}/> blob data = 'x:/PREFIX-MAP-IN{{[/\\]}}cmdline-include{{[12]}}.h' +// CHECK-PREFIX-MAP-IN-CMD: <INPUT_FILE {{.*}}/> blob data = 'x:/PREFIX-MAP-IN{{[/\\]}}cmdline-include{{[12]}}.h' +// CHECK-PREFIX-MAP-IN-CMD: <INPUT_FILE {{.*}}/> blob data = 'x:/PREFIX-MAP-IN{{[/\\]}}Inputs{{[/\\]}}pch-through{{[12]}}.h' +// CHECK-PREFIX-MAP-IN-CMD: <INPUT_FILE {{.*}}/> blob data = 'x:/PREFIX-MAP-IN{{[/\\]}}Inputs{{[/\\]}}pch-through{{[12]}}.h' +// CHECK-PREFIX-MAP-IN-CMD: <INPUT_FILE {{.*}}/> blob data = 'x:/PREFIX-MAP-OUT{{[/\\]}}pch-through{{[34]}}.h' +// CHECK-PREFIX-MAP-IN-CMD: <INPUT_FILE {{.*}}/> blob data = 'x:/PREFIX-MAP-OUT{{[/\\]}}pch-through{{[34]}}.h' + +#include "Inputs/pch-through1.h" +#include "Inputs/pch-through2.h" +#include "pch-through3.h" +#include <pch-through4.h> + _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
