[Lldb-commits] [lldb] [lldb] Fix alias parsing with joined options (PR #190301)
Dave Lee via lldb-commits
lldb-commits at lists.llvm.org
Sat Apr 4 07:22:04 PDT 2026
https://github.com/kastiglione updated https://github.com/llvm/llvm-project/pull/190301
>From 3873abae5ceb98fd5c56dfed85745f8ba195235d Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Thu, 2 Apr 2026 18:57:43 -0700
Subject: [PATCH 1/2] [lldb] Fix alias parsing with joined options
---
lldb/source/Interpreter/Options.cpp | 40 ++++++++++++-------
.../Commands/command-alias-joined-arg.test | 7 ++++
2 files changed, 32 insertions(+), 15 deletions(-)
create mode 100644 lldb/test/Shell/Commands/command-alias-joined-arg.test
diff --git a/lldb/source/Interpreter/Options.cpp b/lldb/source/Interpreter/Options.cpp
index 283c9cc0105a1..54b8edfee4842 100644
--- a/lldb/source/Interpreter/Options.cpp
+++ b/lldb/source/Interpreter/Options.cpp
@@ -21,8 +21,10 @@
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/AnsiTerminal.h"
+#include "lldb/Utility/OptionDefinition.h"
#include "lldb/Utility/StreamString.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorExtras.h"
using namespace lldb;
@@ -887,18 +889,28 @@ static Args ReconstituteArgsAfterParsing(llvm::ArrayRef<char *> parsed,
return result;
}
-static size_t FindArgumentIndexForOption(const Args &args,
- const Option &long_option) {
+/// Find the index of the given option in the arguments. If the option takes an
+/// argument, the second index is the index of the value in args. Otherwise, the
+/// second index is -1.
+static std::pair<size_t, size_t>
+FindArgumentIndexForOption(const Args &args, const Option &long_option) {
std::string short_opt = llvm::formatv("-{0}", char(long_option.val)).str();
std::string long_opt =
- std::string(llvm::formatv("--{0}", long_option.definition->long_option));
+ llvm::formatv("--{0}", long_option.definition->long_option).str();
for (const auto &entry : llvm::enumerate(args)) {
- if (entry.value().ref().starts_with(short_opt) ||
- entry.value().ref().starts_with(long_opt))
- return entry.index();
+ llvm::StringRef arg = entry.value().ref();
+ size_t idx = entry.index();
+ if (long_option.definition->option_has_arg == OptionParser::eNoArgument)
+ return {idx, -1};
+ size_t val_idx;
+ if (arg == short_opt || arg.starts_with(long_opt))
+ val_idx = idx + 1;
+ else if (arg.starts_with(short_opt))
+ val_idx = idx;
+ return {idx, val_idx};
}
- return size_t(-1);
+ return {-1, -1};
}
static std::string BuildShortOptions(const Option *long_options) {
@@ -987,10 +999,9 @@ llvm::Expected<Args> Options::ParseAlias(const Args &args,
StreamString option_str;
option_str.Printf("-%c", val);
- const OptionDefinition *def = long_options[long_options_index].definition;
- int has_arg =
- (def == nullptr) ? OptionParser::eNoArgument : def->option_has_arg;
-
+ const Option &opt = long_options[long_options_index];
+ int has_arg = opt.definition ? opt.definition->option_has_arg
+ : OptionParser::eNoArgument;
const char *option_arg = nullptr;
switch (has_arg) {
case OptionParser::eRequiredArgument:
@@ -1020,12 +1031,11 @@ llvm::Expected<Args> Options::ParseAlias(const Args &args,
// Note: We also need to preserve any option argument values that were
// surrounded by backticks, as we lose track of them in the
// option_args_vector.
- size_t idx =
- FindArgumentIndexForOption(args_copy, long_options[long_options_index]);
+ auto [idx, val_idx] = FindArgumentIndexForOption(args_copy, opt);
std::string option_to_insert;
if (option_arg) {
- if (idx != size_t(-1) && has_arg) {
- bool arg_has_backtick = args_copy[idx + 1].GetQuoteChar() == '`';
+ if (val_idx != size_t(-1) && val_idx < args_copy.size() && has_arg) {
+ bool arg_has_backtick = args_copy[val_idx].GetQuoteChar() == '`';
if (arg_has_backtick)
option_to_insert = "`";
option_to_insert += option_arg;
diff --git a/lldb/test/Shell/Commands/command-alias-joined-arg.test b/lldb/test/Shell/Commands/command-alias-joined-arg.test
new file mode 100644
index 0000000000000..c95672a2cc54a
--- /dev/null
+++ b/lldb/test/Shell/Commands/command-alias-joined-arg.test
@@ -0,0 +1,7 @@
+# Test that command alias with a joined argument (`-P1` in this test) is
+# properly parsed (does not crash).
+
+# RUN: %lldb < %s | FileCheck %s
+command alias vptr frame variable -P1
+help
+# CHECK: {{^ *}}vptr{{ +}}--
>From 4368b23b18adae6ab4f1e8f3b447293304a06ddb Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Sat, 4 Apr 2026 07:18:24 -0700
Subject: [PATCH 2/2] Add and use LLDB_INVALID_INDEX64
---
lldb/include/lldb/lldb-defines.h | 1 +
lldb/source/Interpreter/Options.cpp | 11 ++++++-----
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/lldb/include/lldb/lldb-defines.h b/lldb/include/lldb/lldb-defines.h
index 8e1029387d2da..515f7cff58d8a 100644
--- a/lldb/include/lldb/lldb-defines.h
+++ b/lldb/include/lldb/lldb-defines.h
@@ -81,6 +81,7 @@
#define LLDB_INVALID_STOP_ID 0
#define LLDB_INVALID_ADDRESS UINT64_MAX
#define LLDB_INVALID_INDEX32 UINT32_MAX
+#define LLDB_INVALID_INDEX64 UINT64_MAX
#define LLDB_INVALID_IVAR_OFFSET UINT32_MAX
#define LLDB_INVALID_IMAGE_TOKEN UINT32_MAX
#define LLDB_INVALID_MODULE_VERSION UINT32_MAX
diff --git a/lldb/source/Interpreter/Options.cpp b/lldb/source/Interpreter/Options.cpp
index 54b8edfee4842..cc9f3ebd706fd 100644
--- a/lldb/source/Interpreter/Options.cpp
+++ b/lldb/source/Interpreter/Options.cpp
@@ -23,6 +23,7 @@
#include "lldb/Utility/AnsiTerminal.h"
#include "lldb/Utility/OptionDefinition.h"
#include "lldb/Utility/StreamString.h"
+#include "lldb/lldb-defines.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorExtras.h"
@@ -891,7 +892,7 @@ static Args ReconstituteArgsAfterParsing(llvm::ArrayRef<char *> parsed,
/// Find the index of the given option in the arguments. If the option takes an
/// argument, the second index is the index of the value in args. Otherwise, the
-/// second index is -1.
+/// second index is LLDB_INVALID_INDEX64.
static std::pair<size_t, size_t>
FindArgumentIndexForOption(const Args &args, const Option &long_option) {
std::string short_opt = llvm::formatv("-{0}", char(long_option.val)).str();
@@ -901,7 +902,7 @@ FindArgumentIndexForOption(const Args &args, const Option &long_option) {
llvm::StringRef arg = entry.value().ref();
size_t idx = entry.index();
if (long_option.definition->option_has_arg == OptionParser::eNoArgument)
- return {idx, -1};
+ return {idx, LLDB_INVALID_INDEX64};
size_t val_idx;
if (arg == short_opt || arg.starts_with(long_opt))
val_idx = idx + 1;
@@ -910,7 +911,7 @@ FindArgumentIndexForOption(const Args &args, const Option &long_option) {
return {idx, val_idx};
}
- return {-1, -1};
+ return {LLDB_INVALID_INDEX64, LLDB_INVALID_INDEX64};
}
static std::string BuildShortOptions(const Option *long_options) {
@@ -1034,7 +1035,7 @@ llvm::Expected<Args> Options::ParseAlias(const Args &args,
auto [idx, val_idx] = FindArgumentIndexForOption(args_copy, opt);
std::string option_to_insert;
if (option_arg) {
- if (val_idx != size_t(-1) && val_idx < args_copy.size() && has_arg) {
+ if (val_idx != LLDB_INVALID_INDEX64 && val_idx < args_copy.size()) {
bool arg_has_backtick = args_copy[val_idx].GetQuoteChar() == '`';
if (arg_has_backtick)
option_to_insert = "`";
@@ -1049,7 +1050,7 @@ llvm::Expected<Args> Options::ParseAlias(const Args &args,
option_arg_vector->emplace_back(std::string(option_str.GetString()),
has_arg, option_to_insert);
- if (idx == size_t(-1))
+ if (idx == LLDB_INVALID_INDEX64)
continue;
if (!input_line.empty()) {
More information about the lldb-commits
mailing list