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 2 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
8 changes: 6 additions & 2 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -8839,8 +8839,12 @@ def fdepscan_prefix_map_EQ : Joined<["-"], "fdepscan-prefix-map=">,
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.">,
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
12 changes: 12 additions & 0 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5093,6 +5093,18 @@ void Clang::AddPrefixMappingOptions(const ArgList &Args, ArgStringList &CmdArgs,
A->render(Args, CmdArgs);
}
}

for (const Arg *A : Args.filtered(options::OPT_fdepscan_prefix_map)) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should make a single loop that handles both OPT_fdepscan_prefix_map and OPT_fdepscan_prefix_map_EQ so that the order is preserved with either spelling.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I implemented this in my recent commit, could you please check that? 😄

A->claim();
StringRef Prefix = A->getValue(0);
StringRef 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);
}
}
}

static void addCachingOptions(ArgStringList &CmdArgs) {
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
17 changes: 17 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,19 @@ 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]);
}
for (const Arg *A : Args.filtered(OPT_fdepscan_prefix_map_EQ)) {
StringRef Val = A->getValue();
if (std::optional<llvm::MappedPrefix> mapping = llvm::MappedPrefix::getFromJoined(Val)) {
Opts.PathPrefixMappings.emplace_back(mapping->Old, mapping->New);
}
}

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