diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h --- a/clang/include/clang/Basic/LangOptions.h +++ b/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 diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2840,10 +2840,10 @@ HelpText<"remap file source paths in coverage mapping">; def ffile_prefix_map_EQ : Joined<["-"], "ffile-prefix-map=">, Group, - HelpText<"remap file source paths in debug info and predefined preprocessor macros">; + HelpText<"remap file source paths in debug info, predefined preprocessor macros and __builtin_FILE()">; def fmacro_prefix_map_EQ - : Joined<["-"], "fmacro-prefix-map=">, Group, Flags<[CC1Option]>, - HelpText<"remap file source paths in predefined preprocessor macros">; + : Joined<["-"], "fmacro-prefix-map=">, Group, Flags<[CC1Option]>, + HelpText<"remap file source paths in predefined preprocessor macros and __builtin_FILE()">; defm force_dwarf_frame : BoolFOption<"force-dwarf-frame", CodeGenOpts<"ForceDwarfFrameSection">, DefaultFalse, PosFlag, NegFlag>; diff --git a/clang/include/clang/Lex/PreprocessorOptions.h b/clang/include/clang/Lex/PreprocessorOptions.h --- a/clang/include/clang/Lex/PreprocessorOptions.h +++ b/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. /// diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp --- a/clang/lib/AST/Expr.cpp +++ b/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( diff --git a/clang/lib/Basic/LangOptions.cpp b/clang/lib/Basic/LangOptions.cpp --- a/clang/lib/Basic/LangOptions.cpp +++ b/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; diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/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; diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -3526,6 +3526,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, @@ -4036,6 +4039,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; } @@ -4108,9 +4117,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) + "," + @@ -4179,12 +4185,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(','); diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/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 << '"'; } diff --git a/clang/test/CodeGenCXX/builtin-source-location.cpp b/clang/test/CodeGenCXX/builtin-source-location.cpp --- a/clang/test/CodeGenCXX/builtin-source-location.cpp +++ b/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 {