[Lldb-commits] [lldb] [lldb] Expose language plugin commands based based on language of current frame (PR #136766)
Dave Lee via lldb-commits
lldb-commits at lists.llvm.org
Tue Apr 22 13:58:44 PDT 2025
https://github.com/kastiglione created https://github.com/llvm/llvm-project/pull/136766
None
>From daf394bf76b5fd627f77aee6e451e7d706d26916 Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Tue, 22 Apr 2025 13:58:25 -0700
Subject: [PATCH] [lldb] Expose language plugin commands based based on
language of current frame
---
.../lldb/Interpreter/CommandInterpreter.h | 6 ++
.../source/Interpreter/CommandInterpreter.cpp | 55 ++++++++++++++++++-
2 files changed, 58 insertions(+), 3 deletions(-)
diff --git a/lldb/include/lldb/Interpreter/CommandInterpreter.h b/lldb/include/lldb/Interpreter/CommandInterpreter.h
index 724d88d65f6ac..26e0767951e7f 100644
--- a/lldb/include/lldb/Interpreter/CommandInterpreter.h
+++ b/lldb/include/lldb/Interpreter/CommandInterpreter.h
@@ -730,6 +730,12 @@ class CommandInterpreter : public Broadcaster,
bool EchoCommandNonInteractive(llvm::StringRef line,
const Flags &io_handler_flags) const;
+ /// Return the language specific command object for the current frame.
+ ///
+ /// For example, when stopped on a C++ frame, this returns the command object
+ /// for "language cplusplus" (`CommandObjectMultiwordItaniumABI`).
+ lldb::CommandObjectSP GetFrameLanguageCommand() const;
+
// A very simple state machine which models the command handling transitions
enum class CommandHandlingState {
eIdle,
diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp
index eb4741feb0aa5..2ff02ae5086b4 100644
--- a/lldb/source/Interpreter/CommandInterpreter.cpp
+++ b/lldb/source/Interpreter/CommandInterpreter.cpp
@@ -1018,6 +1018,26 @@ CommandInterpreter::VerifyUserMultiwordCmdPath(Args &path, bool leaf_is_command,
return cur_as_multi;
}
+CommandObjectSP CommandInterpreter::GetFrameLanguageCommand() const {
+ if (auto frame_sp = GetExecutionContext().GetFrameSP()) {
+ auto frame_language = Language::GetPrimaryLanguage(
+ frame_sp->GuessLanguage().AsLanguageType());
+
+ auto it = m_command_dict.find("language");
+ if (it != m_command_dict.end()) {
+ // The root "language" command.
+ CommandObjectSP language_cmd_sp = it->second;
+
+ if (auto *plugin = Language::FindPlugin(frame_language)) {
+ // "cplusplus", "objc", etc.
+ auto lang_name = plugin->GetPluginName();
+ return language_cmd_sp->GetSubcommandSPExact(lang_name);
+ }
+ }
+ }
+ return {};
+}
+
CommandObjectSP
CommandInterpreter::GetCommandSP(llvm::StringRef cmd_str, bool include_aliases,
bool exact, StringList *matches,
@@ -1050,11 +1070,20 @@ CommandInterpreter::GetCommandSP(llvm::StringRef cmd_str, bool include_aliases,
command_sp = pos->second;
}
+ // The `language` subcommand ("language objc", "language cplusplus", etc).
+ CommandObjectMultiword *lang_subcmd = nullptr;
+ if (!command_sp) {
+ if (auto subcmd_sp = GetFrameLanguageCommand()) {
+ lang_subcmd = subcmd_sp->GetAsMultiwordCommand();
+ command_sp = subcmd_sp->GetSubcommandSPExact(cmd_str);
+ }
+ }
+
if (!exact && !command_sp) {
// We will only get into here if we didn't find any exact matches.
CommandObjectSP user_match_sp, user_mw_match_sp, alias_match_sp,
- real_match_sp;
+ real_match_sp, lang_match_sp;
StringList local_matches;
if (matches == nullptr)
@@ -1064,6 +1093,7 @@ CommandInterpreter::GetCommandSP(llvm::StringRef cmd_str, bool include_aliases,
unsigned int num_alias_matches = 0;
unsigned int num_user_matches = 0;
unsigned int num_user_mw_matches = 0;
+ unsigned int num_lang_matches = 0;
// Look through the command dictionaries one by one, and if we get only one
// match from any of them in toto, then return that, otherwise return an
@@ -1121,11 +1151,28 @@ CommandInterpreter::GetCommandSP(llvm::StringRef cmd_str, bool include_aliases,
user_mw_match_sp = pos->second;
}
+ if (lang_subcmd) {
+ num_lang_matches =
+ AddNamesMatchingPartialString(lang_subcmd->GetSubcommandDictionary(),
+ cmd_str, *matches, descriptions);
+ }
+
+ if (num_lang_matches == 1) {
+ cmd.assign(matches->GetStringAtIndex(num_cmd_matches + num_alias_matches +
+ num_user_matches +
+ num_user_mw_matches));
+
+ auto &lang_dict = lang_subcmd->GetSubcommandDictionary();
+ auto pos = lang_dict.find(cmd);
+ if (pos != lang_dict.end())
+ lang_match_sp = pos->second;
+ }
+
// If we got exactly one match, return that, otherwise return the match
// list.
if (num_user_matches + num_user_mw_matches + num_cmd_matches +
- num_alias_matches ==
+ num_alias_matches + num_lang_matches ==
1) {
if (num_cmd_matches)
return real_match_sp;
@@ -1133,8 +1180,10 @@ CommandInterpreter::GetCommandSP(llvm::StringRef cmd_str, bool include_aliases,
return alias_match_sp;
else if (num_user_mw_matches)
return user_mw_match_sp;
- else
+ else if (num_user_matches)
return user_match_sp;
+ else
+ return lang_match_sp;
}
} else if (matches && command_sp) {
matches->AppendString(cmd_str);
More information about the lldb-commits
mailing list