Skip to content

[CommandLine][NFCI] Simplify enumerating subcommands of an option #75679

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
Dec 19, 2023

Conversation

igorkudrin
Copy link
Collaborator

The patch adds a helper method to iterate over all subcommands to which an option belongs. Duplicate code is removed and replaced with calls to this new method.

The patch adds a helper method to iterate over all subcommands to which
an option belongs. Duplicate code is removed and replaced with calls to
this new method.
@llvmbot
Copy link
Member

llvmbot commented Dec 16, 2023

@llvm/pr-subscribers-llvm-support

Author: Igor Kudrin (igorkudrin)

Changes

The patch adds a helper method to iterate over all subcommands to which an option belongs. Duplicate code is removed and replaced with calls to this new method.


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

2 Files Affected:

  • (modified) llvm/include/llvm/Support/CommandLine.h (-4)
  • (modified) llvm/lib/Support/CommandLine.cpp (+24-55)
diff --git a/llvm/include/llvm/Support/CommandLine.h b/llvm/include/llvm/Support/CommandLine.h
index 58ef176551b685..5d733eeee6d399 100644
--- a/llvm/include/llvm/Support/CommandLine.h
+++ b/llvm/include/llvm/Support/CommandLine.h
@@ -314,10 +314,6 @@ class Option {
     return getNumOccurrencesFlag() == cl::ConsumeAfter;
   }
 
-  bool isInAllSubCommands() const {
-    return Subs.contains(&SubCommand::getAll());
-  }
-
   //-------------------------------------------------------------------------===
   // Accessor functions set by OptionModifiers
   //
diff --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp
index 088b4e4d755cbe..00179bc32551fe 100644
--- a/llvm/lib/Support/CommandLine.cpp
+++ b/llvm/lib/Support/CommandLine.cpp
@@ -175,6 +175,24 @@ class CommandLineParser {
                                StringRef Overview, raw_ostream *Errs = nullptr,
                                bool LongOptionsUseDoubleDash = false);
 
+  void forEachSubCommand(Option &Opt,
+                         std::function<void(SubCommand &)> Action) {
+    if (Opt.Subs.empty()) {
+      Action(SubCommand::getTopLevel());
+      return;
+    }
+    if (Opt.Subs.size() == 1 && *Opt.Subs.begin() == &SubCommand::getAll()) {
+      for (auto *SC : RegisteredSubCommands)
+        Action(*SC);
+      return;
+    }
+    for (auto *SC : Opt.Subs) {
+      assert(SC != &SubCommand::getAll() &&
+             "SubCommand::getAll() should not be used with other subcommands");
+      Action(*SC);
+    }
+  }
+
   void addLiteralOption(Option &Opt, SubCommand *SC, StringRef Name) {
     if (Opt.hasArgStr())
       return;
@@ -183,25 +201,11 @@ class CommandLineParser {
              << "' registered more than once!\n";
       report_fatal_error("inconsistency in registered CommandLine options");
     }
-
-    // If we're adding this to all sub-commands, add it to the ones that have
-    // already been registered.
-    if (SC == &SubCommand::getAll()) {
-      for (auto *Sub : RegisteredSubCommands) {
-        if (SC == Sub)
-          continue;
-        addLiteralOption(Opt, Sub, Name);
-      }
-    }
   }
 
   void addLiteralOption(Option &Opt, StringRef Name) {
-    if (Opt.Subs.empty())
-      addLiteralOption(Opt, &SubCommand::getTopLevel(), Name);
-    else {
-      for (auto *SC : Opt.Subs)
-        addLiteralOption(Opt, SC, Name);
-    }
+    forEachSubCommand(
+        Opt, [&](SubCommand &SC) { addLiteralOption(Opt, &SC, Name); });
   }
 
   void addOption(Option *O, SubCommand *SC) {
@@ -238,16 +242,6 @@ class CommandLineParser {
     // linked LLVM distribution.
     if (HadErrors)
       report_fatal_error("inconsistency in registered CommandLine options");
-
-    // If we're adding this to all sub-commands, add it to the ones that have
-    // already been registered.
-    if (SC == &SubCommand::getAll()) {
-      for (auto *Sub : RegisteredSubCommands) {
-        if (SC == Sub)
-          continue;
-        addOption(O, Sub);
-      }
-    }
   }
 
   void addOption(Option *O, bool ProcessDefaultOption = false) {
@@ -255,13 +249,7 @@ class CommandLineParser {
       DefaultOptions.push_back(O);
       return;
     }
-
-    if (O->Subs.empty()) {
-      addOption(O, &SubCommand::getTopLevel());
-    } else {
-      for (auto *SC : O->Subs)
-        addOption(O, SC);
-    }
+    forEachSubCommand(*O, [&](SubCommand &SC) { addOption(O, &SC); });
   }
 
   void removeOption(Option *O, SubCommand *SC) {
@@ -298,17 +286,7 @@ class CommandLineParser {
   }
 
   void removeOption(Option *O) {
-    if (O->Subs.empty())
-      removeOption(O, &SubCommand::getTopLevel());
-    else {
-      if (O->isInAllSubCommands()) {
-        for (auto *SC : RegisteredSubCommands)
-          removeOption(O, SC);
-      } else {
-        for (auto *SC : O->Subs)
-          removeOption(O, SC);
-      }
-    }
+    forEachSubCommand(*O, [&](SubCommand &SC) { removeOption(O, &SC); });
   }
 
   bool hasOptions(const SubCommand &Sub) const {
@@ -344,17 +322,8 @@ class CommandLineParser {
   }
 
   void updateArgStr(Option *O, StringRef NewName) {
-    if (O->Subs.empty())
-      updateArgStr(O, NewName, &SubCommand::getTopLevel());
-    else {
-      if (O->isInAllSubCommands()) {
-        for (auto *SC : RegisteredSubCommands)
-          updateArgStr(O, NewName, SC);
-      } else {
-        for (auto *SC : O->Subs)
-          updateArgStr(O, NewName, SC);
-      }
-    }
+    forEachSubCommand(*O,
+                      [&](SubCommand &SC) { updateArgStr(O, NewName, &SC); });
   }
 
   void printOptionValues();

Copy link
Collaborator

@jh7370 jh7370 left a comment

Choose a reason for hiding this comment

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

LGTM.

Copy link
Collaborator

@RKSimon RKSimon left a comment

Choose a reason for hiding this comment

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

LGTM

@igorkudrin igorkudrin merged commit 6a2a99f into llvm:main Dec 19, 2023
@igorkudrin igorkudrin deleted the cl-simplify-all-subcommands branch December 19, 2023 19:39
@@ -175,6 +175,24 @@ class CommandLineParser {
StringRef Overview, raw_ostream *Errs = nullptr,
bool LongOptionsUseDoubleDash = false);

void forEachSubCommand(Option &Opt,
std::function<void(SubCommand &)> Action) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please use function_ref instead of std::function here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks for the suggestion. I've created #75973 for this.

igorkudrin added a commit to igorkudrin/llvm-project that referenced this pull request Dec 19, 2023
igorkudrin added a commit that referenced this pull request Dec 19, 2023
igorkudrin added a commit to igorkudrin/llvm-project that referenced this pull request Jan 5, 2024
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.
igorkudrin added a commit that referenced this pull request Jan 10, 2024
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.
igorkudrin added a commit to igorkudrin/llvm-project that referenced this pull request Jan 11, 2024
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.
igorkudrin added a commit that referenced this pull request Jan 12, 2024
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.
justinfargnoli pushed a commit to justinfargnoli/llvm-project that referenced this pull request Jan 28, 2024
…#77041)

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.
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.

5 participants