[llvm] r187537 - Option parsing: add support for alias arguments.
Michael Gottesman
mgottesman at apple.com
Fri Aug 2 13:07:34 PDT 2013
Yes you are correct.
I looked at the LLVM commits list instead of the Clang commits list = (.
Thanks for reverting/looking into this = ).
Michael
On Aug 1, 2013, at 6:36 PM, Hans Wennborg <hans at chromium.org> wrote:
> Did you mean r187637? I've reverted that.
>
>
> On Thu, Aug 1, 2013 at 6:26 PM, Michael Gottesman <mgottesman at apple.com> wrote:
>> 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
>>
>>
>>
>> _______________________________________________
>> 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/20130802/65c53b97/attachment.html>
More information about the llvm-commits
mailing list