Index: clang/include/clang/Basic/LangOptions.h =================================================================== --- clang/include/clang/Basic/LangOptions.h +++ clang/include/clang/Basic/LangOptions.h @@ -367,6 +367,9 @@ /// A list of all -fno-builtin-* function names (e.g., memset). std::vector NoBuiltinFuncs; + /// A prefix map for __FILE__, __BASE_FILE__ and __builtin_FILE(). + std::map> MacroPrefixMap; + /// Triples of the OpenMP targets that the host code codegen should /// take into account in order to generate accurate offloading descriptors. std::vector OMPTargetTriples; @@ -473,6 +476,9 @@ } bool isSYCL() const { return SYCLIsDevice || SYCLIsHost; } + + /// Remap path prefix according to -fmacro-prefix-path option. + void remapPathPrefix(SmallString<256> &Path) const; }; /// Floating point control options Index: clang/include/clang/Lex/PreprocessorOptions.h =================================================================== --- clang/include/clang/Lex/PreprocessorOptions.h +++ clang/include/clang/Lex/PreprocessorOptions.h @@ -202,9 +202,6 @@ /// build it again. std::shared_ptr FailedModules; - /// A prefix map for __FILE__ and __BASE_FILE__. - std::map> MacroPrefixMap; - /// Contains the currently active skipped range mappings for skipping excluded /// conditional directives. /// Index: clang/lib/AST/Expr.cpp =================================================================== --- clang/lib/AST/Expr.cpp +++ clang/lib/AST/Expr.cpp @@ -2233,8 +2233,11 @@ }; switch (getIdentKind()) { - case SourceLocExpr::File: - return MakeStringLiteral(PLoc.getFilename()); + case SourceLocExpr::File: { + SmallString<256> Path(PLoc.getFilename()); + Ctx.getLangOpts().remapPathPrefix(Path); + return MakeStringLiteral(Path); + } case SourceLocExpr::Function: { const Decl *CurDecl = dyn_cast_or_null(Context); return MakeStringLiteral( Index: clang/lib/Basic/LangOptions.cpp =================================================================== --- clang/lib/Basic/LangOptions.cpp +++ clang/lib/Basic/LangOptions.cpp @@ -11,6 +11,8 @@ //===----------------------------------------------------------------------===// #include "clang/Basic/LangOptions.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/Path.h" using namespace clang; @@ -48,6 +50,12 @@ return VersionTuple(Ver / 100, (Ver % 100) / 10); } +void LangOptions::remapPathPrefix(SmallString<256> &Path) const { + for (const auto &Entry : MacroPrefixMap) + if (llvm::sys::path::replace_path_prefix(Path, Entry.first, Entry.second)) + break; +} + FPOptions FPOptions::defaultWithoutTrailingStorage(const LangOptions &LO) { FPOptions result(LO); return result; Index: clang/lib/CodeGen/CodeGenModule.cpp =================================================================== --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -186,7 +186,7 @@ !getModule().getSourceFileName().empty()) { std::string Path = getModule().getSourceFileName(); // Check if a path substitution is needed from the MacroPrefixMap. - for (const auto &Entry : PPO.MacroPrefixMap) + for (const auto &Entry : LangOpts.MacroPrefixMap) if (Path.rfind(Entry.first, 0) != std::string::npos) { Path = Entry.second + Path.substr(Entry.first.size()); break; Index: clang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -3528,6 +3528,9 @@ GenerateArg(Args, OPT_fexperimental_relative_cxx_abi_vtables, SA); else GenerateArg(Args, OPT_fno_experimental_relative_cxx_abi_vtables, SA); + + for (const auto &MP : Opts.MacroPrefixMap) + GenerateArg(Args, OPT_fmacro_prefix_map_EQ, MP.first + "=" + MP.second, SA); } bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, @@ -4038,6 +4041,12 @@ options::OPT_fno_experimental_relative_cxx_abi_vtables, TargetCXXABI::usesRelativeVTables(T)); + for (const auto &A : Args.getAllArgValues(OPT_fmacro_prefix_map_EQ)) { + auto Split = StringRef(A).split('='); + Opts.MacroPrefixMap.insert( + {std::string(Split.first), std::string(Split.second)}); + } + return Diags.getNumErrors() == NumErrorsBefore; } @@ -4110,9 +4119,6 @@ for (const auto &D : Opts.DeserializedPCHDeclsToErrorOn) GenerateArg(Args, OPT_error_on_deserialized_pch_decl, D, SA); - for (const auto &MP : Opts.MacroPrefixMap) - GenerateArg(Args, OPT_fmacro_prefix_map_EQ, MP.first + "=" + MP.second, SA); - if (Opts.PrecompiledPreambleBytes != std::make_pair(0u, false)) GenerateArg(Args, OPT_preamble_bytes_EQ, Twine(Opts.PrecompiledPreambleBytes.first) + "," + @@ -4181,12 +4187,6 @@ for (const auto *A : Args.filtered(OPT_error_on_deserialized_pch_decl)) Opts.DeserializedPCHDeclsToErrorOn.insert(A->getValue()); - for (const auto &A : Args.getAllArgValues(OPT_fmacro_prefix_map_EQ)) { - auto Split = StringRef(A).split('='); - Opts.MacroPrefixMap.insert( - {std::string(Split.first), std::string(Split.second)}); - } - if (const Arg *A = Args.getLastArg(OPT_preamble_bytes_EQ)) { StringRef Value(A->getValue()); size_t Comma = Value.find(','); Index: clang/lib/Lex/PPMacroExpansion.cpp =================================================================== --- clang/lib/Lex/PPMacroExpansion.cpp +++ clang/lib/Lex/PPMacroExpansion.cpp @@ -1460,15 +1460,6 @@ return TI.getTriple().getEnvironment() == Env.getEnvironment(); } -static void remapMacroPath( - SmallString<256> &Path, - const std::map> - &MacroPrefixMap) { - for (const auto &Entry : MacroPrefixMap) - if (llvm::sys::path::replace_path_prefix(Path, Entry.first, Entry.second)) - break; -} - /// ExpandBuiltinMacro - If an identifier token is read that is to be expanded /// as a builtin macro, handle it and return the next token as 'Tok'. void Preprocessor::ExpandBuiltinMacro(Token &Tok) { @@ -1550,7 +1541,7 @@ } else { FN += PLoc.getFilename(); } - remapMacroPath(FN, PPOpts->MacroPrefixMap); + getLangOpts().remapPathPrefix(FN); Lexer::Stringify(FN); OS << '"' << FN << '"'; } Index: clang/test/CodeGenCXX/builtin-source-location.cpp =================================================================== --- clang/test/CodeGenCXX/builtin-source-location.cpp +++ clang/test/CodeGenCXX/builtin-source-location.cpp @@ -1,5 +1,13 @@ // RUN: %clang_cc1 -std=c++2a -fblocks %s -triple x86_64-unknown-unknown -emit-llvm -o %t.ll +// This needs to be performed before #line directives which alter filename +// RUN: %clang_cc1 -fmacro-prefix-map=%p=/UNLIKELY/PATH -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-PREFIX-MAP +// +// CHECK-PREFIX-MAP: /UNLIKELY/PATH{{/|\\\\}}builtin-source-location.cpp +void testRemap() { + const char *file = __builtin_FILE(); +} + #line 8 "builtin-source-location.cpp" struct source_location {