[llvm] r187537 - Option parsing: add support for alias arguments.
Michael Gottesman
mgottesman at apple.com
Thu Aug 1 18:26:35 PDT 2013
This breaks the phase 1 llvmlab bot.
Can you fix or revert?
http://lab.llvm.org:8013/builders/phase1%20-%20sanity/builds/9735
Michael
On Jul 31, 2013, at 3:44 PM, Hans Wennborg <hans at hanshq.net> wrote:
> Author: hans
> Date: Wed Jul 31 17:44:41 2013
> New Revision: 187537
>
> URL: http://llvm.org/viewvc/llvm-project?rev=187537&view=rev
> Log:
> Option parsing: add support for alias arguments.
>
> This makes option aliases more powerful by enabling them to
> pass along arguments to the option they're aliasing.
>
> For example, if we have a joined option "-foo=", we can now
> specify a flag option "-bar" to be an alias of that, with the
> argument "baz".
>
> This is especially useful for the cl.exe compatible clang driver,
> where many options are aliases. For example, this patch enables
> us to alias "/Ox" to "-O3" (-O is a joined option), and "/WX" to
> "-Werror" (again, -W is a joined option).
>
> Differential Revision: http://llvm-reviews.chandlerc.com/D1245
>
> Modified:
> llvm/trunk/include/llvm/Option/OptParser.td
> llvm/trunk/include/llvm/Option/OptTable.h
> llvm/trunk/include/llvm/Option/Option.h
> llvm/trunk/lib/Option/Option.cpp
> llvm/trunk/unittests/Option/OptionParsingTest.cpp
> llvm/trunk/unittests/Option/Opts.td
> llvm/trunk/utils/TableGen/OptParserEmitter.cpp
>
> Modified: llvm/trunk/include/llvm/Option/OptParser.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Option/OptParser.td?rev=187537&r1=187536&r2=187537&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Option/OptParser.td (original)
> +++ llvm/trunk/include/llvm/Option/OptParser.td Wed Jul 31 17:44:41 2013
> @@ -89,6 +89,7 @@ class Option<list<string> prefixes, stri
> list<OptionFlag> Flags = [];
> OptionGroup Group = ?;
> Option Alias = ?;
> + list<string> AliasArgs = [];
> }
>
> // Helpers for defining options.
> @@ -113,6 +114,7 @@ class JoinedAndSeparate<list<string> pre
> // Mix-ins for adding optional attributes.
>
> class Alias<Option alias> { Option Alias = alias; }
> +class AliasArgs<list<string> aliasargs> { list<string> AliasArgs = aliasargs; }
> class EnumName<string name> { string EnumName = name; }
> class Flags<list<OptionFlag> flags> { list<OptionFlag> Flags = flags; }
> class Group<OptionGroup group> { OptionGroup Group = group; }
>
> Modified: llvm/trunk/include/llvm/Option/OptTable.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Option/OptTable.h?rev=187537&r1=187536&r2=187537&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Option/OptTable.h (original)
> +++ llvm/trunk/include/llvm/Option/OptTable.h Wed Jul 31 17:44:41 2013
> @@ -44,6 +44,7 @@ public:
> unsigned short Flags;
> unsigned short GroupID;
> unsigned short AliasID;
> + const char *AliasArgs;
> };
>
> private:
>
> Modified: llvm/trunk/include/llvm/Option/Option.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Option/Option.h?rev=187537&r1=187536&r2=187537&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Option/Option.h (original)
> +++ llvm/trunk/include/llvm/Option/Option.h Wed Jul 31 17:44:41 2013
> @@ -103,6 +103,16 @@ public:
> return Owner->getOption(Info->AliasID);
> }
>
> + /// \brief Get the alias arguments as a \0 separated list.
> + /// E.g. ["foo", "bar"] would be returned as "foo\0bar\0".
> + const char *getAliasArgs() const {
> + assert(Info && "Must have a valid info!");
> + assert((!Info->AliasArgs || Info->AliasArgs[0] != 0) &&
> + "AliasArgs should be either 0 or non-empty.");
> +
> + return Info->AliasArgs;
> + }
> +
> /// \brief Get the default prefix for this option.
> StringRef getPrefix() const {
> const char *Prefix = *Info->Prefixes;
>
> Modified: llvm/trunk/lib/Option/Option.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Option/Option.cpp?rev=187537&r1=187536&r2=187537&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Option/Option.cpp (original)
> +++ llvm/trunk/lib/Option/Option.cpp Wed Jul 31 17:44:41 2013
> @@ -26,6 +26,13 @@ Option::Option(const OptTable::Info *inf
> // tracking, it is not an inherent limitation.
> assert((!Info || !getAlias().isValid() || !getAlias().getAlias().isValid()) &&
> "Multi-level aliases are not supported.");
> +
> + if (Info && getAliasArgs()) {
> + assert(getAlias().isValid() && "Only alias options can have alias args.");
> + assert(getKind() == FlagClass && "Only Flag aliases can have alias args.");
> + assert(getAlias().getKind() != FlagClass &&
> + "Cannot provide alias args to a flag option.");
> + }
> }
>
> Option::~Option() {
> @@ -106,11 +113,22 @@ Arg *Option::accept(const ArgList &Args,
> }
>
> switch (getKind()) {
> - case FlagClass:
> + case FlagClass: {
> if (ArgSize != strlen(Args.getArgString(Index)))
> return 0;
>
> - return new Arg(UnaliasedOption, Spelling, Index++);
> + Arg *A = new Arg(UnaliasedOption, Spelling, Index++);
> + if (getAliasArgs()) {
> + const char *Val = getAliasArgs();
> + while (*Val != '\0') {
> + A->getValues().push_back(Val);
> +
> + // Move past the '\0' to the next argument.
> + Val += strlen(Val) + 1;
> + }
> + }
> + return A;
> + }
> case JoinedClass: {
> const char *Value = Args.getArgString(Index) + ArgSize;
> return new Arg(UnaliasedOption, Spelling, Index++, Value);
>
> Modified: llvm/trunk/unittests/Option/OptionParsingTest.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Option/OptionParsingTest.cpp?rev=187537&r1=187536&r2=187537&view=diff
> ==============================================================================
> --- llvm/trunk/unittests/Option/OptionParsingTest.cpp (original)
> +++ llvm/trunk/unittests/Option/OptionParsingTest.cpp Wed Jul 31 17:44:41 2013
> @@ -17,9 +17,11 @@
> using namespace llvm;
> using namespace llvm::opt;
>
> +#define SUPPORT_ALIASARGS // FIXME: Remove when no longer necessary.
> +
> enum ID {
> OPT_INVALID = 0, // This is not an option ID.
> -#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
> +#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
> HELPTEXT, METAVAR) OPT_##ID,
> #include "Opts.inc"
> LastOption
> @@ -37,10 +39,10 @@ enum OptionFlags {
> };
>
> static const OptTable::Info InfoTable[] = {
> -#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
> +#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
> HELPTEXT, METAVAR) \
> { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, PARAM, \
> - FLAGS, OPT_##GROUP, OPT_##ALIAS },
> + FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS },
> #include "Opts.inc"
> #undef OPTION
> };
> @@ -145,3 +147,14 @@ TEST(Option, ParseAliasInGroup) {
> OwningPtr<InputArgList> AL(T.ParseArgs(MyArgs, array_endof(MyArgs), MAI, MAC));
> EXPECT_TRUE(AL->hasArg(OPT_H));
> }
> +
> +TEST(Option, AliasArgs) {
> + TestOptTable T;
> + unsigned MAI, MAC;
> +
> + const char *MyArgs[] = { "-J", "-Joo" };
> + OwningPtr<InputArgList> AL(T.ParseArgs(MyArgs, array_endof(MyArgs), MAI, MAC));
> + EXPECT_TRUE(AL->hasArg(OPT_B));
> + EXPECT_EQ(AL->getAllArgValues(OPT_B)[0], "foo");
> + EXPECT_EQ(AL->getAllArgValues(OPT_B)[1], "bar");
> +}
>
> Modified: llvm/trunk/unittests/Option/Opts.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Option/Opts.td?rev=187537&r1=187536&r2=187537&view=diff
> ==============================================================================
> --- llvm/trunk/unittests/Option/Opts.td (original)
> +++ llvm/trunk/unittests/Option/Opts.td Wed Jul 31 17:44:41 2013
> @@ -19,3 +19,6 @@ def H : Flag<["-"], "H">, Flags<[HelpHid
>
> def my_group : OptionGroup<"my group">;
> def I : Flag<["-"], "I">, Alias<H>, Group<my_group>;
> +
> +def J : Flag<["-"], "J">, Alias<B>, AliasArgs<["foo"]>;
> +def Joo : Flag<["-"], "Joo">, Alias<B>, AliasArgs<["bar"]>;
>
> Modified: llvm/trunk/utils/TableGen/OptParserEmitter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/OptParserEmitter.cpp?rev=187537&r1=187536&r2=187537&view=diff
> ==============================================================================
> --- llvm/trunk/utils/TableGen/OptParserEmitter.cpp (original)
> +++ llvm/trunk/utils/TableGen/OptParserEmitter.cpp Wed Jul 31 17:44:41 2013
> @@ -152,11 +152,22 @@ void EmitOptParser(RecordKeeper &Records
> OS << "/////////\n";
> OS << "// Groups\n\n";
> OS << "#ifdef OPTION\n";
> +
> + // FIXME: Remove when option parsing clients are updated.
> + OS << "#ifdef SUPPORT_ALIASARGS\n";
> + OS << "#define OPTIONX OPTION\n";
> + OS << "#else\n";
> + OS << "#define OPTIONX(prefix, name, id, kind, group, alias, aliasargs, "
> + << "flags, param, helptext, metavar) "
> + << "OPTION(prefix, name, id, kind, "
> + << "group, alias, flags, param, helptext, metavar)\n";
> + OS << "#endif\n";
> +
> for (unsigned i = 0, e = Groups.size(); i != e; ++i) {
> const Record &R = *Groups[i];
>
> // Start a single option entry.
> - OS << "OPTION(";
> + OS << "OPTIONX(";
>
> // The option prefix;
> OS << "0";
> @@ -178,7 +189,7 @@ void EmitOptParser(RecordKeeper &Records
> OS << "INVALID";
>
> // The other option arguments (unused for groups).
> - OS << ", INVALID, 0, 0";
> + OS << ", INVALID, 0, 0, 0";
>
> // The option help text.
> if (!isa<UnsetInit>(R.getValueInit("HelpText"))) {
> @@ -199,7 +210,7 @@ void EmitOptParser(RecordKeeper &Records
> const Record &R = *Opts[i];
>
> // Start a single option entry.
> - OS << "OPTION(";
> + OS << "OPTIONX(";
>
> // The option prefix;
> std::vector<std::string> prf = R.getValueAsListOfStrings("Prefixes");
> @@ -228,6 +239,21 @@ void EmitOptParser(RecordKeeper &Records
> else
> OS << "INVALID";
>
> + // The option alias arguments (if any).
> + // Emitted as a \0 separated list in a string, e.g. ["foo", "bar"]
> + // would become "foo\0bar\0". Note that the compiler adds an implicit
> + // terminating \0 at the end.
> + OS << ", ";
> + std::vector<std::string> AliasArgs = R.getValueAsListOfStrings("AliasArgs");
> + if (AliasArgs.size() == 0) {
> + OS << "0";
> + } else {
> + OS << "\"";
> + for (size_t i = 0, e = AliasArgs.size(); i != e; ++i)
> + OS << AliasArgs[i] << "\\0";
> + OS << "\"";
> + }
> +
> // The option flags.
> const ListInit *LI = R.getValueAsListInit("Flags");
> if (LI->empty()) {
> @@ -261,6 +287,7 @@ void EmitOptParser(RecordKeeper &Records
>
> OS << ")\n";
> }
> + OS << "#undef OPTIONX\n"; // FIXME: Remove when option clients are updated.
> OS << "#endif\n";
> }
> } // end namespace llvm
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130801/5208021f/attachment.html>
More information about the llvm-commits
mailing list