Skip to content

New option format for prefix mapping #10723

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 4 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
10 changes: 7 additions & 3 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -8836,11 +8836,15 @@ def fdepscan_include_tree : Flag<["-"], "fdepscan-include-tree">,
//
// FIXME: Add DepscanOption flag.
def fdepscan_prefix_map_EQ : Joined<["-"], "fdepscan-prefix-map=">,
Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
Group<f_Group>, Visibility<[ClangOption]>,
MetaVarName<"<old>=<new>">,
HelpText<"With -fdepscan, seamlessly filter the CAS filesystem to"
" apply the given prefix, updating the command-line to match.">,
MarshallingInfoStringVector<FrontendOpts<"PathPrefixMappings">>;
" apply the given prefix, updating the command-line to match.">;
def fdepscan_prefix_map : MultiArg<["-"], "fdepscan-prefix-map", 2>,
Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
MetaVarName<"<old> <new>">,
HelpText<"With -fdepscan, seamlessly filter the CAS filesystem to"
" apply the given prefix, updating the command-line to match.">;
def fdepscan_prefix_map_sdk_EQ :
Joined<["-"], "fdepscan-prefix-map-sdk=">,
Group<f_Group>, MetaVarName<"<new>">,
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Frontend/CompileJobCacheKey.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ struct CompileJobCachingOptions {
/// See \c FrontendOptions::WriteOutputAsCASID.
bool WriteOutputAsCASID;
/// See \c FrontendOptions::PathPrefixMappings.
std::vector<std::string> PathPrefixMappings;
std::vector<std::pair<std::string, std::string>> PathPrefixMappings;
};

/// Create a cache key for the given \c CompilerInvocation as a \c CASID. If \p
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Frontend/FrontendOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ class FrontendOptions {
/// When caching is enabled, represents remappings for all the file paths that
/// the compilation may access. This is useful for canonicalizing the
/// compilation for caching purposes.
std::vector<std::string> PathPrefixMappings;
std::vector<std::pair<std::string, std::string>> PathPrefixMappings;

// Currently this is only used as part of the `-extract-api` action.
// A comma separated list of files providing a list of APIs to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ struct DepscanPrefixMapping {
llvm::PrefixMapper &Mapper);

