Apply -fmacro-prefix-map to __builtin_FILE()

This matches the behavior of GCC.
Patch does not change remapping logic itself, so adding one simple smoke test should be enough.

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D107393
This commit is contained in:
Pavel Asyutchenko 2021-08-04 16:42:14 -07:00 committed by Fangrui Song
parent f135a91c72
commit 7df405e079
9 changed files with 41 additions and 28 deletions

View File

@ -367,6 +367,9 @@ public:
/// A list of all -fno-builtin-* function names (e.g., memset). /// A list of all -fno-builtin-* function names (e.g., memset).
std::vector<std::string> NoBuiltinFuncs; std::vector<std::string> NoBuiltinFuncs;
/// A prefix map for __FILE__, __BASE_FILE__ and __builtin_FILE().
std::map<std::string, std::string, std::greater<std::string>> MacroPrefixMap;
/// Triples of the OpenMP targets that the host code codegen should /// Triples of the OpenMP targets that the host code codegen should
/// take into account in order to generate accurate offloading descriptors. /// take into account in order to generate accurate offloading descriptors.
std::vector<llvm::Triple> OMPTargetTriples; std::vector<llvm::Triple> OMPTargetTriples;
@ -473,6 +476,9 @@ public:
} }
bool isSYCL() const { return SYCLIsDevice || SYCLIsHost; } 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 /// Floating point control options

View File

@ -2840,10 +2840,10 @@ def fcoverage_prefix_map_EQ
HelpText<"remap file source paths in coverage mapping">; HelpText<"remap file source paths in coverage mapping">;
def ffile_prefix_map_EQ def ffile_prefix_map_EQ
: Joined<["-"], "ffile-prefix-map=">, Group<f_Group>, : Joined<["-"], "ffile-prefix-map=">, Group<f_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 def fmacro_prefix_map_EQ
: Joined<["-"], "fmacro-prefix-map=">, Group<Preprocessor_Group>, Flags<[CC1Option]>, : Joined<["-"], "fmacro-prefix-map=">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"remap file source paths in predefined preprocessor macros">; HelpText<"remap file source paths in predefined preprocessor macros and __builtin_FILE()">;
defm force_dwarf_frame : BoolFOption<"force-dwarf-frame", defm force_dwarf_frame : BoolFOption<"force-dwarf-frame",
CodeGenOpts<"ForceDwarfFrameSection">, DefaultFalse, CodeGenOpts<"ForceDwarfFrameSection">, DefaultFalse,
PosFlag<SetTrue, [CC1Option], "Always emit a debug frame section">, NegFlag<SetFalse>>; PosFlag<SetTrue, [CC1Option], "Always emit a debug frame section">, NegFlag<SetFalse>>;

View File

@ -202,9 +202,6 @@ public:
/// build it again. /// build it again.
std::shared_ptr<FailedModulesSet> FailedModules; std::shared_ptr<FailedModulesSet> FailedModules;
/// A prefix map for __FILE__ and __BASE_FILE__.
std::map<std::string, std::string, std::greater<std::string>> MacroPrefixMap;
/// Contains the currently active skipped range mappings for skipping excluded /// Contains the currently active skipped range mappings for skipping excluded
/// conditional directives. /// conditional directives.
/// ///

View File

