Skip to content

Commit 63a2481

Browse files
committed
[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
1 parent 44e74c7 commit 63a2481

File tree

4 files changed

+65
-2
lines changed

4 files changed

+65
-2
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1915,7 +1915,8 @@ def fsystem_module : Flag<["-"], "fsystem-module">, Flags<[CC1Option]>,
19151915
MarshallingInfoFlag<"FrontendOpts.IsSystemModule">;
19161916
def fmodule_map_file : Joined<["-"], "fmodule-map-file=">,
19171917
Group<f_Group>, Flags<[NoXarchOption,CC1Option]>, MetaVarName<"<file>">,
1918-
HelpText<"Load this module map file">;
1918+
HelpText<"Load this module map file">,
1919+
MarshallingInfoStringVector<"FrontendOpts.ModuleMapFiles">;
19191920
def fmodule_file : Joined<["-"], "fmodule-file=">,
19201921
Group<i_Group>, Flags<[NoXarchOption,CC1Option]>, MetaVarName<"[<name>=]<file>">,
19211922
HelpText<"Specify the mapping of module name to precompiled module file, or load a module file if name is omitted.">;

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,23 @@ static Optional<IntTy> normalizeStringIntegral(OptSpecifier Opt, int,
323323
return Res;
324324
}
325325

326+
static Optional<std::vector<std::string>>
327+
normalizeStringVector(OptSpecifier Opt, int, const ArgList &Args,
328+
DiagnosticsEngine &) {
329+
return Args.getAllArgValues(Opt);
330+
}
331+
332+
static void denormalizeStringVector(SmallVectorImpl<const char *> &Args,
333+
const char *Spelling,
334+
CompilerInvocation::StringAllocator SA,
335+
Option::OptionClass OptClass,
336+
unsigned TableIndex,
337+
const std::vector<std::string> &Values) {
338+
for (const std::string &Value : Values) {
339+
denormalizeString(Args, Spelling, SA, OptClass, TableIndex, Value);
340+
}
341+
}
342+
326343
static Optional<std::string> normalizeTriple(OptSpecifier Opt, int TableIndex,
327344
const ArgList &Args,
328345
DiagnosticsEngine &Diags) {
@@ -1715,7 +1732,6 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
17151732
Opts.LLVMArgs = Args.getAllArgValues(OPT_mllvm);
17161733
Opts.ASTDumpDecls = Args.hasArg(OPT_ast_dump, OPT_ast_dump_EQ);
17171734
Opts.ASTDumpAll = Args.hasArg(OPT_ast_dump_all, OPT_ast_dump_all_EQ);
1718-
Opts.ModuleMapFiles = Args.getAllArgValues(OPT_fmodule_map_file);
17191735
// Only the -fmodule-file=<file> form.
17201736
for (const auto *A : Args.filtered(OPT_fmodule_file)) {
17211737
StringRef Val = A->getValue();

clang/unittests/Frontend/CompilerInvocationTest.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ using namespace llvm;
1818
using namespace clang;
1919

2020
using ::testing::Contains;
21+
using ::testing::HasSubstr;
2122
using ::testing::StrEq;
2223

2324
namespace {
@@ -408,6 +409,45 @@ TEST_F(CommandLineTest, JoinedEnumDefault) {
408409
ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("legacy"))));
409410
}
410411

412+
TEST_F(CommandLineTest, StringVectorEmpty) {
413+
const char *Args[] = {""};
414+
415+
CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags);
416+
417+
ASSERT_FALSE(Diags->hasErrorOccurred());
418+
ASSERT_TRUE(Invocation.getFrontendOpts().ModuleMapFiles.empty());
419+
420+
Invocation.generateCC1CommandLine(GeneratedArgs, *this);
421+
ASSERT_THAT(GeneratedArgs, Not(Contains(HasSubstr("-fmodule-map-file="))));
422+
}
423+
424+
TEST_F(CommandLineTest, StringVectorSingle) {
425+
const char *Args[] = {"-fmodule-map-file=a"};
426+
427+
CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags);
428+
429+
ASSERT_FALSE(Diags->hasErrorOccurred());
430+
ASSERT_EQ(Invocation.getFrontendOpts().ModuleMapFiles,
431+
std::vector<std::string>({"a"}));
432+
433+
Invocation.generateCC1CommandLine(GeneratedArgs, *this);
434+
ASSERT_EQ(count(GeneratedArgs, StringRef("-fmodule-map-file=a")), 1);
435+
}
436+
437+
TEST_F(CommandLineTest, StringVectorMultiple) {
438+
const char *Args[] = {"-fmodule-map-file=a", "-fmodule-map-file=b"};
439+
440+
CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags);
441+
442+
ASSERT_FALSE(Diags->hasErrorOccurred());
443+
ASSERT_TRUE(Invocation.getFrontendOpts().ModuleMapFiles ==
444+
std::vector<std::string>({"a", "b"}));
445+
446+
Invocation.generateCC1CommandLine(GeneratedArgs, *this);
447+
ASSERT_EQ(count(GeneratedArgs, StringRef("-fmodule-map-file=a")), 1);
448+
ASSERT_EQ(count(GeneratedArgs, StringRef("-fmodule-map-file=b")), 1);
449+
}
450+
411451
// Tree of boolean options that can be (directly or transitively) implied by
412452
// their parent:
413453
//

llvm/include/llvm/Option/OptParser.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,12 @@ class MarshallingInfoStringInt<code keypath, code defaultvalue="0", code type="u
167167
code Denormalizer = "denormalizeString";
168168
}
169169

170+
class MarshallingInfoStringVector<code keypath>
171+
: MarshallingInfo<keypath, "std::vector<std::string>({})"> {
172+
code Normalizer = "normalizeStringVector";
173+
code Denormalizer = "denormalizeStringVector";
174+
}
175+
170176
class MarshallingInfoFlag<code keypath, code defaultvalue = "false">
171177
: MarshallingInfo<keypath, defaultvalue> {
172178
code Normalizer = "normalizeSimpleFlag";

0 commit comments

Comments
 (0)