<div dir="ltr">If you can post the lines of code that define your option set, maybe I can see if anything stands out as obvious.</div><br><div class="gmail_quote"><div dir="ltr">On Mon, Oct 10, 2016 at 9:03 AM Alex L <<a href="mailto:arphaman@gmail.com">arphaman@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="gmail_msg"><div class="gmail_extra gmail_msg"><div class="gmail_quote gmail_msg">On 10 October 2016 at 16:56, Zachary Turner <span dir="ltr" class="gmail_msg"><<a href="mailto:zturner@google.com" class="gmail_msg" target="_blank">zturner@google.com</a>></span> wrote:<br class="gmail_msg"><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="gmail_msg">So here, `Sub` refers to the active SubCommand.  For example, if you typed "llvm-pdbdump raw <options>" then `Sub` will refer to the RawSubcommand.  There are two special subcommands, `TopLevelSubcommand` and `AllSubcommands`.  The former becomes the active subcommand when you type no options at all.  For example, if you were to run `llvm-pdbdump -foo" Then the active subcommand would be `TopLevelSubcommand`.  Since subcommands cannot be nested, `TopLevelSubcommand` is the only subcommand from which it is possible for other subcommands to be "children" of.  So the first part of the conditional is saying "Only print this if the user did not explicitly specify any subcommand".  The >2 comes from the fact that `TopLevelSubcommand` and `AllSubcommands` are builtin subcommands.  Even if someone does not define any subcommands for their tool, there will still be those two.  So the second check is equivalent to saying "If the user has explicitly defined at least 1 subcommand".</div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div></div></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_extra gmail_msg"><div class="gmail_quote gmail_msg"><div class="gmail_msg">Thanks for the explanation, that makes sense. I stumbled across this when I was investigating why the help didn't print out subcommands when I had less than 3 sub-commands in a private tool. Given this explanation it has to be some mistake in my code or my reasoning. I'll double-check my code.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Alex </div><div class="gmail_msg"> </div><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="m_-3955298781657401918HOEnZb gmail_msg"><div class="m_-3955298781657401918h5 gmail_msg"><br class="gmail_msg"><div class="gmail_quote gmail_msg"></div></div></div></blockquote></div></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_extra gmail_msg"><div class="gmail_quote gmail_msg"><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="m_-3955298781657401918HOEnZb gmail_msg"><div class="m_-3955298781657401918h5 gmail_msg"><div class="gmail_quote gmail_msg"><div dir="ltr" class="gmail_msg">On Mon, Oct 10, 2016 at 3:44 AM Alex L <<a href="mailto:arphaman@gmail.com" class="gmail_msg" target="_blank">arphaman@gmail.com</a>> wrote:<br class="gmail_msg"></div></div></div></div></blockquote></div></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_extra gmail_msg"><div class="gmail_quote gmail_msg"><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="m_-3955298781657401918HOEnZb gmail_msg"><div class="m_-3955298781657401918h5 gmail_msg"><div class="gmail_quote gmail_msg"><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg"><div class="gmail_extra m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg"><div class="gmail_quote m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">On 29 June 2016 at 22:48, Zachary Turner via llvm-commits <span dir="ltr" class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg"><<a href="mailto:llvm-commits@lists.llvm.org" class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg"><blockquote class="gmail_quote m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Author: zturner<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
Date: Wed Jun 29 16:48:26 2016<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
New Revision: 274171<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=274171&view=rev" rel="noreferrer" class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project?rev=274171&view=rev</a><br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
Log:<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
Resubmit "Update llvm command line parser to support subcommands."<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
This fixes an issue where occurrence counts would be unexpectedly<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
reset when parsing different parts of a command line multiple<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
times.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
**ORIGINAL COMMIT MESSAGE**<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
This allows command line tools to use syntaxes like the following:<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
      llvm-foo.exe command1 -o1 -o2<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
      llvm-foo.exe command2 -p1 -p2<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
Where command1 and command2 contain completely different sets of<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
valid options.  This is backwards compatible with previous uses<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
of llvm cl which did not support subcommands, as any option<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
which specifies no optional subcommand (e.g. all existing<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
code) goes into a special "top level" subcommand that expects<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
dashed options to appear immediately after the program name.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
For example, code which is subcommand unaware would generate<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
a command line such as the following, where no subcommand<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
is specified:<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
      llvm-foo.exe -q1 -q2<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
The top level subcommand can co-exist with actual subcommands,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
as it is implemented as an actual subcommand which is searched<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
if no explicit subcommand is specified.  So llvm-foo.exe as<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
specified above could be written so as to support all three<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
aforementioned command lines simultaneously.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
There is one additional "special" subcommand called AllSubCommands,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
which can be used to inject an option into every subcommand.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
This is useful to support things like help, so that commands<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
such as:<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
      llvm-foo.exe --help<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
      llvm-foo.exe command1 --help<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
      llvm-foo.exe command2 --help<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
All work and display the help for the selected subcommand<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
without having to explicitly go and write code to handle each<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
one separately.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
This patch is submitted without an example of anything actually<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
using subcommands, but a followup patch will convert the<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
llvm-pdbdump tool to use subcommands.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
Reviewed By: beanz<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
Modified:<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
    llvm/trunk/include/llvm/Support/CommandLine.h<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
    llvm/trunk/lib/Support/CommandLine.cpp<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
    llvm/trunk/unittests/Support/CommandLineTest.cpp<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
    llvm/trunk/unittests/Support/ProgramTest.cpp<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
Modified: llvm/trunk/include/llvm/Support/CommandLine.h<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/CommandLine.h?rev=274171&r1=274170&r2=274171&view=diff" rel="noreferrer" class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/CommandLine.h?rev=274171&r1=274170&r2=274171&view=diff</a><br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
==============================================================================<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
--- llvm/trunk/include/llvm/Support/CommandLine.h (original)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+++ llvm/trunk/include/llvm/Support/CommandLine.h Wed Jun 29 16:48:26 2016<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -21,10 +21,12 @@<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 #define LLVM_SUPPORT_COMMANDLINE_H<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 #include "llvm/ADT/ArrayRef.h"<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+#include "llvm/ADT/SmallPtrSet.h"<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 #include "llvm/ADT/SmallVector.h"<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 #include "llvm/ADT/StringMap.h"<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 #include "llvm/ADT/Twine.h"<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 #include "llvm/Support/Compiler.h"<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+#include "llvm/Support/ManagedStatic.h"<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 #include <cassert><br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 #include <climits><br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 #include <cstdarg><br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -43,8 +45,9 @@ namespace cl {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 //===----------------------------------------------------------------------===//<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 // ParseCommandLineOptions - Command line option processing entry point.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 //<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-void ParseCommandLineOptions(int argc, const char *const *argv,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-                             const char *Overview = nullptr);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+bool ParseCommandLineOptions(int argc, const char *const *argv,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+                             const char *Overview = nullptr,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+                             bool IgnoreErrors = false);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 //===----------------------------------------------------------------------===//<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 // ParseEnvironmentOptions - Environment variable option processing alternate<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -171,6 +174,45 @@ public:<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 extern OptionCategory GeneralCategory;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 //===----------------------------------------------------------------------===//<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+// SubCommand class<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+//<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+class SubCommand {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+private:<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  const char *const Name = nullptr;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  const char *const Description = nullptr;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+protected:<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  void registerSubCommand();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  void unregisterSubCommand();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+public:<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  SubCommand(const char *const Name, const char *const Description = nullptr)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      : Name(Name), Description(Description) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    registerSubCommand();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  SubCommand() {}<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  void reset();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  operator bool() const;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  const char *getName() const { return Name; }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  const char *getDescription() const { return Description; }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  SmallVector<Option *, 4> PositionalOpts;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  SmallVector<Option *, 4> SinkOpts;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  StringMap<Option *> OptionsMap;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  Option *ConsumeAfterOpt = nullptr; // The ConsumeAfter option if it exists.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+};<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+// A special subcommand representing no subcommand<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+extern ManagedStatic<SubCommand> TopLevelSubCommand;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+// A special subcommand that can be used to put an option into all subcommands.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+extern ManagedStatic<SubCommand> AllSubCommands;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+//===----------------------------------------------------------------------===//<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 // Option Base class<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 //<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 class alias;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -209,6 +251,7 @@ public:<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   StringRef HelpStr;  // The descriptive text message for -help<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   StringRef ValueStr; // String describing what the value of this option is<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   OptionCategory *Category; // The Category this option belongs to<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  SmallPtrSet<SubCommand *, 4> Subs; // The subcommands this option belongs to.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   bool FullyInitialized;    // Has addArguemnt been called?<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   inline enum NumOccurrencesFlag getNumOccurrencesFlag() const {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -229,6 +272,16 @@ public:<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   // hasArgStr - Return true if the argstr != ""<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   bool hasArgStr() const { return !ArgStr.empty(); }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  bool isPositional() const { return getFormattingFlag() == cl::Positional; }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  bool isSink() const { return getMiscFlags() & cl::Sink; }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  bool isConsumeAfter() const {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    return getNumOccurrencesFlag() == cl::ConsumeAfter;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  bool isInAllSubCommands() const {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    return std::any_of(Subs.begin(), Subs.end(), [](const SubCommand *SC) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      return SC == &*AllSubCommands;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    });<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   //-------------------------------------------------------------------------===<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   // Accessor functions set by OptionModifiers<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -243,6 +296,7 @@ public:<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   void setMiscFlag(enum MiscFlags M) { Misc |= M; }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   void setPosition(unsigned pos) { Position = pos; }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   void setCategory(OptionCategory &C) { Category = &C; }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  void addSubCommand(SubCommand &S) { Subs.insert(&S); }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 protected:<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   explicit Option(enum NumOccurrencesFlag OccurrencesFlag,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -287,6 +341,7 @@ public:<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 public:<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   inline int getNumOccurrences() const { return NumOccurrences; }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  inline void reset() { NumOccurrences = 0; }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   virtual ~Option() {}<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 };<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -349,6 +404,14 @@ struct cat {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   template <class Opt> void apply(Opt &O) const { O.setCategory(Category); }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 };<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+// sub - Specify the subcommand that this option belongs to.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+struct sub {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  SubCommand &Sub;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  sub(SubCommand &S) : Sub(S) {}<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  template <class Opt> void apply(Opt &O) const { O.addSubCommand(Sub); }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+};<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 //===----------------------------------------------------------------------===//<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 // OptionValue class<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -1589,6 +1652,7 @@ class alias : public Option {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       error("cl::alias must have argument name specified!");<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     if (!AliasFor)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       error("cl::alias must have an cl::aliasopt(option) specified!");<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    Subs = AliasFor->Subs;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     addArgument();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -1669,7 +1733,7 @@ void PrintHelpMessage(bool Hidden = fals<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 /// Hopefully this API can be depricated soon. Any situation where options need<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 /// to be modified by tools or libraries should be handled by sane APIs rather<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 /// than just handing around a global list.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-StringMap<Option *> &getRegisteredOptions();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+StringMap<Option *> &getRegisteredOptions(SubCommand &Sub);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 //===----------------------------------------------------------------------===//<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 // Standalone command line processing utilities.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -1737,7 +1801,8 @@ bool ExpandResponseFiles(StringSaver &Sa<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 /// Some tools (like clang-format) like to be able to hide all options that are<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 /// not specific to the tool. This function allows a tool to specify a single<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 /// option category to display in the -help output.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-void HideUnrelatedOptions(cl::OptionCategory &Category);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+void HideUnrelatedOptions(cl::OptionCategory &Category,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+                          SubCommand &Sub = *TopLevelSubCommand);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 /// \brief Mark all options not part of the categories as cl::ReallyHidden.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 ///<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -1746,7 +1811,19 @@ void HideUnrelatedOptions(cl::OptionCate<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 /// Some tools (like clang-format) like to be able to hide all options that are<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 /// not specific to the tool. This function allows a tool to specify a single<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 /// option category to display in the -help output.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-void HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *> Categories);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+void HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *> Categories,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+                          SubCommand &Sub = *TopLevelSubCommand);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+/// \brief Reset all command line options to a state that looks as if they have<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+/// never appeared on the command line.  This is useful for being able to parse<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+/// a command line multiple times (especially useful for writing tests).<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+void ResetAllOptionOccurrences();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+/// \brief Reset the command line parser back to its initial state.  This<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+/// removes<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+/// all options, categories, and subcommands and returns the parser to a state<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+/// where no options are supported.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+void ResetCommandLineParser();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 } // End namespace cl<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
Modified: llvm/trunk/lib/Support/CommandLine.cpp<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CommandLine.cpp?rev=274171&r1=274170&r2=274171&view=diff" rel="noreferrer" class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CommandLine.cpp?rev=274171&r1=274170&r2=274171&view=diff</a><br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
==============================================================================<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
--- llvm/trunk/lib/Support/CommandLine.cpp (original)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+++ llvm/trunk/lib/Support/CommandLine.cpp Wed Jun 29 16:48:26 2016<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -19,6 +19,7 @@<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 #include "llvm/Support/CommandLine.h"<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 #include "llvm-c/Support.h"<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 #include "llvm/ADT/ArrayRef.h"<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+#include "llvm/ADT/DenseMap.h"<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 #include "llvm/ADT/STLExtras.h"<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 #include "llvm/ADT/SmallPtrSet.h"<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 #include "llvm/ADT/SmallString.h"<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -94,35 +95,56 @@ public:<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   // This collects additional help to be printed.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   std::vector<const char *> MoreHelp;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-  SmallVector<Option *, 4> PositionalOpts;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-  SmallVector<Option *, 4> SinkOpts;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-  StringMap<Option *> OptionsMap;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-  Option *ConsumeAfterOpt; // The ConsumeAfter option if it exists.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   // This collects the different option categories that have been registered.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   SmallPtrSet<OptionCategory *, 16> RegisteredOptionCategories;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-  CommandLineParser() : ProgramOverview(nullptr), ConsumeAfterOpt(nullptr) {}<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  // This collects the different subcommands that have been registered.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  SmallPtrSet<SubCommand *, 4> RegisteredSubCommands;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-  void ParseCommandLineOptions(int argc, const char *const *argv,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-                               const char *Overview);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  CommandLineParser() : ProgramOverview(nullptr), ActiveSubCommand(nullptr) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    registerSubCommand(&*TopLevelSubCommand);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    registerSubCommand(&*AllSubCommands);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-  void addLiteralOption(Option &Opt, const char *Name) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-    if (!Opt.hasArgStr()) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-      if (!OptionsMap.insert(std::make_pair(Name, &Opt)).second) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-        errs() << ProgramName << ": CommandLine Error: Option '" << Name<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-               << "' registered more than once!\n";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-        report_fatal_error("inconsistency in registered CommandLine options");<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  void ResetAllOptionOccurrences();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  bool ParseCommandLineOptions(int argc, const char *const *argv,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+                               const char *Overview, bool IgnoreErrors);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  void addLiteralOption(Option &Opt, SubCommand *SC, const char *Name) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    if (Opt.hasArgStr())<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      return;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    if (!SC->OptionsMap.insert(std::make_pair(Name, &Opt)).second) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      errs() << ProgramName << ": CommandLine Error: Option '" << Name<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+             << "' registered more than once!\n";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      report_fatal_error("inconsistency in registered CommandLine options");<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    // If we're adding this to all sub-commands, add it to the ones that have<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    // already been registered.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    if (SC == &*AllSubCommands) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      for (const auto &Sub : RegisteredSubCommands) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+        if (SC == Sub)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+          continue;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+        addLiteralOption(Opt, Sub, Name);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-  void addOption(Option *O) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  void addLiteralOption(Option &Opt, const char *Name) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    if (Opt.Subs.empty())<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      addLiteralOption(Opt, &*TopLevelSubCommand, Name);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    else {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      for (auto SC : Opt.Subs)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+        addLiteralOption(Opt, SC, Name);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  void addOption(Option *O, SubCommand *SC) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     bool HadErrors = false;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     if (O->hasArgStr()) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       // Add argument to the argument map!<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-      if (!OptionsMap.insert(std::make_pair(O->ArgStr, O)).second) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      if (!SC->OptionsMap.insert(std::make_pair(O->ArgStr, O)).second) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
         errs() << ProgramName << ": CommandLine Error: Option '" << O->ArgStr<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
                << "' registered more than once!\n";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
         HadErrors = true;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -131,15 +153,15 @@ public:<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     // Remember information about positional options.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     if (O->getFormattingFlag() == cl::Positional)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-      PositionalOpts.push_back(O);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      SC->PositionalOpts.push_back(O);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     else if (O->getMiscFlags() & cl::Sink) // Remember sink options<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-      SinkOpts.push_back(O);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      SC->SinkOpts.push_back(O);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     else if (O->getNumOccurrencesFlag() == cl::ConsumeAfter) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-      if (ConsumeAfterOpt) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      if (SC->ConsumeAfterOpt) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
         O->error("Cannot specify more than one option with cl::ConsumeAfter!");<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
         HadErrors = true;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-      ConsumeAfterOpt = O;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      SC->ConsumeAfterOpt = O;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     // Fail hard if there were errors. These are strictly unrecoverable and<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -148,47 +170,102 @@ public:<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     // linked LLVM distribution.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     if (HadErrors)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       report_fatal_error("inconsistency in registered CommandLine options");<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    // If we're adding this to all sub-commands, add it to the ones that have<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    // already been registered.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    if (SC == &*AllSubCommands) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      for (const auto &Sub : RegisteredSubCommands) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+        if (SC == Sub)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+          continue;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+        addOption(O, Sub);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-  void removeOption(Option *O) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  void addOption(Option *O) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    if (O->Subs.empty()) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      addOption(O, &*TopLevelSubCommand);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    } else {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      for (auto SC : O->Subs)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+        addOption(O, SC);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  void removeOption(Option *O, SubCommand *SC) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     SmallVector<StringRef, 16> OptionNames;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     O->getExtraOptionNames(OptionNames);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     if (O->hasArgStr())<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       OptionNames.push_back(O->ArgStr);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    SubCommand &Sub = *SC;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     for (auto Name : OptionNames)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-      OptionsMap.erase(Name);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      Sub.OptionsMap.erase(Name);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     if (O->getFormattingFlag() == cl::Positional)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-      for (auto Opt = PositionalOpts.begin(); Opt != PositionalOpts.end();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-           ++Opt) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      for (auto Opt = Sub.PositionalOpts.begin();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+           Opt != Sub.PositionalOpts.end(); ++Opt) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
         if (*Opt == O) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-          PositionalOpts.erase(Opt);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+          Sub.PositionalOpts.erase(Opt);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
           break;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
         }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     else if (O->getMiscFlags() & cl::Sink)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-      for (auto Opt = SinkOpts.begin(); Opt != SinkOpts.end(); ++Opt) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      for (auto Opt = Sub.SinkOpts.begin(); Opt != Sub.SinkOpts.end(); ++Opt) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
         if (*Opt == O) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-          SinkOpts.erase(Opt);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+          Sub.SinkOpts.erase(Opt);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
           break;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
         }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-    else if (O == ConsumeAfterOpt)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-      ConsumeAfterOpt = nullptr;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    else if (O == Sub.ConsumeAfterOpt)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      Sub.ConsumeAfterOpt = nullptr;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-  bool hasOptions() {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-    return (!OptionsMap.empty() || !PositionalOpts.empty() ||<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-            nullptr != ConsumeAfterOpt);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  void removeOption(Option *O) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    if (O->Subs.empty())<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      removeOption(O, &*TopLevelSubCommand);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    else {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      if (O->isInAllSubCommands()) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+        for (auto SC : RegisteredSubCommands)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+          removeOption(O, SC);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      } else {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+        for (auto SC : O->Subs)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+          removeOption(O, SC);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-  void updateArgStr(Option *O, StringRef NewName) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-    if (!OptionsMap.insert(std::make_pair(NewName, O)).second) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  bool hasOptions(const SubCommand &Sub) const {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    return (!Sub.OptionsMap.empty() || !Sub.PositionalOpts.empty() ||<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+            nullptr != Sub.ConsumeAfterOpt);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  bool hasOptions() const {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    for (const auto &S : RegisteredSubCommands) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      if (hasOptions(*S))<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+        return true;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    return false;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  SubCommand *getActiveSubCommand() { return ActiveSubCommand; }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  void updateArgStr(Option *O, StringRef NewName, SubCommand *SC) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    SubCommand &Sub = *SC;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    if (!Sub.OptionsMap.insert(std::make_pair(NewName, O)).second) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       errs() << ProgramName << ": CommandLine Error: Option '" << O->ArgStr<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
              << "' registered more than once!\n";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       report_fatal_error("inconsistency in registered CommandLine options");<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-    OptionsMap.erase(O->ArgStr);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    Sub.OptionsMap.erase(O->ArgStr);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  void updateArgStr(Option *O, StringRef NewName) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    if (O->Subs.empty())<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      updateArgStr(O, NewName, &*TopLevelSubCommand);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    else {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      for (auto SC : O->Subs)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+        updateArgStr(O, NewName, SC);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   void printOptionValues();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -203,8 +280,55 @@ public:<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     RegisteredOptionCategories.insert(cat);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  void registerSubCommand(SubCommand *sub) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    assert(count_if(RegisteredSubCommands,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+                    [sub](const SubCommand *Sub) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+                      return (sub->getName() != nullptr) &&<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+                             (Sub->getName() == sub->getName());<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+                    }) == 0 &&<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+           "Duplicate subcommands");<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    RegisteredSubCommands.insert(sub);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    // For all options that have been registered for all subcommands, add the<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    // option to this subcommand now.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    if (sub != &*AllSubCommands) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      for (auto &E : AllSubCommands->OptionsMap) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+        Option *O = E.second;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+        if ((O->isPositional() || O->isSink() || O->isConsumeAfter()) ||<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+            O->hasArgStr())<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+          addOption(O, sub);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+        else<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+          addLiteralOption(*O, sub, E.first().str().c_str());<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  void unregisterSubCommand(SubCommand *sub) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    RegisteredSubCommands.erase(sub);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  void reset() {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    ActiveSubCommand = nullptr;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    ProgramName.clear();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    ProgramOverview = nullptr;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    MoreHelp.clear();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    RegisteredOptionCategories.clear();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    ResetAllOptionOccurrences();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    RegisteredSubCommands.clear();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    TopLevelSubCommand->reset();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    AllSubCommands->reset();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    registerSubCommand(&*TopLevelSubCommand);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    registerSubCommand(&*AllSubCommands);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 private:<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-  Option *LookupOption(StringRef &Arg, StringRef &Value);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  SubCommand *ActiveSubCommand;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  Option *LookupOption(SubCommand &Sub, StringRef &Arg, StringRef &Value);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  SubCommand *LookupSubCommand(const char *Name);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 };<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 } // namespace<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -239,6 +363,32 @@ void OptionCategory::registerCategory()<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   GlobalParser->registerCategory(this);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+// A special subcommand representing no subcommand<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+ManagedStatic<SubCommand> llvm::cl::TopLevelSubCommand;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+// A special subcommand that can be used to put an option into all subcommands.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+ManagedStatic<SubCommand> llvm::cl::AllSubCommands;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+void SubCommand::registerSubCommand() {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  GlobalParser->registerSubCommand(this);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+}<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+void SubCommand::unregisterSubCommand() {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  GlobalParser->unregisterSubCommand(this);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+}<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+void SubCommand::reset() {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  PositionalOpts.clear();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  SinkOpts.clear();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  OptionsMap.clear();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  ConsumeAfterOpt = nullptr;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+}<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+SubCommand::operator bool() const {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  return (GlobalParser->getActiveSubCommand() == this);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+}<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 //===----------------------------------------------------------------------===//<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 // Basic, shared command line option processing machinery.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 //<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -246,25 +396,29 @@ void OptionCategory::registerCategory()<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 /// LookupOption - Lookup the option specified by the specified option on the<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 /// command line.  If there is a value specified (after an equal sign) return<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 /// that as well.  This assumes that leading dashes have already been stripped.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-Option *CommandLineParser::LookupOption(StringRef &Arg, StringRef &Value) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+Option *CommandLineParser::LookupOption(SubCommand &Sub, StringRef &Arg,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+                                        StringRef &Value) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   // Reject all dashes.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   if (Arg.empty())<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     return nullptr;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  assert(&Sub != &*AllSubCommands);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   size_t EqualPos = Arg.find('=');<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   // If we have an equals sign, remember the value.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   if (EqualPos == StringRef::npos) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     // Look up the option.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-    StringMap<Option *>::const_iterator I = OptionsMap.find(Arg);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-    return I != OptionsMap.end() ? I->second : nullptr;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    auto I = Sub.OptionsMap.find(Arg);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    if (I == Sub.OptionsMap.end())<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      return nullptr;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    return I != Sub.OptionsMap.end() ? I->second : nullptr;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   // If the argument before the = is a valid option name, we match.  If not,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   // return Arg unmolested.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-  StringMap<Option *>::const_iterator I =<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-      OptionsMap.find(Arg.substr(0, EqualPos));<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-  if (I == OptionsMap.end())<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  auto I = Sub.OptionsMap.find(Arg.substr(0, EqualPos));<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  if (I == Sub.OptionsMap.end())<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     return nullptr;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   Value = Arg.substr(EqualPos + 1);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -272,6 +426,21 @@ Option *CommandLineParser::LookupOption(<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   return I->second;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+SubCommand *CommandLineParser::LookupSubCommand(const char *Name) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  if (Name == nullptr)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    return &*TopLevelSubCommand;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  for (auto S : RegisteredSubCommands) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    if (S == &*AllSubCommands)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      continue;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    if (S->getName() == nullptr)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      continue;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    if (StringRef(S->getName()) == StringRef(Name))<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      return S;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  return &*TopLevelSubCommand;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+}<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 /// LookupNearestOption - Lookup the closest match to the option specified by<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 /// the specified option on the command line.  If there is a value specified<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 /// (after an equal sign) return that as well.  This assumes that leading dashes<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -820,14 +989,25 @@ void cl::ParseEnvironmentOptions(const c<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   ParseCommandLineOptions(newArgc, &newArgv[0], Overview);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-void cl::ParseCommandLineOptions(int argc, const char *const *argv,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-                                 const char *Overview) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-  GlobalParser->ParseCommandLineOptions(argc, argv, Overview);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+bool cl::ParseCommandLineOptions(int argc, const char *const *argv,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+                                 const char *Overview, bool IgnoreErrors) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  return GlobalParser->ParseCommandLineOptions(argc, argv, Overview,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+                                               IgnoreErrors);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-void CommandLineParser::ParseCommandLineOptions(int argc,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+void CommandLineParser::ResetAllOptionOccurrences() {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  // So that we can parse different command lines multiple times in succession<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  // we reset all option values to look like they have never been seen before.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  for (auto SC : RegisteredSubCommands) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    for (auto &O : SC->OptionsMap)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      O.second->reset();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+}<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+bool CommandLineParser::ParseCommandLineOptions(int argc,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
                                                 const char *const *argv,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-                                                const char *Overview) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+                                                const char *Overview,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+                                                bool IgnoreErrors) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   assert(hasOptions() && "No options specified!");<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   // Expand response files.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -850,6 +1030,23 @@ void CommandLineParser::ParseCommandLine<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   // Determine whether or not there are an unlimited number of positionals<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   bool HasUnlimitedPositionals = false;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  int FirstArg = 1;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  SubCommand *ChosenSubCommand = &*TopLevelSubCommand;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  if (argc >= 2 && argv[FirstArg][0] != '-') {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    // If the first argument specifies a valid subcommand, start processing<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    // options from the second argument.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    ChosenSubCommand = LookupSubCommand(argv[FirstArg]);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    if (ChosenSubCommand != &*TopLevelSubCommand)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      FirstArg = 2;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  GlobalParser->ActiveSubCommand = ChosenSubCommand;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  assert(ChosenSubCommand);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  auto &ConsumeAfterOpt = ChosenSubCommand->ConsumeAfterOpt;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  auto &PositionalOpts = ChosenSubCommand->PositionalOpts;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  auto &SinkOpts = ChosenSubCommand->SinkOpts;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  auto &OptionsMap = ChosenSubCommand->OptionsMap;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   if (ConsumeAfterOpt) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     assert(PositionalOpts.size() > 0 &&<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
            "Cannot specify cl::ConsumeAfter without a positional argument!");<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -865,23 +1062,28 @@ void CommandLineParser::ParseCommandLine<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       else if (ConsumeAfterOpt) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
         // ConsumeAfter cannot be combined with "optional" positional options<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
         // unless there is only one positional argument...<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-        if (PositionalOpts.size() > 1)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-          ErrorParsing |= Opt->error(<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-              "error - this positional option will never be matched, "<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-              "because it does not Require a value, and a "<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-              "cl::ConsumeAfter option is active!");<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+        if (PositionalOpts.size() > 1) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+          if (!IgnoreErrors)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+            Opt->error("error - this positional option will never be matched, "<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+                       "because it does not Require a value, and a "<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+                       "cl::ConsumeAfter option is active!");<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+          ErrorParsing = true;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+        }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       } else if (UnboundedFound && !Opt->hasArgStr()) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
         // This option does not "require" a value...  Make sure this option is<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
         // not specified after an option that eats all extra arguments, or this<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
         // one will never get any!<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
         //<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-        ErrorParsing |= Opt->error("error - option can never match, because "<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-                                   "another positional argument will match an "<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-                                   "unbounded number of values, and this option"<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-                                   " does not require a value!");<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-        errs() << ProgramName << ": CommandLine Error: Option '" << Opt->ArgStr<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-               << "' is all messed up!\n";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-        errs() << PositionalOpts.size();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+        if (!IgnoreErrors) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+          Opt->error("error - option can never match, because "<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+                     "another positional argument will match an "<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+                     "unbounded number of values, and this option"<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+                     " does not require a value!");<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+          errs() << ProgramName << ": CommandLine Error: Option '"<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+                 << Opt->ArgStr << "' is all messed up!\n";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+          errs() << PositionalOpts.size();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+        }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+        ErrorParsing = true;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       UnboundedFound |= EatsUnboundedNumberOfValues(Opt);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -900,7 +1102,7 @@ void CommandLineParser::ParseCommandLine<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   // Loop over all of the arguments... processing them.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   bool DashDashFound = false; // Have we read '--'?<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-  for (int i = 1; i < argc; ++i) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  for (int i = FirstArg; i < argc; ++i) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     Option *Handler = nullptr;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     Option *NearestHandler = nullptr;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     std::string NearestHandlerString;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -947,7 +1149,7 @@ void CommandLineParser::ParseCommandLine<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       while (!ArgName.empty() && ArgName[0] == '-')<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
         ArgName = ArgName.substr(1);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-      Handler = LookupOption(ArgName, Value);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      Handler = LookupOption(*ChosenSubCommand, ArgName, Value);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       if (!Handler || Handler->getFormattingFlag() != cl::Positional) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
         ProvidePositionalOption(ActivePositionalArg, argv[i], i);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
         continue; // We are done!<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -959,7 +1161,7 @@ void CommandLineParser::ParseCommandLine<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       while (!ArgName.empty() && ArgName[0] == '-')<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
         ArgName = ArgName.substr(1);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-      Handler = LookupOption(ArgName, Value);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      Handler = LookupOption(*ChosenSubCommand, ArgName, Value);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       // Check to see if this "option" is really a prefixed or grouped argument.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       if (!Handler)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -975,13 +1177,15 @@ void CommandLineParser::ParseCommandLine<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     if (!Handler) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       if (SinkOpts.empty()) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-        errs() << ProgramName << ": Unknown command line argument '" << argv[i]<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-               << "'.  Try: '" << argv[0] << " -help'\n";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-        if (NearestHandler) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-          // If we know a near match, report it as well.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-          errs() << ProgramName << ": Did you mean '-" << NearestHandlerString<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-                 << "'?\n";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+        if (!IgnoreErrors) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+          errs() << ProgramName << ": Unknown command line argument '"<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+                 << argv[i] << "'.  Try: '" << argv[0] << " -help'\n";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+          if (NearestHandler) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+            // If we know a near match, report it as well.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+            errs() << ProgramName << ": Did you mean '-" << NearestHandlerString<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+                   << "'?\n";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+          }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
         }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
         ErrorParsing = true;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -1004,17 +1208,21 @@ void CommandLineParser::ParseCommandLine<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   // Check and handle positional arguments now...<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   if (NumPositionalRequired > PositionalVals.size()) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-    errs() << ProgramName<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-           << ": Not enough positional command line arguments specified!\n"<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-           << "Must specify at least " << NumPositionalRequired<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-           << " positional arguments: See: " << argv[0] << " -help\n";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    if (!IgnoreErrors) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      errs() << ProgramName<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+             << ": Not enough positional command line arguments specified!\n"<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+             << "Must specify at least " << NumPositionalRequired<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+             << " positional arguments: See: " << argv[0] << " -help\n";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     ErrorParsing = true;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   } else if (!HasUnlimitedPositionals &&<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
              PositionalVals.size() > PositionalOpts.size()) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-    errs() << ProgramName << ": Too many positional arguments specified!\n"<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-           << "Can specify at most " << PositionalOpts.size()<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-           << " positional arguments: See: " << argv[0] << " -help\n";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    if (!IgnoreErrors) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      errs() << ProgramName << ": Too many positional arguments specified!\n"<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+             << "Can specify at most " << PositionalOpts.size()<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+             << " positional arguments: See: " << argv[0] << " -help\n";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     ErrorParsing = true;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   } else if (!ConsumeAfterOpt) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -1109,8 +1317,12 @@ void CommandLineParser::ParseCommandLine<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   MoreHelp.clear();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   // If we had an error processing our arguments, don't let the program execute<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-  if (ErrorParsing)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-    exit(1);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  if (ErrorParsing) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    if (!IgnoreErrors)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      exit(1);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    return false;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  return true;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 //===----------------------------------------------------------------------===//<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -1460,6 +1672,11 @@ static int OptNameCompare(const std::pai<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   return strcmp(LHS->first, RHS->first);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+static int SubNameCompare(const std::pair<const char *, SubCommand *> *LHS,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+                          const std::pair<const char *, SubCommand *> *RHS) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  return strcmp(LHS->first, RHS->first);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+}<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 // Copy Options into a vector so we can sort them as we like.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 static void sortOpts(StringMap<Option *> &OptMap,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
                      SmallVectorImpl<std::pair<const char *, Option *>> &Opts,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -1488,6 +1705,17 @@ static void sortOpts(StringMap<Option *><br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   array_pod_sort(Opts.begin(), Opts.end(), OptNameCompare);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+static void<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+sortSubCommands(const SmallPtrSetImpl<SubCommand *> &SubMap,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+                SmallVectorImpl<std::pair<const char *, SubCommand *>> &Subs) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  for (const auto &S : SubMap) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    if (S->getName() == nullptr)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      continue;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    Subs.push_back(std::make_pair(S->getName(), S));<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  array_pod_sort(Subs.begin(), Subs.end(), SubNameCompare);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+}<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 namespace {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 class HelpPrinter {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -1495,12 +1723,25 @@ protected:<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   const bool ShowHidden;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   typedef SmallVector<std::pair<const char *, Option *>, 128><br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       StrOptionPairVector;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  typedef SmallVector<std::pair<const char *, SubCommand *>, 128><br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      StrSubCommandPairVector;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   // Print the options. Opts is assumed to be alphabetically sorted.<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   virtual void printOptions(StrOptionPairVector &Opts, size_t MaxArgLen) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     for (size_t i = 0, e = Opts.size(); i != e; ++i)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       Opts[i].second->printOptionInfo(MaxArgLen);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  void printSubCommands(StrSubCommandPairVector &Subs, size_t MaxSubLen) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    for (const auto &S : Subs) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      outs() << "  " << S.first;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      if (S.second->getDescription()) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+        outs().indent(MaxSubLen - strlen(S.first));<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+        outs() << " - " << S.second->getDescription();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      outs() << "\n";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 public:<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   explicit HelpPrinter(bool showHidden) : ShowHidden(showHidden) {}<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   virtual ~HelpPrinter() {}<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -1510,23 +1751,56 @@ public:<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     if (!Value)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       return;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    SubCommand *Sub = GlobalParser->getActiveSubCommand();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    auto &OptionsMap = Sub->OptionsMap;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    auto &PositionalOpts = Sub->PositionalOpts;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    auto &ConsumeAfterOpt = Sub->ConsumeAfterOpt;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     StrOptionPairVector Opts;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-    sortOpts(GlobalParser->OptionsMap, Opts, ShowHidden);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    sortOpts(OptionsMap, Opts, ShowHidden);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    StrSubCommandPairVector Subs;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    sortSubCommands(GlobalParser->RegisteredSubCommands, Subs);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     if (GlobalParser->ProgramOverview)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       outs() << "OVERVIEW: " << GlobalParser->ProgramOverview << "\n";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-    outs() << "USAGE: " << GlobalParser->ProgramName << " [options]";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    if (Sub == &*TopLevelSubCommand)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      outs() << "USAGE: " << GlobalParser->ProgramName<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+             << " [subcommand] [options]";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    else {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      if (Sub->getDescription() != nullptr) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+        outs() << "SUBCOMMAND '" << Sub->getName()<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+               << "': " << Sub->getDescription() << "\n\n";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      outs() << "USAGE: " << GlobalParser->ProgramName << " " << Sub->getName()<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+             << " [options]";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-    for (auto Opt : GlobalParser->PositionalOpts) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    for (auto Opt : PositionalOpts) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       if (Opt->hasArgStr())<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
         outs() << " --" << Opt->ArgStr;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       outs() << " " << Opt->HelpStr;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     // Print the consume after option info if it exists...<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-    if (GlobalParser->ConsumeAfterOpt)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-      outs() << " " << GlobalParser->ConsumeAfterOpt->HelpStr;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    if (ConsumeAfterOpt)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      outs() << " " << ConsumeAfterOpt->HelpStr;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    if (Sub == &*TopLevelSubCommand && Subs.size() > 2) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg"></blockquote><div class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg"><br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg"></div></div></div></div><div dir="ltr" class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg"><div class="gmail_extra m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg"><div class="gmail_quote m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg"><div class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">I'm sorry if I missed something, but I looked at the review for this commit, and couldn't find an answer to one question that I have, so I hope that you can help me:<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg"></div><div class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg"><br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg"></div><div class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">Is the > 2 intentional here? I think because of this check subcommands don't show up in help unless there are 3 of them. It seems like a bug to me, since it's valid to have a tool with just 2 subcommands.</div><div class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg"><br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg"></div><div class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">Thanks,</div><div class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">Alex</div></div></div></div></blockquote></div></div></div></blockquote></div></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_extra gmail_msg"><div class="gmail_quote gmail_msg"><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="m_-3955298781657401918HOEnZb gmail_msg"><div class="m_-3955298781657401918h5 gmail_msg"><div class="gmail_quote gmail_msg"><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg"><div class="gmail_extra m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg"><div class="gmail_quote m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg"><blockquote class="gmail_quote m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
+      // Compute the maximum subcommand length...<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      size_t MaxSubLen = 0;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      for (size_t i = 0, e = Subs.size(); i != e; ++i)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+        MaxSubLen = std::max(MaxSubLen, strlen(Subs[i].first));<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      outs() << "\n\n";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      outs() << "SUBCOMMANDS:\n\n";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      printSubCommands(Subs, MaxSubLen);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      outs() << "\n";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      outs() << "  Type \"" << GlobalParser->ProgramName<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+             << " <subcommand> -help\" to get more help on a specific "<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+                "subcommand";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     outs() << "\n\n";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -1675,12 +1949,13 @@ static cl::opt<HelpPrinter, true, parser<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     "help-list",<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     cl::desc("Display list of available options (-help-list-hidden for more)"),<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     cl::location(UncategorizedNormalPrinter), cl::Hidden, cl::ValueDisallowed,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-    cl::cat(GenericCategory));<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    cl::cat(GenericCategory), cl::sub(*AllSubCommands));<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 static cl::opt<HelpPrinter, true, parser<bool>><br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     HLHOp("help-list-hidden", cl::desc("Display list of all available options"),<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
           cl::location(UncategorizedHiddenPrinter), cl::Hidden,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-          cl::ValueDisallowed, cl::cat(GenericCategory));<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+          cl::ValueDisallowed, cl::cat(GenericCategory),<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+          cl::sub(*AllSubCommands));<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 // Define uncategorized/categorized help printers. These printers change their<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 // behaviour at runtime depending on whether one or more Option categories have<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -1688,22 +1963,23 @@ static cl::opt<HelpPrinter, true, parser<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 static cl::opt<HelpPrinterWrapper, true, parser<bool>><br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     HOp("help", cl::desc("Display available options (-help-hidden for more)"),<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
         cl::location(WrappedNormalPrinter), cl::ValueDisallowed,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-        cl::cat(GenericCategory));<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+        cl::cat(GenericCategory), cl::sub(*AllSubCommands));<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 static cl::opt<HelpPrinterWrapper, true, parser<bool>><br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     HHOp("help-hidden", cl::desc("Display all available options"),<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
          cl::location(WrappedHiddenPrinter), cl::Hidden, cl::ValueDisallowed,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-         cl::cat(GenericCategory));<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+         cl::cat(GenericCategory), cl::sub(*AllSubCommands));<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 static cl::opt<bool> PrintOptions(<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     "print-options",<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     cl::desc("Print non-default options after command line parsing"),<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-    cl::Hidden, cl::init(false), cl::cat(GenericCategory));<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    cl::Hidden, cl::init(false), cl::cat(GenericCategory),<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    cl::sub(*AllSubCommands));<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 static cl::opt<bool> PrintAllOptions(<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     "print-all-options",<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     cl::desc("Print all option values after command line parsing"), cl::Hidden,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-    cl::init(false), cl::cat(GenericCategory));<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    cl::init(false), cl::cat(GenericCategory), cl::sub(*AllSubCommands));<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 void HelpPrinterWrapper::operator=(bool Value) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   if (!Value)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -1730,7 +2006,7 @@ void CommandLineParser::printOptionValue<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     return;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   SmallVector<std::pair<const char *, Option *>, 128> Opts;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-  sortOpts(OptionsMap, Opts, /*ShowHidden*/ true);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  sortOpts(ActiveSubCommand->OptionsMap, Opts, /*ShowHidden*/ true);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   // Compute the maximum argument length...<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   size_t MaxArgLen = 0;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -1839,22 +2115,26 @@ void cl::AddExtraVersionPrinter(void (*f<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   ExtraVersionPrinters->push_back(func);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-StringMap<Option *> &cl::getRegisteredOptions() {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-  return GlobalParser->OptionsMap;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+StringMap<Option *> &cl::getRegisteredOptions(SubCommand &Sub) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  auto &Subs = GlobalParser->RegisteredSubCommands;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  (void)Subs;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  assert(std::find(Subs.begin(), Subs.end(), &Sub) != Subs.end());<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  return Sub.OptionsMap;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-void cl::HideUnrelatedOptions(cl::OptionCategory &Category) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-  for (auto &I : GlobalParser->OptionsMap) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+void cl::HideUnrelatedOptions(cl::OptionCategory &Category, SubCommand &Sub) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  for (auto &I : Sub.OptionsMap) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     if (I.second->Category != &Category &&<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
         I.second->Category != &GenericCategory)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       I.second->setHiddenFlag(cl::ReallyHidden);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-void cl::HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *> Categories) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+void cl::HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *> Categories,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+                              SubCommand &Sub) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   auto CategoriesBegin = Categories.begin();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   auto CategoriesEnd = Categories.end();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-  for (auto &I : GlobalParser->OptionsMap) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  for (auto &I : Sub.OptionsMap) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     if (std::find(CategoriesBegin, CategoriesEnd, I.second->Category) ==<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
             CategoriesEnd &&<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
         I.second->Category != &GenericCategory)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -1862,7 +2142,12 @@ void cl::HideUnrelatedOptions(ArrayRef<c<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+void cl::ResetCommandLineParser() { GlobalParser->reset(); }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+void cl::ResetAllOptionOccurrences() {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  GlobalParser->ResetAllOptionOccurrences();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+}<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 void LLVMParseCommandLineOptions(int argc, const char *const *argv,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
                                  const char *Overview) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-  llvm::cl::ParseCommandLineOptions(argc, argv, Overview);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  llvm::cl::ParseCommandLineOptions(argc, argv, Overview, true);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
Modified: llvm/trunk/unittests/Support/CommandLineTest.cpp<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/CommandLineTest.cpp?rev=274171&r1=274170&r2=274171&view=diff" rel="noreferrer" class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/CommandLineTest.cpp?rev=274171&r1=274170&r2=274171&view=diff</a><br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
==============================================================================<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
--- llvm/trunk/unittests/Support/CommandLineTest.cpp (original)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+++ llvm/trunk/unittests/Support/CommandLineTest.cpp Wed Jun 29 16:48:26 2016<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -67,6 +67,22 @@ public:<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     : Base(M0, M1, M2, M3) {}<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   ~StackOption() override { this->removeArgument(); }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  template <class DT> StackOption<T> &operator=(const DT &V) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    this->setValue(V);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+    return *this;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+};<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+class StackSubCommand : public cl::SubCommand {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+public:<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  StackSubCommand(const char *const Name,<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+                  const char *const Description = nullptr)<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      : SubCommand(Name, Description) {}<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  StackSubCommand() : SubCommand() {}<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  ~StackSubCommand() { unregisterSubCommand(); }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 };<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -78,7 +94,8 @@ TEST(CommandLineTest, ModifyExisitingOpt<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   const char ArgString[] = "new-test-option";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   const char ValueString[] = "Integer";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-  StringMap<cl::Option *> &Map = cl::getRegisteredOptions();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  StringMap<cl::Option *> &Map =<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      cl::getRegisteredOptions(*cl::TopLevelSubCommand);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   ASSERT_TRUE(Map.count("test-option") == 1) <<<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
     "Could not find option in map.";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -237,7 +254,8 @@ TEST(CommandLineTest, HideUnrelatedOptio<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   ASSERT_EQ(cl::NotHidden, TestOption2.getOptionHiddenFlag())<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       << "Hid extra option that should be visable.";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-  StringMap<cl::Option *> &Map = cl::getRegisteredOptions();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  StringMap<cl::Option *> &Map =<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      cl::getRegisteredOptions(*cl::TopLevelSubCommand);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   ASSERT_EQ(cl::NotHidden, Map["help"]->getOptionHiddenFlag())<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       << "Hid default option that should be visable.";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
@@ -261,9 +279,201 @@ TEST(CommandLineTest, HideUnrelatedOptio<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   ASSERT_EQ(cl::NotHidden, TestOption3.getOptionHiddenFlag())<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       << "Hid extra option that should be visable.";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
-  StringMap<cl::Option *> &Map = cl::getRegisteredOptions();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  StringMap<cl::Option *> &Map =<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+      cl::getRegisteredOptions(*cl::TopLevelSubCommand);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
   ASSERT_EQ(cl::NotHidden, Map["help"]->getOptionHiddenFlag())<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
       << "Hid default option that should be visable.";<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
 }<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+TEST(CommandLineTest, SetValueInSubcategories) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  cl::ResetCommandLineParser();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  StackSubCommand SC1("sc1", "First subcommand");<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  StackSubCommand SC2("sc2", "Second subcommand");<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  StackOption<bool> TopLevelOpt("top-level", cl::init(false));<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  StackOption<bool> SC1Opt("sc1", cl::sub(SC1), cl::init(false));<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  StackOption<bool> SC2Opt("sc2", cl::sub(SC2), cl::init(false));<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  EXPECT_FALSE(TopLevelOpt);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  EXPECT_FALSE(SC1Opt);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  EXPECT_FALSE(SC2Opt);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  const char *args[] = {"prog", "-top-level"};<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  EXPECT_TRUE(cl::ParseCommandLineOptions(2, args, nullptr, true));<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  EXPECT_TRUE(TopLevelOpt);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  EXPECT_FALSE(SC1Opt);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  EXPECT_FALSE(SC2Opt);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  TopLevelOpt = false;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  cl::ResetAllOptionOccurrences();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  EXPECT_FALSE(TopLevelOpt);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  EXPECT_FALSE(SC1Opt);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  EXPECT_FALSE(SC2Opt);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  const char *args2[] = {"prog", "sc1", "-sc1"};<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  EXPECT_TRUE(cl::ParseCommandLineOptions(3, args2, nullptr, true));<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  EXPECT_FALSE(TopLevelOpt);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  EXPECT_TRUE(SC1Opt);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  EXPECT_FALSE(SC2Opt);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  SC1Opt = false;<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  cl::ResetAllOptionOccurrences();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  EXPECT_FALSE(TopLevelOpt);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  EXPECT_FALSE(SC1Opt);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  EXPECT_FALSE(SC2Opt);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  const char *args3[] = {"prog", "sc2", "-sc2"};<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  EXPECT_TRUE(cl::ParseCommandLineOptions(3, args3, nullptr, true));<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  EXPECT_FALSE(TopLevelOpt);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  EXPECT_FALSE(SC1Opt);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  EXPECT_TRUE(SC2Opt);<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+}<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+TEST(CommandLineTest, LookupFailsInWrongSubCommand) {<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+  cl::ResetCommandLineParser();<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg">
+<br class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg"></blockquote></div></div></div></blockquote></div></div></div></blockquote></div></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_extra gmail_msg"><div class="gmail_quote gmail_msg"><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="m_-3955298781657401918HOEnZb gmail_msg"><div class="m_-3955298781657401918h5 gmail_msg"><div class="gmail_quote gmail_msg"><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class="m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg"><div class="gmail_extra m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg"><div class="gmail_quote m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg"><blockquote class="gmail_quote m_-3955298781657401918m_1046857407579580143gmail_msg gmail_msg" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
+  StackSubCommand SC1("sc1", "First subcommand");<br class="m_1046857407579580143gmail_msg</blockquote></div></div></div></blockquote></div></div></div></blockquote></div></div></div></blockquote></div>