diff options
author | Igor Kudrin <ikudrin@accesssoftek.com> | 2019-03-01 09:22:42 +0000 |
---|---|---|
committer | Igor Kudrin <ikudrin@accesssoftek.com> | 2019-03-01 09:22:42 +0000 |
commit | a38432cefb08657ccaae51679dddb1ce4de096d0 (patch) | |
tree | 3ffbd166e5ea2670a8652e3af5656c3831c9f0f4 /llvm/lib/Support/CommandLine.cpp | |
parent | 875f05828d95251abe7c943d79399a3b1c80db12 (diff) | |
download | llvm-a38432cefb08657ccaae51679dddb1ce4de096d0.zip llvm-a38432cefb08657ccaae51679dddb1ce4de096d0.tar.gz llvm-a38432cefb08657ccaae51679dddb1ce4de096d0.tar.bz2 |
[CommandLine] Allow grouping options which can have values.
This patch allows all forms of values for options to be used at the end
of a group. With the fix, it is possible to follow the way GNU binutils
tools handle grouping options better. For example, the -j option can be
used with objdump in any of the following ways:
$ objdump -d -j .text a.o
$ objdump -d -j.text a.o
$ objdump -dj .text a.o
$ objdump -dj.text a.o
Differential Revision: https://reviews.llvm.org/D58711
llvm-svn: 355185
Diffstat (limited to 'llvm/lib/Support/CommandLine.cpp')
-rw-r--r-- | llvm/lib/Support/CommandLine.cpp | 45 |
1 files changed, 24 insertions, 21 deletions
diff --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp index 8b279ba..39991a8 100644 --- a/llvm/lib/Support/CommandLine.cpp +++ b/llvm/lib/Support/CommandLine.cpp @@ -600,7 +600,7 @@ static bool ProvidePositionalOption(Option *Handler, StringRef Arg, int i) { // Option predicates... static inline bool isGrouping(const Option *O) { - return O->getFormattingFlag() == cl::Grouping; + return O->getMiscFlags() & cl::Grouping; } static inline bool isPrefixedOrGrouping(const Option *O) { return isGrouping(O) || O->getFormattingFlag() == cl::Prefix || @@ -651,26 +651,29 @@ HandlePrefixedOrGroupedOption(StringRef &Arg, StringRef &Value, if (!PGOpt) return nullptr; - // If the option is a prefixed option, then the value is simply the - // rest of the name... so fall through to later processing, by - // setting up the argument name flags and value fields. - if (PGOpt->getFormattingFlag() == cl::Prefix || - PGOpt->getFormattingFlag() == cl::AlwaysPrefix) { - Value = Arg.substr(Length); + do { + StringRef MaybeValue = + (Length < Arg.size()) ? Arg.substr(Length) : StringRef(); Arg = Arg.substr(0, Length); assert(OptionsMap.count(Arg) && OptionsMap.find(Arg)->second == PGOpt); - return PGOpt; - } - // This must be a grouped option... handle them now. Grouping options can't - // have values. - assert(isGrouping(PGOpt) && "Broken getOptionPred!"); + // cl::Prefix options do not preserve '=' when used separately. + // The behavior for them with grouped options should be the same. + if (MaybeValue.empty() || PGOpt->getFormattingFlag() == cl::AlwaysPrefix || + (PGOpt->getFormattingFlag() == cl::Prefix && MaybeValue[0] != '=')) { + Value = MaybeValue; + return PGOpt; + } + + if (MaybeValue[0] == '=') { + Value = MaybeValue.substr(1); + return PGOpt; + } - do { - // Move current arg name out of Arg into OneArgName. - StringRef OneArgName = Arg.substr(0, Length); - Arg = Arg.substr(Length); + // This must be a grouped option. + assert(isGrouping(PGOpt) && "Broken getOptionPred!"); + // Grouping options inside a group can't have values. if (PGOpt->getValueExpectedFlag() == cl::ValueRequired) { ErrorParsing |= PGOpt->error("may not occur within a group!"); return nullptr; @@ -679,15 +682,15 @@ HandlePrefixedOrGroupedOption(StringRef &Arg, StringRef &Value, // Because the value for the option is not required, we don't need to pass // argc/argv in. int Dummy = 0; - ErrorParsing |= - ProvideOption(PGOpt, OneArgName, StringRef(), 0, nullptr, Dummy); + ErrorParsing |= ProvideOption(PGOpt, Arg, StringRef(), 0, nullptr, Dummy); // Get the next grouping option. + Arg = MaybeValue; PGOpt = getOptionPred(Arg, Length, isGrouping, OptionsMap); - } while (PGOpt && Length != Arg.size()); + } while (PGOpt); - // Return the last option with Arg cut down to just the last one. - return PGOpt; + // We could not find a grouping option in the remainder of Arg. + return nullptr; } static bool RequiresValue(const Option *O) { |