Author: Nicolai Hähnle Date: 2022-08-02T23:49:16+02:00 New Revision: f7872cdce1102a5c12633dad462a1d9763a578d3
URL: https://github.com/llvm/llvm-project/commit/f7872cdce1102a5c12633dad462a1d9763a578d3 DIFF: https://github.com/llvm/llvm-project/commit/f7872cdce1102a5c12633dad462a1d9763a578d3.diff LOG: CommandLine: add and use cl::SubCommand::get{All,TopLevel} 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. Differential Revision: https://reviews.llvm.org/D129118 Added: Modified: 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 Removed: ################################################################################ diff --git a/bolt/lib/Utils/CommandLineOpts.cpp b/bolt/lib/Utils/CommandLineOpts.cpp index fbaaf16019fcb..b90a73543ed64 100644 --- a/bolt/lib/Utils/CommandLineOpts.cpp +++ b/bolt/lib/Utils/CommandLineOpts.cpp @@ -135,12 +135,9 @@ OutputFilename("o", 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", @@ -181,12 +178,9 @@ cl::opt<bool> UpdateDebugSections( 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) diff --git a/bolt/tools/driver/llvm-bolt.cpp b/bolt/tools/driver/llvm-bolt.cpp index 24e10c70ae2a8..942a434d09719 100644 --- a/bolt/tools/driver/llvm-bolt.cpp +++ b/bolt/tools/driver/llvm-bolt.cpp @@ -49,7 +49,7 @@ static cl::OptionCategory *Perf2BoltCategories[] = {&AggregatorCategory, 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", diff --git a/clang/lib/Tooling/CommonOptionsParser.cpp b/clang/lib/Tooling/CommonOptionsParser.cpp index 7d48dd5054649..59ef47cc0166e 100644 --- a/clang/lib/Tooling/CommonOptionsParser.cpp +++ b/clang/lib/Tooling/CommonOptionsParser.cpp @@ -86,21 +86,21 @@ llvm::Error CommonOptionsParser::init( 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(); diff --git a/clang/tools/clang-refactor/ClangRefactor.cpp b/clang/tools/clang-refactor/ClangRefactor.cpp index eacd00a601dbe..83c6976e7d22d 100644 --- a/clang/tools/clang-refactor/ClangRefactor.cpp +++ b/clang/tools/clang-refactor/ClangRefactor.cpp @@ -39,11 +39,11 @@ static cl::OptionCategory CommonRefactorOptions("Refactoring options"); 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 diff --git a/llvm/include/llvm/Support/CommandLine.h b/llvm/include/llvm/Support/CommandLine.h index 6461164fceffb..be1f54cfba368 100644 --- a/llvm/include/llvm/Support/CommandLine.h +++ b/llvm/include/llvm/Support/CommandLine.h @@ -217,6 +217,13 @@ class SubCommand { } 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 @@ class Option { } bool isInAllSubCommands() const { - return llvm::is_contained(Subs, &*AllSubCommands); + return llvm::is_contained(Subs, &SubCommand::getAll()); } //-------------------------------------------------------------------------=== @@ -1952,7 +1959,8 @@ void PrintHelpMessage(bool Hidden = false, bool Categorized = false); /// 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 @@ bool expandResponseFiles(int Argc, const char *const *Argv, const char *EnvVar, /// 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 @@ void HideUnrelatedOptions(cl::OptionCategory &Category, /// 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 diff --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp index 5e7d631651300..b86be5ea4219e 100644 --- a/llvm/lib/Support/CommandLine.cpp +++ b/llvm/lib/Support/CommandLine.cpp @@ -167,8 +167,8 @@ class CommandLineParser { SmallPtrSet<SubCommand *, 4> RegisteredSubCommands; CommandLineParser() { - registerSubCommand(&*TopLevelSubCommand); - registerSubCommand(&*AllSubCommands); + registerSubCommand(&SubCommand::getTopLevel()); + registerSubCommand(&SubCommand::getAll()); } void ResetAllOptionOccurrences(); @@ -188,7 +188,7 @@ class CommandLineParser { // 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 @@ class CommandLineParser { 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 @@ class CommandLineParser { // 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 @@ class CommandLineParser { } if (O->Subs.empty()) { - addOption(O, &*TopLevelSubCommand); + addOption(O, &SubCommand::getTopLevel()); } else { for (auto *SC : O->Subs) addOption(O, SC); @@ -302,7 +302,7 @@ class CommandLineParser { 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 @@ class CommandLineParser { 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 @@ class CommandLineParser { // 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 @@ class CommandLineParser { 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 @@ ManagedStatic<SubCommand> llvm::cl::TopLevelSubCommand; // 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 @@ Option *CommandLineParser::LookupOption(SubCommand &Sub, StringRef &Arg, // Reject all dashes. if (Arg.empty()) return nullptr; - assert(&Sub != &*AllSubCommands); + assert(&Sub != &SubCommand::getAll()); size_t EqualPos = Arg.find('='); @@ -551,9 +555,9 @@ Option *CommandLineParser::LookupOption(SubCommand &Sub, StringRef &Arg, 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 @@ SubCommand *CommandLineParser::LookupSubCommand(StringRef Name) { 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 CommandLineParser::ParseCommandLineOptions(int argc, 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; @@ -2289,7 +2293,7 @@ class HelpPrinter { if (!GlobalParser->ProgramOverview.empty()) outs() << "OVERVIEW: " << GlobalParser->ProgramOverview << "\n"; - if (Sub == &*TopLevelSubCommand) { + if (Sub == &SubCommand::getTopLevel()) { outs() << "USAGE: " << GlobalParser->ProgramName; if (Subs.size() > 2) outs() << " [subcommand]"; @@ -2313,7 +2317,7 @@ class HelpPrinter { 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) @@ -2519,7 +2523,7 @@ struct CommandLineCommonOptions { cl::Hidden, cl::ValueDisallowed, cl::cat(GenericCategory), - cl::sub(*AllSubCommands)}; + cl::sub(SubCommand::getAll())}; cl::opt<HelpPrinter, true, parser<bool>> HLHOp{ "help-list-hidden", @@ -2528,7 +2532,7 @@ struct CommandLineCommonOptions { 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 @@ -2539,7 +2543,7 @@ struct CommandLineCommonOptions { 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}; @@ -2551,7 +2555,7 @@ struct CommandLineCommonOptions { cl::Hidden, cl::ValueDisallowed, cl::cat(GenericCategory), - cl::sub(*AllSubCommands)}; + cl::sub(SubCommand::getAll())}; cl::opt<bool> PrintOptions{ "print-options", @@ -2559,7 +2563,7 @@ struct CommandLineCommonOptions { cl::Hidden, cl::init(false), cl::cat(GenericCategory), - cl::sub(*AllSubCommands)}; + cl::sub(SubCommand::getAll())}; cl::opt<bool> PrintAllOptions{ "print-all-options", @@ -2567,7 +2571,7 @@ struct CommandLineCommonOptions { cl::Hidden, cl::init(false), cl::cat(GenericCategory), - cl::sub(*AllSubCommands)}; + cl::sub(SubCommand::getAll())}; VersionPrinterTy OverrideVersionPrinter = nullptr; diff --git a/llvm/tools/llvm-xray/llvm-xray.cpp b/llvm/tools/llvm-xray/llvm-xray.cpp index 9ee653e97b2dd..2b1182cad2bd8 100644 --- a/llvm/tools/llvm-xray/llvm-xray.cpp +++ b/llvm/tools/llvm-xray/llvm-xray.cpp @@ -31,7 +31,7 @@ int main(int argc, char *argv[]) { 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; } diff --git a/llvm/unittests/Support/CommandLineInit/CommandLineInitTest.cpp b/llvm/unittests/Support/CommandLineInit/CommandLineInitTest.cpp index 391b344bd6450..dce79b2a3d2c7 100644 --- a/llvm/unittests/Support/CommandLineInit/CommandLineInitTest.cpp +++ b/llvm/unittests/Support/CommandLineInit/CommandLineInitTest.cpp @@ -51,7 +51,7 @@ int main(int argc, char **argv) { 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"}) diff --git a/llvm/unittests/Support/CommandLineTest.cpp b/llvm/unittests/Support/CommandLineTest.cpp index ed0dc98415a67..32dc440135cb3 100644 --- a/llvm/unittests/Support/CommandLineTest.cpp +++ b/llvm/unittests/Support/CommandLineTest.cpp @@ -99,7 +99,7 @@ TEST(CommandLineTest, ModifyExisitingOption) { 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 @@ TEST(CommandLineTest, HideUnrelatedOptions) { << "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 @@ TEST(CommandLineTest, HideUnrelatedOptionsMulti) { << "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 @@ TEST(CommandLineTest, AddToAllSubCommands) { 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, AddToAllSubCommands) { 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, RemoveFromRegularSubCommand) { 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 @@ TEST(CommandLineTest, RemoveFromAllSubCommands) { 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, GetRegisteredSubcommands) { 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 @@ TEST(CommandLineTest, SetDefautValue) { 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; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits