Skip to content

[CommandLine][NFCI] Do not add 'All' to 'RegisteredSubCommands' #77722

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 12, 2024

Conversation

igorkudrin
Copy link
Collaborator

After #75679, it is no longer necessary to add the All pseudo subcommand to the list of registered subcommands. The change causes the list to contain only real subcommands, i.e. an unnamed top-level subcommand and named ones. This simplifies the code a bit by removing some checks for this special case.

This is a fixed version of #77041, where options of the 'All' subcommand were not added to subcommands defined after them.

After llvm#75679, it is no longer necessary to add the `All` pseudo
subcommand to the list of registered subcommands. The change causes the
list to contain only real subcommands, i.e. an unnamed top-level
subcommand and named ones. This simplifies the code a bit by removing
some checks for this special case.

This is a fixed version of llvm#77041, where options of the 'All' subcommand
were not added to subcommands defined after them.
@llvmbot
Copy link
Member

llvmbot commented Jan 11, 2024

@llvm/pr-subscribers-llvm-support

Author: Igor Kudrin (igorkudrin)

Changes

After #75679, it is no longer necessary to add the All pseudo subcommand to the list of registered subcommands. The change causes the list to contain only real subcommands, i.e. an unnamed top-level subcommand and named ones. This simplifies the code a bit by removing some checks for this special case.

This is a fixed version of #77041, where options of the 'All' subcommand were not added to subcommands defined after them.


Full diff: https://github.com/llvm/llvm-project/pull/77722.diff

2 Files Affected:

  • (modified) llvm/lib/Support/CommandLine.cpp (+13-16)
  • (modified) llvm/unittests/Support/CommandLineTest.cpp (+5)
diff --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp
index 7360d733d96e7b..553669ce8ee37c 100644
--- a/llvm/lib/Support/CommandLine.cpp
+++ b/llvm/lib/Support/CommandLine.cpp
@@ -164,10 +164,7 @@ class CommandLineParser {
   // This collects the different subcommands that have been registered.
   SmallPtrSet<SubCommand *, 4> RegisteredSubCommands;
 
-  CommandLineParser() {
-    registerSubCommand(&SubCommand::getTopLevel());
-    registerSubCommand(&SubCommand::getAll());
-  }
+  CommandLineParser() { registerSubCommand(&SubCommand::getTopLevel()); }
 
   void ResetAllOptionOccurrences();
 
@@ -183,6 +180,7 @@ class CommandLineParser {
     if (Opt.Subs.size() == 1 && *Opt.Subs.begin() == &SubCommand::getAll()) {
       for (auto *SC : RegisteredSubCommands)
         Action(*SC);
+      Action(SubCommand::getAll());
       return;
     }
     for (auto *SC : Opt.Subs) {
@@ -348,15 +346,15 @@ class CommandLineParser {
 
     // For all options that have been registered for all subcommands, add the
     // option to this subcommand now.
-    if (sub != &SubCommand::getAll()) {
-      for (auto &E : SubCommand::getAll().OptionsMap) {
-        Option *O = E.second;
-        if ((O->isPositional() || O->isSink() || O->isConsumeAfter()) ||
-            O->hasArgStr())
-          addOption(O, sub);
-        else
-          addLiteralOption(*O, sub, E.first());
-      }
+    assert(sub != &SubCommand::getAll() &&
+           "SubCommand::getAll() should not be registered");
+    for (auto &E : SubCommand::getAll().OptionsMap) {
+      Option *O = E.second;
+      if ((O->isPositional() || O->isSink() || O->isConsumeAfter()) ||
+          O->hasArgStr())
+        addOption(O, sub);
+      else
+        addLiteralOption(*O, sub, E.first());
     }
   }
 
@@ -384,7 +382,6 @@ class CommandLineParser {
     SubCommand::getTopLevel().reset();
     SubCommand::getAll().reset();
     registerSubCommand(&SubCommand::getTopLevel());
-    registerSubCommand(&SubCommand::getAll());
 
     DefaultOptions.clear();
   }
@@ -532,8 +529,8 @@ SubCommand *CommandLineParser::LookupSubCommand(StringRef Name,
   // Find a subcommand with the edit distance == 1.
   SubCommand *NearestMatch = nullptr;
   for (auto *S : RegisteredSubCommands) {
-    if (S == &SubCommand::getAll())
-      continue;
+    assert(S != &SubCommand::getAll() &&
+           "SubCommand::getAll() is not expected in RegisteredSubCommands");
     if (S->getName().empty())
       continue;
 
diff --git a/llvm/unittests/Support/CommandLineTest.cpp b/llvm/unittests/Support/CommandLineTest.cpp
index 99d99c74c128b0..bbeb9d5dc19bda 100644
--- a/llvm/unittests/Support/CommandLineTest.cpp
+++ b/llvm/unittests/Support/CommandLineTest.cpp
@@ -585,6 +585,11 @@ TEST(CommandLineTest, AddToAllSubCommands) {
                            cl::init(false));
   StackSubCommand SC2("sc2", "Second subcommand");
 
+  EXPECT_TRUE(cl::SubCommand::getTopLevel().OptionsMap.contains("everywhere"));
+  EXPECT_TRUE(cl::SubCommand::getAll().OptionsMap.contains("everywhere"));
+  EXPECT_TRUE(SC1.OptionsMap.contains("everywhere"));
+  EXPECT_TRUE(SC2.OptionsMap.contains("everywhere"));
+
   const char *args[] = {"prog", "-everywhere"};
   const char *args2[] = {"prog", "sc1", "-everywhere"};
   const char *args3[] = {"prog", "sc2", "-everywhere"};

Copy link
Collaborator

@nhaehnle nhaehnle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding the unit test, that's really useful.

Copy link
Member

@MaskRay MaskRay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the simplification. The main trick appears to be forEachSubCommand

@igorkudrin igorkudrin merged commit 9f8c818 into llvm:main Jan 12, 2024
@igorkudrin igorkudrin deleted the cl-do-not-register-allsubs-fix branch January 12, 2024 19:19
justinfargnoli pushed a commit to justinfargnoli/llvm-project that referenced this pull request Jan 28, 2024
…#77722)

After llvm#75679, it is no longer necessary to add the `All` pseudo
subcommand to the list of registered subcommands. The change causes the
list to contain only real subcommands, i.e. an unnamed top-level
subcommand and named ones. This simplifies the code a bit by removing
some checks for this special case.

This is a fixed version of llvm#77041, where options of the 'All' subcommand
were not added to subcommands defined after them.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants