hintonda updated this revision to Diff 194669. hintonda added a comment. - Delay actually adding default options until ParseCommandLineOptions which simplifies handling and makes it easy to only add them to the correct SubCommand.
Add simple tests. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D59746/new/ https://reviews.llvm.org/D59746 Files: clang/lib/Tooling/CommonOptionsParser.cpp llvm/docs/CommandLine.rst llvm/include/llvm/Support/CommandLine.h llvm/lib/Support/CommandLine.cpp llvm/test/Support/check-default-options.txt llvm/tools/llvm-opt-report/OptReport.cpp
Index: llvm/tools/llvm-opt-report/OptReport.cpp =================================================================== --- llvm/tools/llvm-opt-report/OptReport.cpp +++ llvm/tools/llvm-opt-report/OptReport.cpp @@ -36,8 +36,6 @@ using namespace llvm; using namespace llvm::yaml; -static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden); - // Mark all our options with this category, everything else (except for -version // and -help) will be hidden. static cl::OptionCategory @@ -440,11 +438,6 @@ "A tool to generate an optimization report from YAML optimization" " record files.\n"); - if (Help) { - cl::PrintHelpMessage(); - return 0; - } - LocationInfoTy LocationInfo; if (!readLocationInfo(LocationInfo)) return 1; Index: llvm/test/Support/check-default-options.txt =================================================================== --- /dev/null +++ llvm/test/Support/check-default-options.txt @@ -0,0 +1,18 @@ +# RUN: llvm-objdump -help-hidden %t | FileCheck --check-prefix=CHECK-OBJDUMP %s +# RUN: llvm-readobj -help-hidden %t | FileCheck --check-prefix=CHECK-READOBJ %s +# RUN: llvm-tblgen -help-hidden %t | FileCheck --check-prefix=CHECK-TBLGEN %s +# RUN: llvm-opt-report -help-hidden %t | FileCheck --check-prefix=CHECK-OPT-RPT %s +# RUN: llvm-dwarfdump -help-hidden %t | FileCheck --check-prefix=CHECK-DWARF %s +# RUN: llvm-dwarfdump -h %t | FileCheck --check-prefix=CHECK-DWARF-H %s + + +# CHECK-OBJDUMP: -h - Alias for --section-headers +# CHECK-READOBJ: -h - Alias for --file-headers +# CHECK-TBLGEN: -h - Alias for -help +# CHECK-OPT-RPT: -h - Alias for -help +# CHECK-DWARF: -h - Alias for -help + +# llvm-dwarfdump declares `-h` option and prints special help in that case, +# which is weird, but makes for a good test, i.e., shows the default `-h` +# wasn't used. +# CHECK-DWARF-H-NOT: -help-list - Display list of available options (-help-list-hidden for more) Index: llvm/lib/Support/CommandLine.cpp =================================================================== --- llvm/lib/Support/CommandLine.cpp +++ llvm/lib/Support/CommandLine.cpp @@ -98,6 +98,8 @@ // This collects additional help to be printed. std::vector<StringRef> MoreHelp; + SmallVector<Option*, 4> DefaultOptions; + // This collects the different option categories that have been registered. SmallPtrSet<OptionCategory *, 16> RegisteredOptionCategories; @@ -146,6 +148,11 @@ void addOption(Option *O, SubCommand *SC) { bool HadErrors = false; if (O->hasArgStr()) { + // If it's a DefaultOption, check to make sure it isn't already there. + if (O->getMiscFlags() & cl::DefaultOption && + SC->OptionsMap.find(O->ArgStr) != SC->OptionsMap.end()) + return; + // Add argument to the argument map! if (!SC->OptionsMap.insert(std::make_pair(O->ArgStr, O)).second) { errs() << ProgramName << ": CommandLine Error: Option '" << O->ArgStr @@ -185,7 +192,13 @@ } } - void addOption(Option *O) { + void addOption(Option *O, bool ProcessDefaultOption = false) { + // Handle DefaultOptions + if (!ProcessDefaultOption && O->getMiscFlags() & cl::DefaultOption) { + DefaultOptions.push_back(O); + return; + } + if (O->Subs.empty()) { addOption(O, &*TopLevelSubCommand); } else { @@ -266,8 +279,13 @@ if (O->Subs.empty()) updateArgStr(O, NewName, &*TopLevelSubCommand); else { - for (auto SC : O->Subs) - updateArgStr(O, NewName, SC); + if (O->isInAllSubCommands()) { + for (auto SC : RegisteredSubCommands) + updateArgStr(O, NewName, SC); + } else { + for (auto SC : O->Subs) + updateArgStr(O, NewName, SC); + } } } @@ -1167,6 +1185,11 @@ auto &SinkOpts = ChosenSubCommand->SinkOpts; auto &OptionsMap = ChosenSubCommand->OptionsMap; + // Handle DefaultOptions. + for (auto O: DefaultOptions) { + addOption(O, true); + } + if (ConsumeAfterOpt) { assert(PositionalOpts.size() > 0 && "Cannot specify cl::ConsumeAfter without a positional argument!"); @@ -2146,6 +2169,9 @@ cl::location(WrappedNormalPrinter), cl::ValueDisallowed, cl::cat(GenericCategory), cl::sub(*AllSubCommands)); +static cl::alias HOpA("h", cl::desc("Alias for -help"), cl::aliasopt(HOp), + cl::DefaultOption); + static cl::opt<HelpPrinterWrapper, true, parser<bool>> HHOp("help-hidden", cl::desc("Display all available options"), cl::location(WrappedHiddenPrinter), cl::Hidden, cl::ValueDisallowed, Index: llvm/include/llvm/Support/CommandLine.h =================================================================== --- llvm/include/llvm/Support/CommandLine.h +++ llvm/include/llvm/Support/CommandLine.h @@ -175,7 +175,10 @@ // If this is enabled, multiple letter options are allowed to bunch together // with only a single hyphen for the whole group. This allows emulation // of the behavior that ls uses for example: ls -la === ls -l -a - Grouping = 0x08 + Grouping = 0x08, + + // Default option + DefaultOption = 0x10 }; //===----------------------------------------------------------------------===// @@ -270,7 +273,7 @@ unsigned Value : 2; unsigned HiddenFlag : 2; // enum OptionHidden unsigned Formatting : 2; // enum FormattingFlags - unsigned Misc : 4; + unsigned Misc : 5; unsigned Position = 0; // Position of last occurrence of the option unsigned AdditionalVals = 0; // Greater than 0 for multi-valued option. @@ -1732,7 +1735,10 @@ error("cl::alias must have argument name specified!"); if (!AliasFor) error("cl::alias must have an cl::aliasopt(option) specified!"); + if (!Subs.empty()) + error("cl::alias must not have cl::sub(), aliased option's cl::sub() will be used!"); Subs = AliasFor->Subs; + Category = AliasFor->Category; addArgument(); } Index: llvm/docs/CommandLine.rst =================================================================== --- llvm/docs/CommandLine.rst +++ llvm/docs/CommandLine.rst @@ -128,6 +128,7 @@ USAGE: compiler [options] OPTIONS: + -h - Alias for -help -help - display available options (-help-hidden for more) -o <filename> - Specify output filename @@ -194,6 +195,7 @@ USAGE: compiler [options] <input file> OPTIONS: + -h - Alias for -help -help - display available options (-help-hidden for more) -o <filename> - Specify output filename @@ -1251,6 +1253,14 @@ with ``cl::CommaSeparated``, this modifier only makes sense with a `cl::list`_ option. +.. _cl::DefaultOption: + +* The **cl::DefaultOption** modifier is used to specify that the option is a + default that can be overridden by application specific parsers. For example, + the ``-help`` alias, ``-h``, is registered this way, so it can be overridden + by applications that need to use the ``-h`` option for another purpose, + either as a regular option or an alias for another option. + .. _response files: Response files Index: clang/lib/Tooling/CommonOptionsParser.cpp =================================================================== --- clang/lib/Tooling/CommonOptionsParser.cpp +++ clang/lib/Tooling/CommonOptionsParser.cpp @@ -83,8 +83,6 @@ llvm::Error CommonOptionsParser::init( int &argc, const char **argv, cl::OptionCategory &Category, llvm::cl::NumOccurrencesFlag OccurrencesFlag, const char *Overview) { - static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden, - cl::sub(*cl::AllSubCommands)); static cl::opt<std::string> BuildPath("p", cl::desc("Build path"), cl::Optional, cl::cat(Category),
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits