forked from OSchip/llvm-project
[clang][cli] Implement `getAllArgValues` marshalling
This infrastructure can be used ~30 more command line options. Reviewed By: dexonsmith Differential Revision: https://reviews.llvm.org/D93631
This commit is contained in:
parent
44e74c75e6
commit
63a24816f5
|
@ -1915,7 +1915,8 @@ def fsystem_module : Flag<["-"], "fsystem-module">, Flags<[CC1Option]>,
|
|||
MarshallingInfoFlag<"FrontendOpts.IsSystemModule">;
|
||||
def fmodule_map_file : Joined<["-"], "fmodule-map-file=">,
|
||||
Group<f_Group>, Flags<[NoXarchOption,CC1Option]>, MetaVarName<"<file>">,
|
||||
HelpText<"Load this module map file">;
|
||||
HelpText<"Load this module map file">,
|
||||
MarshallingInfoStringVector<"FrontendOpts.ModuleMapFiles">;
|
||||
def fmodule_file : Joined<["-"], "fmodule-file=">,
|
||||
Group<i_Group>, Flags<[NoXarchOption,CC1Option]>, MetaVarName<"[<name>=]<file>">,
|
||||
HelpText<"Specify the mapping of module name to precompiled module file, or load a module file if name is omitted.">;
|
||||
|
|
|
@ -323,6 +323,23 @@ static Optional<IntTy> normalizeStringIntegral(OptSpecifier Opt, int,
|
|||
return Res;
|
||||
}
|
||||
|
||||
static Optional<std::vector<std::string>>
|
||||
normalizeStringVector(OptSpecifier Opt, int, const ArgList &Args,
|
||||
DiagnosticsEngine &) {
|
||||
return Args.getAllArgValues(Opt);
|
||||
}
|
||||
|
||||
static void denormalizeStringVector(SmallVectorImpl<const char *> &Args,
|
||||
const char *Spelling,
|
||||
CompilerInvocation::StringAllocator SA,
|
||||
Option::OptionClass OptClass,
|
||||
unsigned TableIndex,
|
||||
const std::vector<std::string> &Values) {
|
||||
for (const std::string &Value : Values) {
|
||||
denormalizeString(Args, Spelling, SA, OptClass, TableIndex, Value);
|
||||
}
|
||||
}
|
||||
|
||||
static Optional<std::string> normalizeTriple(OptSpecifier Opt, int TableIndex,
|
||||
const ArgList &Args,
|
||||
DiagnosticsEngine &Diags) {
|
||||
|
@ -1715,7 +1732,6 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
|
|||
Opts.LLVMArgs = Args.getAllArgValues(OPT_mllvm);
|
||||
Opts.ASTDumpDecls = Args.hasArg(OPT_ast_dump, OPT_ast_dump_EQ);
|
||||
Opts.ASTDumpAll = Args.hasArg(OPT_ast_dump_all, OPT_ast_dump_all_EQ);
|
||||
Opts.ModuleMapFiles = Args.getAllArgValues(OPT_fmodule_map_file);
|
||||
// Only the -fmodule-file=<file> form.
|
||||
for (const auto *A : Args.filtered(OPT_fmodule_file)) {
|
||||
StringRef Val = A->getValue();
|
||||
|
|
|
@ -18,6 +18,7 @@ using namespace llvm;
|
|||
using namespace clang;
|
||||
|
||||
using ::testing::Contains;
|
||||
using ::testing::HasSubstr;
|
||||
using ::testing::StrEq;
|
||||
|
||||
namespace {
|
||||
|
@ -408,6 +409,45 @@ TEST_F(CommandLineTest, JoinedEnumDefault) {
|
|||
ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("legacy"))));
|
||||
}
|
||||
|
||||
TEST_F(CommandLineTest, StringVectorEmpty) {
|
||||
const char *Args[] = {""};
|
||||
|
||||
CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags);
|
||||
|
||||
ASSERT_FALSE(Diags->hasErrorOccurred());
|
||||
ASSERT_TRUE(Invocation.getFrontendOpts().ModuleMapFiles.empty());
|
||||
|
||||
Invocation.generateCC1CommandLine(GeneratedArgs, *this);
|
||||
ASSERT_THAT(GeneratedArgs, Not(Contains(HasSubstr("-fmodule-map-file="))));
|
||||
}
|
||||
|
||||
TEST_F(CommandLineTest, StringVectorSingle) {
|
||||
const char *Args[] = {"-fmodule-map-file=a"};
|
||||
|
||||
CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags);
|
||||
|
||||
ASSERT_FALSE(Diags->hasErrorOccurred());
|
||||
ASSERT_EQ(Invocation.getFrontendOpts().ModuleMapFiles,
|
||||
std::vector<std::string>({"a"}));
|
||||
|
||||
Invocation.generateCC1CommandLine(GeneratedArgs, *this);
|
||||
ASSERT_EQ(count(GeneratedArgs, StringRef("-fmodule-map-file=a")), 1);
|
||||
}
|
||||
|
||||
TEST_F(CommandLineTest, StringVectorMultiple) {
|
||||
const char *Args[] = {"-fmodule-map-file=a", "-fmodule-map-file=b"};
|
||||
|
||||
CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags);
|
||||
|
||||
ASSERT_FALSE(Diags->hasErrorOccurred());
|
||||
ASSERT_TRUE(Invocation.getFrontendOpts().ModuleMapFiles ==
|
||||
std::vector<std::string>({"a", "b"}));
|
||||
|
||||
Invocation.generateCC1CommandLine(GeneratedArgs, *this);
|
||||
ASSERT_EQ(count(GeneratedArgs, StringRef("-fmodule-map-file=a")), 1);
|
||||
ASSERT_EQ(count(GeneratedArgs, StringRef("-fmodule-map-file=b")), 1);
|
||||
}
|
||||
|
||||
// Tree of boolean options that can be (directly or transitively) implied by
|
||||
// their parent:
|
||||
//
|
||||
|
|
|
@ -167,6 +167,12 @@ class MarshallingInfoStringInt<code keypath, code defaultvalue="0", code type="u
|
|||
code Denormalizer = "denormalizeString";
|
||||
}
|
||||
|
||||
class MarshallingInfoStringVector<code keypath>
|
||||
: MarshallingInfo<keypath, "std::vector<std::string>({})"> {
|
||||
code Normalizer = "normalizeStringVector";
|
||||
code Denormalizer = "denormalizeStringVector";
|
||||
}
|
||||
|
||||
class MarshallingInfoFlag<code keypath, code defaultvalue = "false">
|
||||
: MarshallingInfo<keypath, defaultvalue> {
|
||||
code Normalizer = "normalizeSimpleFlag";
|
||||
|
|
Loading…
Reference in New Issue