[clang] [clang-tools-extra] [lld] [llvm] [llvm] Add subcommand support for OptTable (PR #155026)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 17 10:06:13 PDT 2025
================
@@ -0,0 +1,123 @@
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Option/OptTable.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/InitLLVM.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+using namespace llvm::opt;
+
+namespace {
+enum ID {
+ OPT_INVALID = 0,
+#define OPTION(PREFIXES, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \
+ VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, \
+ VALUES, COMMANDIDS_OFFSET) \
+ OPT_##ID,
+#include "Opts.inc"
+#undef OPTION
+};
+#define OPTTABLE_STR_TABLE_CODE
+#include "Opts.inc"
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "Opts.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
+
+#define OPTTABLE_COMMAND_IDS_TABLE_CODE
+#include "Opts.inc"
+#undef OPTTABLE_COMMAND_IDS_TABLE_CODE
+
+#define OPTTABLE_COMMANDS_CODE
+#include "Opts.inc"
+#undef OPTTABLE_COMMANDS_CODE
+
+static constexpr OptTable::Info InfoTable[] = {
+#define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__),
+#include "Opts.inc"
+#undef OPTION
+};
+
+class HelloSubOptTable : public GenericOptTable {
+public:
+ HelloSubOptTable()
+ : GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable, false,
+ OptionCommands, OptionCommandIDsTable) {}
+};
+} // namespace
+
+int main(int argc, char **argv) {
+ InitLLVM X(argc, argv);
+ HelloSubOptTable T;
+ unsigned MissingArgIndex, MissingArgCount;
+
+ auto HandleMultipleSubcommands = [](ArrayRef<StringRef> SubCommands) {
+ assert(SubCommands.size() > 1);
+ llvm::errs() << "error: more than one subcommand passed [\n";
+ for (auto SC : SubCommands)
+ llvm::errs() << " `" << SC << "`\n";
+ llvm::errs() << "]\n";
+ llvm::errs() << "See --help.\n";
+ exit(1);
+ };
+
+ auto HandleOtherPositionals = [](ArrayRef<StringRef> Positionals) {
+ assert(!Positionals.empty());
+ llvm::errs() << "error: unknown positional argument(s) [\n";
+ for (auto SC : Positionals)
+ llvm::errs() << " `" << SC << "`\n";
+ llvm::errs() << "]\n";
+ llvm::errs() << "See --help.\n";
+ exit(1);
+ };
+
+ InputArgList Args = T.ParseArgs(ArrayRef(argv + 1, argc - 1), MissingArgIndex,
+ MissingArgCount);
+
+ StringRef Subcommand = Args.getSubcommand(
+ T.getCommands(), HandleMultipleSubcommands, HandleOtherPositionals);
+ // Handle help. When help options is found, ignore all other options and exit
+ // after printing help.
+ if (Args.hasArg(OPT_help)) {
+ T.printHelp(llvm::outs(), "llvm-hello-sub [subcommand] [options]",
+ "LLVM Hello Subcommand Example", false, false, Visibility(),
+ Subcommand);
+ return 0;
+ }
+ bool HasUnknownOptions = false;
+ for (const Arg *A : Args.filtered(OPT_UNKNOWN)) {
+ HasUnknownOptions = true;
+ llvm::errs() << "Unknown option `" << A->getAsString(Args) << "'\n";
+ }
+ if (HasUnknownOptions) {
+ llvm::errs() << "See `OptSubcommand --help`.\n";
+ return 1;
+ }
+ if (Subcommand.empty()) {
+ if (Args.hasArg(OPT_version)) {
+ llvm::outs() << "LLVM Hello Subcommand Example 1.0\n";
+ }
----------------
PiJoules wrote:
https://llvm.org/docs/CodingStandards.html#don-t-use-braces-on-simple-single-statement-bodies-of-if-else-loop-statements
```
if (Args.hasArg(OPT_version))
llvm::outs() << "LLVM Hello Subcommand Example 1.0\n";
```
https://github.com/llvm/llvm-project/pull/155026
More information about the llvm-commits
mailing list