nhaehnle created this revision.
nhaehnle added reviewers: efriedma, lattner.
Herald added subscribers: ayermolo, hiraditya.
Herald added a reviewer: rafauler.
Herald added a reviewer: Amir.
Herald added a reviewer: maksfb.
Herald added a project: All.
nhaehnle requested review of this revision.
Herald added subscribers: cfe-commits, yota9.
Herald added projects: clang, LLVM.

Prefer using these accessors to access the special sub-commands
corresponding to the top-level (no subcommand) and all sub-commands.

This is a preparatory step towards removing the use of ManagedStatic:
with a subsequent change, these global instances will be moved to
be regular function-scope statics.

It is split up to give downstream projects a (albeit short) window in
which they can switch to using the accessors in a forward-compatible
way.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D129118

Files:
  bolt/lib/Utils/CommandLineOpts.cpp
  bolt/tools/driver/llvm-bolt.cpp
  clang/lib/Tooling/CommonOptionsParser.cpp
  clang/tools/clang-refactor/ClangRefactor.cpp
  llvm/include/llvm/Support/CommandLine.h
  llvm/lib/Support/CommandLine.cpp
  llvm/tools/llvm-xray/llvm-xray.cpp
  llvm/unittests/Support/CommandLineInit/CommandLineInitTest.cpp
  llvm/unittests/Support/CommandLineTest.cpp

Index: llvm/unittests/Support/CommandLineTest.cpp
===================================================================
--- llvm/unittests/Support/CommandLineTest.cpp
+++ llvm/unittests/Support/CommandLineTest.cpp
@@ -99,7 +99,7 @@
   static const char ValueString[] = "Integer";
 
   StringMap<cl::Option *> &Map =
-      cl::getRegisteredOptions(*cl::TopLevelSubCommand);
+      cl::getRegisteredOptions(cl::SubCommand::getTopLevel());
 
   ASSERT_EQ(Map.count("test-option"), 1u) << "Could not find option in map.";
 
@@ -420,7 +420,7 @@
       << "Hid extra option that should be visable.";
 
   StringMap<cl::Option *> &Map =
-      cl::getRegisteredOptions(*cl::TopLevelSubCommand);
+      cl::getRegisteredOptions(cl::SubCommand::getTopLevel());
   ASSERT_TRUE(Map.count("help") == (size_t)0 ||
               cl::NotHidden == Map["help"]->getOptionHiddenFlag())
       << "Hid default option that should be visable.";
@@ -446,7 +446,7 @@
       << "Hid extra option that should be visable.";
 
   StringMap<cl::Option *> &Map =
-      cl::getRegisteredOptions(*cl::TopLevelSubCommand);
+      cl::getRegisteredOptions(cl::SubCommand::getTopLevel());
   ASSERT_TRUE(Map.count("help") == (size_t)0 ||
               cl::NotHidden == Map["help"]->getOptionHiddenFlag())
       << "Hid default option that should be visable.";
@@ -529,7 +529,7 @@
   cl::ResetCommandLineParser();
 
   StackSubCommand SC1("sc1", "First subcommand");