@ -2233,8 +2233,11 @@ APValue SourceLocExpr::EvaluateInContext(const ASTContext &Ctx,
}; };
switch (getIdentKind()) { switch (getIdentKind()) {
case SourceLocExpr::File: case SourceLocExpr::File: {
return MakeStringLiteral(PLoc.getFilename()); SmallString<256> Path(PLoc.getFilename());
Ctx.getLangOpts().remapPathPrefix(Path);
return MakeStringLiteral(Path);
}
case SourceLocExpr::Function: { case SourceLocExpr::Function: {
const Decl *CurDecl = dyn_cast_or_null<Decl>(Context); const Decl *CurDecl = dyn_cast_or_null<Decl>(Context);
return MakeStringLiteral( return MakeStringLiteral(

View File

@ -11,6 +11,8 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "clang/Basic/LangOptions.h" #include "clang/Basic/LangOptions.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Path.h"
using namespace clang; using namespace clang;
@ -48,6 +50,12 @@ VersionTuple LangOptions::getOpenCLVersionTuple() const {
return VersionTuple(Ver / 100, (Ver % 100) / 10); 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 FPOptions::defaultWithoutTrailingStorage(const LangOptions &LO) {
FPOptions result(LO); FPOptions result(LO);
return result; return result;

View File

@ -186,7 +186,7 @@ CodeGenModule::CodeGenModule(ASTContext &C, const HeaderSearchOptions &HSO,
!getModule().getSourceFileName().empty()) { !getModule().getSourceFileName().empty()) {
std::string Path = getModule().getSourceFileName(); std::string Path = getModule().getSourceFileName();
// Check if a path substitution is needed from the MacroPrefixMap. // 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) { if (Path.rfind(Entry.first, 0) != std::string::npos) {
Path = Entry.second + Path.substr(Entry.first.size()); Path = Entry.second + Path.substr(Entry.first.size());
break; break;

View File

@ -3526,6 +3526,9 @@ void CompilerInvocation::GenerateLangArgs(const LangOptions &Opts,
GenerateArg(Args, OPT_fexperimental_relative_cxx_abi_vtables, SA); GenerateArg(Args, OPT_fexperimental_relative_cxx_abi_vtables, SA);
else else
GenerateArg(Args, OPT_fno_experimental_relative_cxx_abi_vtables, SA); 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, bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
@ -4036,6 +4039,12 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
options::OPT_fno_experimental_relative_cxx_abi_vtables, options::OPT_fno_experimental_relative_cxx_abi_vtables,
TargetCXXABI::usesRelativeVTables(T)); 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; return Diags.getNumErrors() == NumErrorsBefore;
} }
@ -4108,9 +4117,6 @@ static void GeneratePreprocessorArgs(PreprocessorOptions &Opts,
for (const auto &D : Opts.DeserializedPCHDeclsToErrorOn) for (const auto &D : Opts.DeserializedPCHDeclsToErrorOn)
GenerateArg(Args, OPT_error_on_deserialized_pch_decl, D, SA); 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)) if (Opts.PrecompiledPreambleBytes != std::make_pair(0u, false))
GenerateArg(Args, OPT_preamble_bytes_EQ, GenerateArg(Args, OPT_preamble_bytes_EQ,
Twine(Opts.PrecompiledPreambleBytes.first) + "," + Twine(Opts.PrecompiledPreambleBytes.first) + "," +
@ -4179,12 +4185,6 @@ static bool ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
for (const auto *A : Args.filtered(OPT_error_on_deserialized_pch_decl)) for (const auto *A : Args.filtered(OPT_error_on_deserialized_pch_decl))
Opts.DeserializedPCHDeclsToErrorOn.insert(A->getValue()); 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)) { if (const Arg *A = Args.getLastArg(OPT_preamble_bytes_EQ)) {
StringRef Value(A->getValue()); StringRef Value(A->getValue());
size_t Comma = Value.find(','); size_t Comma = Value.find(',');

View File

@ -1460,15 +1460,6 @@ static bool isTargetEnvironment(const TargetInfo &TI,
return TI.getTriple().getEnvironment() == Env.getEnvironment(); return TI.getTriple().getEnvironment() == Env.getEnvironment();
} }
static void remapMacroPath(
SmallString<256> &Path,
const std::map<std::string, std::string, std::greater<std::string>>
&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 /// 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'. /// as a builtin macro, handle it and return the next token as 'Tok'.
void Preprocessor::ExpandBuiltinMacro(Token &Tok) { void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
@ -1550,7 +1541,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
} else { } else {
FN += PLoc.getFilename(); FN += PLoc.getFilename();
} }
remapMacroPath(FN, PPOpts->MacroPrefixMap); getLangOpts().remapPathPrefix(FN);
Lexer::Stringify(FN); Lexer::Stringify(FN);
OS << '"' << FN << '"'; OS << '"' << FN << '"';
} }

View File

@ -1,5 +1,13 @@
// RUN: %clang_cc1 -std=c++2a -fblocks %s -triple x86_64-unknown-unknown -emit-llvm -o %t.ll // 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" #line 8 "builtin-source-location.cpp"
struct source_location { struct source_location {