/// Add path mappings to the \p Mapper.
static void configurePrefixMapper(ArrayRef<std::string> PathPrefixMappings,
static void configurePrefixMapper(ArrayRef<std::pair<std::string, std::string>> PathPrefixMappings,
llvm::PrefixMapper &Mapper);

/// Apply the mappings from \p Mapper to \p Invocation.
Expand Down
28 changes: 19 additions & 9 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5059,8 +5059,9 @@ void Clang::AddPrefixMappingOptions(const ArgList &Args, ArgStringList &CmdArgs,

if (Arg *A = Args.getLastArg(options::OPT_fdepscan_prefix_map_sdk_EQ)) {
if (IsPathApplicableAsPrefix(Sysroot)) {
CmdArgs.push_back(Args.MakeArgString(Twine("-fdepscan-prefix-map=") +
*Sysroot + "=" + A->getValue()));
CmdArgs.push_back("-fdepscan-prefix-map");
CmdArgs.push_back(Args.MakeArgString(*Sysroot));
CmdArgs.push_back(Args.MakeArgString(A->getValue()));
} else {
// FIXME: warning if we cannot infer sdk
}
Expand All @@ -5075,22 +5076,31 @@ void Clang::AddPrefixMappingOptions(const ArgList &Args, ArgStringList &CmdArgs,
Guess = llvm::sys::path::parent_path(Guess);
}
if (IsPathApplicableAsPrefix(Guess)) {
CmdArgs.push_back(Args.MakeArgString(Twine("-fdepscan-prefix-map=") +
Guess + "=" + A->getValue()));
CmdArgs.push_back("-fdepscan-prefix-map");
CmdArgs.push_back(Args.MakeArgString(Guess));
CmdArgs.push_back(Args.MakeArgString(A->getValue()));
} else {
// FIXME: warning if we cannot infer toolchain
}
}

for (const Arg *A : Args.filtered(options::OPT_fdepscan_prefix_map_EQ)) {
for (const Arg *A : Args.filtered(options::OPT_fdepscan_prefix_map, options::OPT_fdepscan_prefix_map_EQ)) {
A->claim();
StringRef Map = A->getValue();
StringRef Prefix = Map.split('=').first;
if (Prefix.size() == Map.size() || !IsPathApplicableAsPrefix(Prefix)) {
StringRef Prefix, MapTarget;
if (A->getOption().matches(options::OPT_fdepscan_prefix_map_EQ)) {
StringRef Map = A->getValue();
std::tie(Prefix, MapTarget) = Map.split('=');
} else {
Prefix = A->getValue(0);
MapTarget = A->getValue(1);
}
if (MapTarget.size() == 0 || !IsPathApplicableAsPrefix(Prefix)) {
D.Diag(diag::err_drv_invalid_argument_to_option)
<< A->getValue() << A->getOption().getName();
} else {
A->render(Args, CmdArgs);
CmdArgs.push_back("-fdepscan-prefix-map");
CmdArgs.push_back(Args.MakeArgString(Prefix));
CmdArgs.push_back(Args.MakeArgString(MapTarget));
}
}
}
Expand Down
5 changes: 2 additions & 3 deletions clang/lib/Frontend/CompileJobCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,8 +330,7 @@ std::optional<int> CompileJobCache::initialize(CompilerInstance &Clang) {

llvm::PrefixMapper PrefixMapper;
llvm::SmallVector<llvm::MappedPrefix> Split;
llvm::MappedPrefix::transformJoinedIfValid(CacheOpts.PathPrefixMappings,
Split);
llvm::MappedPrefix::transformPairs(CacheOpts.PathPrefixMappings, Split);
for (const auto &MappedPrefix : Split) {
// We use the inverse mapping because the \p PrefixMapper will be used for
// de-canonicalization of paths.
Expand Down Expand Up @@ -629,7 +628,7 @@ Expected<std::optional<int>> CompileJobCache::replayCachedResult(

llvm::PrefixMapper PrefixMapper;
llvm::SmallVector<llvm::MappedPrefix> Split;
llvm::MappedPrefix::transformJoinedIfValid(
llvm::MappedPrefix::transformPairs(
Clang.getFrontendOpts().PathPrefixMappings, Split);
for (const auto &MappedPrefix : Split) {
// We use the inverse mapping because the \p PrefixMapper will be used for
Expand Down
11 changes: 11 additions & 0 deletions clang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PrefixMapper.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/VersionTuple.h"
Expand Down Expand Up @@ -3155,6 +3156,9 @@ static void GenerateFrontendArgs(const FrontendOptions &Opts,
for (const auto &A : Opts.ModuleCacheKeys)
GenerateMultiArg(Consumer, OPT_fmodule_file_cache_key, {A.first, A.second});

for (const auto &A : Opts.PathPrefixMappings)
GenerateMultiArg(Consumer, OPT_fdepscan_prefix_map, {A.first, A.second});

if (Opts.AuxTargetCPU)
GenerateArg(Consumer, OPT_aux_target_cpu, *Opts.AuxTargetCPU);

Expand Down Expand Up @@ -3381,6 +3385,13 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
Opts.ModuleCacheKeys.emplace_back(Values[0], Values[1]);
}

// Handle path prefix mappings
for (const Arg *A : Args.filtered(OPT_fdepscan_prefix_map)) {
ArrayRef<const char *> Values = A->getValues();
assert(Values.size() == 2);
Opts.PathPrefixMappings.emplace_back(Values[0], Values[1]);
}

if (Opts.ProgramAction != frontend::GenerateModule && Opts.IsSystemModule)
Diags.Report(diag::err_drv_argument_only_allowed_with) << "-fsystem-module"
<< "-emit-module";
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/Tooling/DependencyScanning/ScanAndUpdateArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ void DepscanPrefixMapping::remapInvocationPaths(CompilerInvocation &Invocation,
// Pass the remappings so that we can map cached diagnostics to the local
// paths during diagnostic rendering.
for (const llvm::MappedPrefix &Map : Mapper.getMappings()) {
FrontendOpts.PathPrefixMappings.push_back(Map.Old + "=" + Map.New);
FrontendOpts.PathPrefixMappings.emplace_back(Map.Old, Map.New);
}

auto mapInPlaceAll = [&](std::vector<std::string> &Vector) {
Expand Down Expand Up @@ -244,12 +244,12 @@ void DepscanPrefixMapping::configurePrefixMapper(const CompilerInvocation &CI,
}

void DepscanPrefixMapping::configurePrefixMapper(
ArrayRef<std::string> PathPrefixMappings, llvm::PrefixMapper &Mapper) {
ArrayRef<std::pair<std::string, std::string>> PathPrefixMappings, llvm::PrefixMapper &Mapper) {
if (PathPrefixMappings.empty())
return;

llvm::SmallVector<llvm::MappedPrefix> Split;
llvm::MappedPrefix::transformJoinedIfValid(PathPrefixMappings, Split);
llvm::MappedPrefix::transformPairs(PathPrefixMappings, Split);
for (auto &MappedPrefix : Split)
Mapper.add(MappedPrefix);

Expand Down
3 changes: 3 additions & 0 deletions llvm/include/llvm/Support/PrefixMapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Path.h"
#include <optional>
Expand Down Expand Up @@ -48,6 +49,8 @@ struct MappedPrefix {
SmallVectorImpl<MappedPrefix> &Split);
static void transformJoinedIfValid(ArrayRef<std::string> Joined,
SmallVectorImpl<MappedPrefix> &Split);
static void transformPairs(ArrayRef<std::pair<std::string, std::string>> Pairs,
SmallVectorImpl<MappedPrefix> & Split);
};

/// Remap path prefixes.
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/Support/PrefixMapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ void MappedPrefix::transformJoinedIfValid(
transformJoinedImpl</*StopOnInvalid*/ false>(Joined, Split);
}

void MappedPrefix::transformPairs(
ArrayRef<std::pair<std::string, std::string>> Pairs, SmallVectorImpl<MappedPrefix> &Split) {
for (auto &Pair : Pairs) {
Split.push_back(MappedPrefix{Pair.first, Pair.second});
}
}

/// FIXME: Copy/pasted from llvm/lib/Support/Path.cpp.
static bool startsWith(StringRef Path, StringRef Prefix,
sys::path::Style PathStyle) {
Expand Down
15 changes: 15 additions & 0 deletions llvm/unittests/Support/PrefixMapperTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,21 @@ TEST(MappedPrefixTest, transformJoinedIfValid) {
EXPECT_EQ(ArrayRef(ExpectedSplit), ArrayRef(ComputedSplit));
}

TEST(PrefixMapperTest, transformPairs) {
SmallVector<std::pair<std::string, std::string>> PrefixMappings = {
{"", ""}, {"a", "b"}, {"", "a"}, {"a", ""}, {"=a=b=", "=c=d==="}
};
MappedPrefix ExpectedSplit[] = {
MappedPrefix{"", ""}, MappedPrefix{"a", "b"},
MappedPrefix{"", "a"}, MappedPrefix{"a", ""},
MappedPrefix{"=a=b=", "=c=d==="},
};

SmallVector<MappedPrefix> ComputedSplit;
MappedPrefix::transformPairs(PrefixMappings, ComputedSplit);
EXPECT_EQ(ArrayRef(ExpectedSplit), ArrayRef(ComputedSplit));
}

TEST(PrefixMapperTest, construct) {
for (auto PathStyle : {
sys::path::Style::posix,
Expand Down