-  StackOption<bool> AllOpt("everywhere", cl::sub(*cl::AllSubCommands),
+  StackOption<bool> AllOpt("everywhere", cl::sub(cl::SubCommand::getAll()),
                            cl::init(false));
   StackSubCommand SC2("sc2", "Second subcommand");
 
@@ -566,8 +566,8 @@
 TEST(CommandLineTest, ReparseCommandLineOptions) {
   cl::ResetCommandLineParser();
 
-  StackOption<bool> TopLevelOpt("top-level", cl::sub(*cl::TopLevelSubCommand),
-                                cl::init(false));
+  StackOption<bool> TopLevelOpt(
+      "top-level", cl::sub(cl::SubCommand::getTopLevel()), cl::init(false));
 
   const char *args[] = {"prog", "-top-level"};
 
@@ -614,10 +614,12 @@
 TEST(CommandLineTest, RemoveFromTopLevelSubCommand) {
   cl::ResetCommandLineParser();
 
-  StackOption<bool> TopLevelRemove(
-      "top-level-remove", cl::sub(*cl::TopLevelSubCommand), cl::init(false));
-  StackOption<bool> TopLevelKeep(
-      "top-level-keep", cl::sub(*cl::TopLevelSubCommand), cl::init(false));
+  StackOption<bool> TopLevelRemove("top-level-remove",
+                                   cl::sub(cl::SubCommand::getTopLevel()),
+                                   cl::init(false));
+  StackOption<bool> TopLevelKeep("top-level-keep",
+                                 cl::sub(cl::SubCommand::getTopLevel()),
+                                 cl::init(false));
 
   const char *args[] = {"prog", "-top-level-remove"};
 
@@ -638,9 +640,9 @@
 
   StackSubCommand SC1("sc1", "First Subcommand");
   StackSubCommand SC2("sc2", "Second Subcommand");
-  StackOption<bool> RemoveOption("remove-option", cl::sub(*cl::AllSubCommands),
-                                 cl::init(false));
-  StackOption<bool> KeepOption("keep-option", cl::sub(*cl::AllSubCommands),
+  StackOption<bool> RemoveOption(
+      "remove-option", cl::sub(cl::SubCommand::getAll()), cl::init(false));
+  StackOption<bool> KeepOption("keep-option", cl::sub(cl::SubCommand::getAll()),
                                cl::init(false));
 
   const char *args0[] = {"prog", "-remove-option"};
@@ -719,13 +721,13 @@
 TEST(CommandLineTest, DefaultOptions) {
   cl::ResetCommandLineParser();
 
-  StackOption<std::string> Bar("bar", cl::sub(*cl::AllSubCommands),
+  StackOption<std::string> Bar("bar", cl::sub(cl::SubCommand::getAll()),
                                cl::DefaultOption);
   StackOption<std::string, cl::alias> Bar_Alias(
       "b", cl::desc("Alias for -bar"), cl::aliasopt(Bar), cl::DefaultOption);
 
-  StackOption<bool> Foo("foo", cl::init(false), cl::sub(*cl::AllSubCommands),
-                        cl::DefaultOption);
+  StackOption<bool> Foo("foo", cl::init(false),
+                        cl::sub(cl::SubCommand::getAll()), cl::DefaultOption);
   StackOption<bool, cl::alias> Foo_Alias("f", cl::desc("Alias for -foo"),
                                          cl::aliasopt(Foo), cl::DefaultOption);
 
@@ -1062,7 +1064,7 @@
 
   cl::ResetAllOptionOccurrences();
 
-  for (auto &OM : cl::getRegisteredOptions(*cl::TopLevelSubCommand)) {
+  for (auto &OM : cl::getRegisteredOptions(cl::SubCommand::getTopLevel())) {
     cl::Option *O = OM.second;
     if (O->ArgStr == "opt2") {
       continue;
Index: llvm/unittests/Support/CommandLineInit/CommandLineInitTest.cpp
===================================================================
--- llvm/unittests/Support/CommandLineInit/CommandLineInitTest.cpp
+++ llvm/unittests/Support/CommandLineInit/CommandLineInitTest.cpp
@@ -51,7 +51,7 @@
 
 TEST(CommandLineInitTest, GetPresetOptions) {
   StringMap<cl::Option *> &Map =
-      cl::getRegisteredOptions(*cl::TopLevelSubCommand);
+      cl::getRegisteredOptions(cl::SubCommand::getTopLevel());
 
   for (auto *Str :
        {"help", "help-hidden", "help-list", "help-list-hidden", "version"})
Index: llvm/tools/llvm-xray/llvm-xray.cpp
===================================================================
--- llvm/tools/llvm-xray/llvm-xray.cpp
+++ llvm/tools/llvm-xray/llvm-xray.cpp
@@ -31,7 +31,7 @@
     if (*SC) {
       // If no subcommand was provided, we need to explicitly check if this is
       // the top-level subcommand.
-      if (SC == &*cl::TopLevelSubCommand) {
+      if (SC == &cl::SubCommand::getTopLevel()) {
         cl::PrintHelpMessage(false, true);
         return 0;
       }
Index: llvm/lib/Support/CommandLine.cpp
===================================================================
--- llvm/lib/Support/CommandLine.cpp
+++ llvm/lib/Support/CommandLine.cpp
@@ -167,8 +167,8 @@
   SmallPtrSet<SubCommand *, 4> RegisteredSubCommands;
 
   CommandLineParser() {
-    registerSubCommand(&*TopLevelSubCommand);
-    registerSubCommand(&*AllSubCommands);
+    registerSubCommand(&SubCommand::getTopLevel());
+    registerSubCommand(&SubCommand::getAll());
   }
 
   void ResetAllOptionOccurrences();
@@ -188,7 +188,7 @@
 
     // If we're adding this to all sub-commands, add it to the ones that have
     // already been registered.
-    if (SC == &*AllSubCommands) {
+    if (SC == &SubCommand::getAll()) {
       for (auto *Sub : RegisteredSubCommands) {
         if (SC == Sub)
           continue;
@@ -199,7 +199,7 @@
 
   void addLiteralOption(Option &Opt, StringRef Name) {
     if (Opt.Subs.empty())
-      addLiteralOption(Opt, &*TopLevelSubCommand, Name);
+      addLiteralOption(Opt, &SubCommand::getTopLevel(), Name);
     else {
       for (auto *SC : Opt.Subs)
         addLiteralOption(Opt, SC, Name);
@@ -244,7 +244,7 @@
 
     // If we're adding this to all sub-commands, add it to the ones that have
     // already been registered.
-    if (SC == &*AllSubCommands) {
+    if (SC == &SubCommand::getAll()) {
       for (auto *Sub : RegisteredSubCommands) {
         if (SC == Sub)
           continue;
@@ -260,7 +260,7 @@
     }
 
     if (O->Subs.empty()) {
-      addOption(O, &*TopLevelSubCommand);
+      addOption(O, &SubCommand::getTopLevel());
     } else {
       for (auto *SC : O->Subs)
         addOption(O, SC);
@@ -302,7 +302,7 @@
 
   void removeOption(Option *O) {
     if (O->Subs.empty())
-      removeOption(O, &*TopLevelSubCommand);
+      removeOption(O, &SubCommand::getTopLevel());
     else {
       if (O->isInAllSubCommands()) {
         for (auto *SC : RegisteredSubCommands)
@@ -341,7 +341,7 @@
 
   void updateArgStr(Option *O, StringRef NewName) {
     if (O->Subs.empty())
-      updateArgStr(O, NewName, &*TopLevelSubCommand);
+      updateArgStr(O, NewName, &SubCommand::getTopLevel());
     else {
       if (O->isInAllSubCommands()) {
         for (auto *SC : RegisteredSubCommands)
@@ -376,8 +376,8 @@
 
     // For all options that have been registered for all subcommands, add the
     // option to this subcommand now.
-    if (sub != &*AllSubCommands) {
-      for (auto &E : AllSubCommands->OptionsMap) {
+    if (sub != &SubCommand::getAll()) {
+      for (auto &E : SubCommand::getAll().OptionsMap) {
         Option *O = E.second;
         if ((O->isPositional() || O->isSink() || O->isConsumeAfter()) ||
             O->hasArgStr())
@@ -409,10 +409,10 @@
     ResetAllOptionOccurrences();
     RegisteredSubCommands.clear();
 
-    TopLevelSubCommand->reset();
-    AllSubCommands->reset();
-    registerSubCommand(&*TopLevelSubCommand);
-    registerSubCommand(&*AllSubCommands);
+    SubCommand::getTopLevel().reset();
+    SubCommand::getAll().reset();
+    registerSubCommand(&SubCommand::getTopLevel());
+    registerSubCommand(&SubCommand::getAll());
 
     DefaultOptions.clear();
   }
@@ -491,6 +491,10 @@
 // A special subcommand that can be used to put an option into all subcommands.
 ManagedStatic<SubCommand> llvm::cl::AllSubCommands;
 
+SubCommand &SubCommand::getTopLevel() { return *TopLevelSubCommand; }
+
+SubCommand &SubCommand::getAll() { return *AllSubCommands; }
+
 void SubCommand::registerSubCommand() {
   GlobalParser->registerSubCommand(this);
 }
@@ -523,7 +527,7 @@
   // Reject all dashes.
   if (Arg.empty())
     return nullptr;
-  assert(&Sub != &*AllSubCommands);
+  assert(&Sub != &SubCommand::getAll());
 
   size_t EqualPos = Arg.find('=');
 
@@ -551,9 +555,9 @@
 
 SubCommand *CommandLineParser::LookupSubCommand(StringRef Name) {
   if (Name.empty())
-    return &*TopLevelSubCommand;
+    return &SubCommand::getTopLevel();
   for (auto *S : RegisteredSubCommands) {
-    if (S == &*AllSubCommands)
+    if (S == &SubCommand::getAll())
       continue;
     if (S->getName().empty())
       continue;
@@ -561,7 +565,7 @@
     if (StringRef(S->getName()) == StringRef(Name))
       return S;
   }
-  return &*TopLevelSubCommand;
+  return &SubCommand::getTopLevel();
 }
 
 /// LookupNearestOption - Lookup the closest match to the option specified by
@@ -1452,12 +1456,12 @@
   bool HasUnlimitedPositionals = false;
 
   int FirstArg = 1;
-  SubCommand *ChosenSubCommand = &*TopLevelSubCommand;
+  SubCommand *ChosenSubCommand = &SubCommand::getTopLevel();
   if (argc >= 2 && argv[FirstArg][0] != '-') {
     // If the first argument specifies a valid subcommand, start processing
     // options from the second argument.
     ChosenSubCommand = LookupSubCommand(StringRef(argv[FirstArg]));
-    if (ChosenSubCommand != &*TopLevelSubCommand)
+    if (ChosenSubCommand != &SubCommand::getTopLevel())
       FirstArg = 2;
   }
   GlobalParser->ActiveSubCommand = ChosenSubCommand;
@@ -2287,19 +2291,19 @@
     if (!GlobalParser->ProgramOverview.empty())
       outs() << "OVERVIEW: " << GlobalParser->ProgramOverview << "\n";
 
-    if (Sub == &*TopLevelSubCommand) {
       outs() << "USAGE: " << GlobalParser->ProgramName;
-      if (Subs.size() > 2)
-        outs() << " [subcommand]";
-      outs() << " [options]";
-    } else {
-      if (!Sub->getDescription().empty()) {
-        outs() << "SUBCOMMAND '" << Sub->getName()
-               << "': " << Sub->getDescription() << "\n\n";
+      if (Sub == &SubCommand::getTopLevel()) {
+        if (Subs.size() > 2)
+          outs() << " [subcommand]";
+        outs() << " [options]";
+      } else {
+        if (!Sub->getDescription().empty()) {
+          outs() << "SUBCOMMAND '" << Sub->getName()
+                 << "': " << Sub->getDescription() << "\n\n";
+        }
+        outs() << "USAGE: " << GlobalParser->ProgramName << " "
+               << Sub->getName() << " [options]";
       }
-      outs() << "USAGE: " << GlobalParser->ProgramName << " " << Sub->getName()
-             << " [options]";
-    }
 
     for (auto *Opt : PositionalOpts) {
       if (Opt->hasArgStr())
@@ -2311,7 +2315,7 @@
     if (ConsumeAfterOpt)
       outs() << " " << ConsumeAfterOpt->HelpStr;
 
-    if (Sub == &*TopLevelSubCommand && !Subs.empty()) {
+    if (Sub == &SubCommand::getTopLevel() && !Subs.empty()) {
       // Compute the maximum subcommand length...
       size_t MaxSubLen = 0;
       for (size_t i = 0, e = Subs.size(); i != e; ++i)
@@ -2517,7 +2521,7 @@
       cl::Hidden,
       cl::ValueDisallowed,
       cl::cat(GenericCategory),
-      cl::sub(*AllSubCommands)};
+      cl::sub(SubCommand::getAll())};
 
   cl::opt<HelpPrinter, true, parser<bool>> HLHOp{
       "help-list-hidden",
@@ -2526,7 +2530,7 @@
       cl::Hidden,
       cl::ValueDisallowed,
       cl::cat(GenericCategory),
-      cl::sub(*AllSubCommands)};
+      cl::sub(SubCommand::getAll())};
 
   // Define uncategorized/categorized help printers. These printers change their
   // behaviour at runtime depending on whether one or more Option categories
@@ -2537,7 +2541,7 @@
       cl::location(WrappedNormalPrinter),
       cl::ValueDisallowed,
       cl::cat(GenericCategory),
-      cl::sub(*AllSubCommands)};
+      cl::sub(SubCommand::getAll())};
 
   cl::alias HOpA{"h", cl::desc("Alias for --help"), cl::aliasopt(HOp),
                  cl::DefaultOption};
@@ -2549,7 +2553,7 @@
       cl::Hidden,
       cl::ValueDisallowed,
       cl::cat(GenericCategory),
-      cl::sub(*AllSubCommands)};
+      cl::sub(SubCommand::getAll())};
 
   cl::opt<bool> PrintOptions{
       "print-options",
@@ -2557,7 +2561,7 @@
       cl::Hidden,
       cl::init(false),
       cl::cat(GenericCategory),
-      cl::sub(*AllSubCommands)};
+      cl::sub(SubCommand::getAll())};
 
   cl::opt<bool> PrintAllOptions{
       "print-all-options",
@@ -2565,7 +2569,7 @@
       cl::Hidden,
       cl::init(false),
       cl::cat(GenericCategory),
-      cl::sub(*AllSubCommands)};
+      cl::sub(SubCommand::getAll())};
 
   VersionPrinterTy OverrideVersionPrinter = nullptr;
 
Index: llvm/include/llvm/Support/CommandLine.h
===================================================================
--- llvm/include/llvm/Support/CommandLine.h
+++ llvm/include/llvm/Support/CommandLine.h
@@ -217,6 +217,13 @@
   }
   SubCommand() = default;
 
+  // Get the special subcommand representing no subcommand.
+  static SubCommand &getTopLevel();
+
+  // Get the special subcommand that can be used to put an option into all
+  // subcomands.
+  static SubCommand &getAll();
+
   void reset();
 
   explicit operator bool() const;
@@ -309,7 +316,7 @@
   }
 
   bool isInAllSubCommands() const {
-    return llvm::is_contained(Subs, &*AllSubCommands);
+    return llvm::is_contained(Subs, &SubCommand::getAll());
   }
 
   //-------------------------------------------------------------------------===
@@ -1952,7 +1959,8 @@
 /// Hopefully this API can be deprecated soon. Any situation where options need
 /// to be modified by tools or libraries should be handled by sane APIs rather
 /// than just handing around a global list.
-StringMap<Option *> &getRegisteredOptions(SubCommand &Sub = *TopLevelSubCommand);
+StringMap<Option *> &
+getRegisteredOptions(SubCommand &Sub = SubCommand::getTopLevel());
 
 /// Use this to get all registered SubCommands from the provided parser.
 ///
@@ -2123,7 +2131,7 @@
 /// not specific to the tool. This function allows a tool to specify a single
 /// option category to display in the -help output.
 void HideUnrelatedOptions(cl::OptionCategory &Category,
-                          SubCommand &Sub = *TopLevelSubCommand);
+                          SubCommand &Sub = SubCommand::getTopLevel());
 
 /// Mark all options not part of the categories as cl::ReallyHidden.
 ///
@@ -2133,7 +2141,7 @@
 /// not specific to the tool. This function allows a tool to specify a single
 /// option category to display in the -help output.
 void HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *> Categories,
-                          SubCommand &Sub = *TopLevelSubCommand);
+                          SubCommand &Sub = SubCommand::getTopLevel());
 
 /// Reset all command line options to a state that looks as if they have
 /// never appeared on the command line.  This is useful for being able to parse
Index: clang/tools/clang-refactor/ClangRefactor.cpp
===================================================================
--- clang/tools/clang-refactor/ClangRefactor.cpp
+++ clang/tools/clang-refactor/ClangRefactor.cpp
@@ -39,11 +39,11 @@
 
 static cl::opt<bool> Verbose("v", cl::desc("Use verbose output"),
                              cl::cat(cl::getGeneralCategory()),
-                             cl::sub(*cl::AllSubCommands));
+                             cl::sub(cl::SubCommand::getAll()));
 
 static cl::opt<bool> Inplace("i", cl::desc("Inplace edit <file>s"),
                              cl::cat(cl::getGeneralCategory()),
-                             cl::sub(*cl::AllSubCommands));
+                             cl::sub(cl::SubCommand::getAll()));
 
 } // end namespace opts
 
Index: clang/lib/Tooling/CommonOptionsParser.cpp
===================================================================
--- clang/lib/Tooling/CommonOptionsParser.cpp
+++ clang/lib/Tooling/CommonOptionsParser.cpp
@@ -86,21 +86,21 @@
 
   static cl::opt<std::string> BuildPath("p", cl::desc("Build path"),
                                         cl::Optional, cl::cat(Category),
-                                        cl::sub(*cl::AllSubCommands));
+                                        cl::sub(cl::SubCommand::getAll()));
 
   static cl::list<std::string> SourcePaths(
       cl::Positional, cl::desc("<source0> [... <sourceN>]"), OccurrencesFlag,
-      cl::cat(Category), cl::sub(*cl::AllSubCommands));
+      cl::cat(Category), cl::sub(cl::SubCommand::getAll()));
 
   static cl::list<std::string> ArgsAfter(
       "extra-arg",
       cl::desc("Additional argument to append to the compiler command line"),
-      cl::cat(Category), cl::sub(*cl::AllSubCommands));
+      cl::cat(Category), cl::sub(cl::SubCommand::getAll()));
 
   static cl::list<std::string> ArgsBefore(
       "extra-arg-before",
       cl::desc("Additional argument to prepend to the compiler command line"),
-      cl::cat(Category), cl::sub(*cl::AllSubCommands));
+      cl::cat(Category), cl::sub(cl::SubCommand::getAll()));
 
   cl::ResetAllOptionOccurrences();
 
Index: bolt/tools/driver/llvm-bolt.cpp
===================================================================
--- bolt/tools/driver/llvm-bolt.cpp
+++ bolt/tools/driver/llvm-bolt.cpp
@@ -49,7 +49,7 @@
 static cl::opt<std::string> InputFilename(cl::Positional,
                                           cl::desc("<executable>"),
                                           cl::Required, cl::cat(BoltCategory),
-                                          cl::sub(*cl::AllSubCommands));
+                                          cl::sub(cl::SubCommand::getAll()));
 
 static cl::opt<std::string>
 InputDataFilename("data",
Index: bolt/lib/Utils/CommandLineOpts.cpp
===================================================================
--- bolt/lib/Utils/CommandLineOpts.cpp
+++ bolt/lib/Utils/CommandLineOpts.cpp
@@ -129,12 +129,9 @@
   cl::Optional,
   cl::cat(BoltOutputCategory));
 
-cl::opt<std::string>
-PerfData("perfdata",
-  cl::desc("<data file>"),
-  cl::Optional,
-  cl::cat(AggregatorCategory),
-  cl::sub(*cl::AllSubCommands));
+cl::opt<std::string> PerfData("perfdata", cl::desc("<data file>"), cl::Optional,
+                              cl::cat(AggregatorCategory),
+                              cl::sub(cl::SubCommand::getAll()));
 
 static cl::alias
 PerfDataA("p",
@@ -175,12 +172,9 @@
     cl::cat(BoltCategory));
 
 cl::opt<unsigned>
-Verbosity("v",
-  cl::desc("set verbosity level for diagnostic output"),
-  cl::init(0),
-  cl::ZeroOrMore,
-  cl::cat(BoltCategory),
-  cl::sub(*cl::AllSubCommands));
+    Verbosity("v", cl::desc("set verbosity level for diagnostic output"),
+              cl::init(0), cl::ZeroOrMore, cl::cat(BoltCategory),
+              cl::sub(cl::SubCommand::getAll()));
 
 bool processAllFunctions() {
   if (opts::AggregateOnly)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to