[clang] [clang-tools-extra] [lld] [llvm] [llvm] Add subcommand support for OptTable (PR #155026)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 26 11:22:37 PDT 2025
================
@@ -0,0 +1,227 @@
+//===- unittest/Support/OptionParsingTest.cpp - OptTable tests ------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Option/Arg.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Option/OptTable.h"
+#include "llvm/Option/Option.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::opt;
+
+#if defined(__clang__)
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+#endif
+
+namespace {
+enum ID {
+ OPT_INVALID = 0,
+#define OPTION(PREFIXES, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \
+ VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, \
+ VALUES, SUBCOMMANDIDS_OFFSET) \
+ OPT_##ID,
+#include "SubCommandOpts.inc"
+#undef OPTION
+};
+#define OPTTABLE_STR_TABLE_CODE
+#include "SubCommandOpts.inc"
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "SubCommandOpts.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
+
+#define OPTTABLE_SUBCOMMAND_IDS_TABLE_CODE
+#include "SubCommandOpts.inc"
+#undef OPTTABLE_SUBCOMMAND_IDS_TABLE_CODE
+
+#define OPTTABLE_SUBCOMMANDS_CODE
+#include "SubCommandOpts.inc"
+#undef OPTTABLE_SUBCOMMANDS_CODE
+
+static constexpr OptTable::Info InfoTable[] = {
+#define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__),
+#include "SubCommandOpts.inc"
+#undef OPTION
+};
+
+class TestOptSubCommandTable : public GenericOptTable {
+public:
+ TestOptSubCommandTable(bool IgnoreCase = false)
+ : GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable,
+ /*IgnoreCase=*/false, OptionSubCommands,
+ OptionSubCommandIDsTable) {}
+};
+
+// Test fixture
+template <typename T> class OptSubCommandTableTest : public ::testing::Test {};
+
+// Test both precomputed and computed OptTables with the same suite of tests.
+using OptSubCommandTableTestTypes = ::testing::Types<TestOptSubCommandTable>;
+
+TYPED_TEST_SUITE(OptSubCommandTableTest, OptSubCommandTableTestTypes, );
+
+TYPED_TEST(OptSubCommandTableTest, SubCommandParsing) {
+ TypeParam T;
+ unsigned MAI, MAC;
+
+ std::string ErrMsg;
+ raw_string_ostream RSO1(ErrMsg);
+
+ auto HandleMultipleSubcommands = [&](ArrayRef<StringRef> SubCommands) {
+ ErrMsg.clear();
+ RSO1 << "Multiple subcommands passed\n";
+ for (auto SC : SubCommands) {
+ RSO1 << "\n" << SC;
+ }
+ };
+
+ auto HandleOtherPositionals = [&](ArrayRef<StringRef> Positionals) {
+ ErrMsg.clear();
+ RSO1 << "Unregistered positionals passed\n";
+ for (auto SC : Positionals) {
+ RSO1 << "\n" << SC;
+ }
+ };
+
+ {
+ // Test case 1: Toplevel option, no subcommand
+ const char *Args[] = {"-version"};
+ InputArgList AL = T.ParseArgs(Args, MAI, MAC);
+ EXPECT_TRUE(AL.hasArg(OPT_version));
+ StringRef SC = AL.getSubcommand(
+ T.getSubCommands(), HandleMultipleSubcommands, HandleOtherPositionals);
+ EXPECT_TRUE(SC.empty());
+ EXPECT_FALSE(AL.hasArg(OPT_uppercase));
+ EXPECT_FALSE(AL.hasArg(OPT_lowercase));
+ }
+
+ {
+ // Test case 2: Subcommand 'foo' with its valid options
+ const char *Args[] = {"foo", "-uppercase"};
+ InputArgList AL = T.ParseArgs(Args, MAI, MAC);
+ StringRef SC = AL.getSubcommand(
+ T.getSubCommands(), HandleMultipleSubcommands, HandleOtherPositionals);
+ EXPECT_EQ(SC, "foo");
+ EXPECT_TRUE(AL.hasArg(OPT_uppercase));
+ EXPECT_FALSE(AL.hasArg(OPT_lowercase));
+ EXPECT_FALSE(AL.hasArg(OPT_version));
+ // Do not expect any error messages as this is a valid use case.
----------------
PiJoules wrote:
Since you're using gtest, it might be more verbose if the comment was part of the error message on an expect failure, so something like:
```
EXPECT_EQ(std::string::npos, ErrMsg.find("Multiple subcommands passed")) << "Do not expect any error messages as this is a valid use case.";
```
same might be good for other comments above individual EXPECT lines below.
https://github.com/llvm/llvm-project/pull/155026
More information about the llvm-commits
mailing list