[llvm] 90a6884 - Enable parsing of optional strings (#154364)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 25 12:16:04 PDT 2025
Author: Jacques Pienaar
Date: 2025-09-25T12:16:00-07:00
New Revision: 90a6884f2d088547f7b2650d2151a316b9694f59
URL: https://github.com/llvm/llvm-project/commit/90a6884f2d088547f7b2650d2151a316b9694f59
DIFF: https://github.com/llvm/llvm-project/commit/90a6884f2d088547f7b2650d2151a316b9694f59.diff
LOG: Enable parsing of optional strings (#154364)
Previously a "opt<std::optional<std::string>>>" would fail to
parse/would attempt to parse option value as argument.
Added:
Modified:
llvm/include/llvm/Support/CommandLine.h
llvm/lib/Support/CommandLine.cpp
llvm/unittests/Support/CommandLineTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Support/CommandLine.h b/llvm/include/llvm/Support/CommandLine.h
index b81df756247c9..dd05c530cc06e 100644
--- a/llvm/include/llvm/Support/CommandLine.h
+++ b/llvm/include/llvm/Support/CommandLine.h
@@ -1193,6 +1193,31 @@ class LLVM_ABI parser<std::string> : public basic_parser<std::string> {
//--------------------------------------------------
+template <>
+class LLVM_ABI parser<std::optional<std::string>>
+ : public basic_parser<std::optional<std::string>> {
+public:
+ parser(Option &O) : basic_parser(O) {}
+
+ // Return true on error.
+ bool parse(Option &, StringRef, StringRef Arg,
+ std::optional<std::string> &Value) {
+ Value = Arg.str();
+ return false;
+ }
+
+ // Overload in subclass to provide a better default value.
+ StringRef getValueName() const override { return "optional string"; }
+
+ void printOptionDiff(const Option &O, std::optional<StringRef> V,
+ const OptVal &Default, size_t GlobalWidth) const;
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ void anchor() override;
+};
+
+//--------------------------------------------------
+
extern template class LLVM_TEMPLATE_ABI basic_parser<char>;
template <> class LLVM_ABI parser<char> : public basic_parser<char> {
diff --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp
index 12a8d0c3a6bae..9491ec049f79d 100644
--- a/llvm/lib/Support/CommandLine.cpp
+++ b/llvm/lib/Support/CommandLine.cpp
@@ -101,6 +101,7 @@ void parser<unsigned long long>::anchor() {}
void parser<double>::anchor() {}
void parser<float>::anchor() {}
void parser<std::string>::anchor() {}
+void parser<std::optional<std::string>>::anchor() {}
void parser<char>::anchor() {}
// These anchor functions instantiate opt<T> and reference its virtual
@@ -2261,6 +2262,22 @@ void parser<std::string>::printOptionDiff(const Option &O, StringRef V,
outs() << ")\n";
}
+void parser<std::optional<std::string>>::printOptionDiff(
+ const Option &O, std::optional<StringRef> V,
+ const OptionValue<std::optional<std::string>> &D,
+ size_t GlobalWidth) const {
+ printOptionName(O, GlobalWidth);
+ outs() << "= " << V;
+ size_t VSize = V.has_value() ? V.value().size() : 0;
+ size_t NumSpaces = MaxOptWidth > VSize ? MaxOptWidth - VSize : 0;
+ outs().indent(NumSpaces) << " (default: ";
+ if (D.hasValue() && D.getValue().has_value())
+ outs() << D.getValue();
+ else
+ outs() << "*no value*";
+ outs() << ")\n";
+}
+
// Print a placeholder for options that don't yet support printOptionDiff().
void basic_parser_impl::printOptionNoValue(const Option &O,
size_t GlobalWidth) const {
diff --git a/llvm/unittests/Support/CommandLineTest.cpp b/llvm/unittests/Support/CommandLineTest.cpp
index 88e6445190b59..7f538f155be15 100644
--- a/llvm/unittests/Support/CommandLineTest.cpp
+++ b/llvm/unittests/Support/CommandLineTest.cpp
@@ -2117,6 +2117,22 @@ TEST(CommandLineTest, ConsumeAfterTwoPositionals) {
EXPECT_TRUE(Errs.empty());
}
+TEST(CommandLineTest, ConsumeOptionalString) {
+ cl::ResetCommandLineParser();
+
+ StackOption<std::optional<std::string>, cl::opt<std::optional<std::string>>>
+ Input("input");
+
+ const char *Args[] = {"prog", "--input=\"value\""};
+
+ std::string Errs;
+ raw_string_ostream OS(Errs);
+ ASSERT_TRUE(cl::ParseCommandLineOptions(2, Args, StringRef(), &OS));
+ ASSERT_TRUE(Input.has_value());
+ EXPECT_EQ("\"value\"", *Input);
+ EXPECT_TRUE(Errs.empty());
+}
+
TEST(CommandLineTest, ResetAllOptionOccurrences) {
cl::ResetCommandLineParser();
More information about the llvm-commits
mailing list