[PATCH] Options: Add new option kind that consumes remaining arguments
Hans Wennborg
hans at chromium.org
Tue Aug 13 13:43:47 PDT 2013
Hi rnk,
This adds KIND_REMAINING_ARGS, a class of options that consume all remaining arguments on the command line.
This will be used to support /link in clang-cl, which is used to forward all remaining arguments to the linker.
It also allows us to remove the hard-coded handling of "--", allowing clients (clang and lld) to implement that functionality themselves with this new option class.
Please take a look!
http://llvm-reviews.chandlerc.com/D1387
Files:
include/llvm/Option/OptParser.td
include/llvm/Option/Option.h
lib/Option/OptTable.cpp
lib/Option/Option.cpp
unittests/Option/OptionParsingTest.cpp
unittests/Option/Opts.td
Index: include/llvm/Option/OptParser.td
===================================================================
--- include/llvm/Option/OptParser.td
+++ include/llvm/Option/OptParser.td
@@ -44,6 +44,8 @@
// An option which is both joined to its (first) value, and followed by its
// (second) value.
def KIND_JOINED_AND_SEPARATE : OptionKind<"JoinedAndSeparate">;
+// An option which consumes all remaining arguments if there are any.
+def KIND_REMAINING_ARGS : OptionKind<"RemainingArgs">;
// Define the option flags.
Index: include/llvm/Option/Option.h
===================================================================
--- include/llvm/Option/Option.h
+++ include/llvm/Option/Option.h
@@ -50,6 +50,7 @@
FlagClass,
JoinedClass,
SeparateClass,
+ RemainingArgsClass,
CommaJoinedClass,
MultiArgClass,
JoinedOrSeparateClass,
@@ -149,6 +150,7 @@
case SeparateClass:
case MultiArgClass:
case JoinedOrSeparateClass:
+ case RemainingArgsClass:
return RenderSeparateStyle;
}
llvm_unreachable("Unexpected kind!");
Index: lib/Option/OptTable.cpp
===================================================================
--- lib/Option/OptTable.cpp
+++ lib/Option/OptTable.cpp
@@ -259,6 +259,8 @@
continue;
}
+ // FIXME: Remove once clients are updated to use a KIND_REMAINING_ARGS
+ // option to handle this explicitly instead.
if (Str == "--") {
// Everything after -- is a filename.
++Index;
@@ -308,6 +310,7 @@
break;
case Option::SeparateClass: case Option::JoinedOrSeparateClass:
+ case Option::RemainingArgsClass:
Name += ' ';
// FALLTHROUGH
case Option::JoinedClass: case Option::CommaJoinedClass:
Index: lib/Option/Option.cpp
===================================================================
--- lib/Option/Option.cpp
+++ lib/Option/Option.cpp
@@ -52,6 +52,7 @@
P(MultiArgClass);
P(JoinedOrSeparateClass);
P(JoinedAndSeparateClass);
+ P(RemainingArgsClass);
#undef P
}
@@ -214,6 +215,16 @@
return new Arg(UnaliasedOption, Spelling, Index - 2,
Args.getArgString(Index - 2) + ArgSize,
Args.getArgString(Index - 1));
+ case RemainingArgsClass: {
+ // Matches iff this is an exact match.
+ // FIXME: Avoid strlen.
+ if (ArgSize != strlen(Args.getArgString(Index)))
+ return 0;
+ Arg *A = new Arg(UnaliasedOption, Spelling, Index++);
+ while (Index < Args.getNumInputArgStrings())
+ A->getValues().push_back(Args.getArgString(Index++));
+ return A;
+ }
default:
llvm_unreachable("Invalid option kind!");
}
Index: unittests/Option/OptionParsingTest.cpp
===================================================================
--- unittests/Option/OptionParsingTest.cpp
+++ unittests/Option/OptionParsingTest.cpp
@@ -169,3 +169,30 @@
EXPECT_EQ(AL->getAllArgValues(OPT_INPUT)[0], "-B");
EXPECT_EQ(AL->getAllArgValues(OPT_INPUT)[1], "--");
}
+
+TEST(Option, SlurpEmpty) {
+ TestOptTable T;
+ unsigned MAI, MAC;
+
+ const char *MyArgs[] = { "-A", "-slurp" };
+ OwningPtr<InputArgList> AL(T.ParseArgs(MyArgs, array_endof(MyArgs), MAI, MAC));
+ EXPECT_TRUE(AL->hasArg(OPT_A));
+ EXPECT_TRUE(AL->hasArg(OPT_Slurp));
+ EXPECT_EQ(AL->getAllArgValues(OPT_Slurp).size(), 0);
+}
+
+TEST(Option, Slurp) {
+ TestOptTable T;
+ unsigned MAI, MAC;
+
+ const char *MyArgs[] = { "-A", "-slurp", "-B", "--", "foo" };
+ OwningPtr<InputArgList> AL(T.ParseArgs(MyArgs, array_endof(MyArgs), MAI, MAC));
+ EXPECT_EQ(AL->size(), 2U);
+ EXPECT_TRUE(AL->hasArg(OPT_A));
+ EXPECT_FALSE(AL->hasArg(OPT_B));
+ EXPECT_TRUE(AL->hasArg(OPT_Slurp));
+ EXPECT_EQ(AL->getAllArgValues(OPT_Slurp).size(), 3U);
+ EXPECT_EQ(AL->getAllArgValues(OPT_Slurp)[0], "-B");
+ EXPECT_EQ(AL->getAllArgValues(OPT_Slurp)[1], "--");
+ EXPECT_EQ(AL->getAllArgValues(OPT_Slurp)[2], "foo");
+}
Index: unittests/Option/Opts.td
===================================================================
--- unittests/Option/Opts.td
+++ unittests/Option/Opts.td
@@ -22,3 +22,5 @@
def J : Flag<["-"], "J">, Alias<B>, AliasArgs<["foo"]>;
def Joo : Flag<["-"], "Joo">, Alias<B>, AliasArgs<["bar"]>;
+
+def Slurp : Option<["-"], "slurp", KIND_REMAINING_ARGS>;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1387.1.patch
Type: text/x-patch
Size: 4248 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130813/4eb09f0f/attachment.bin>
More information about the llvm-commits
mailing list