[Lldb-commits] [lldb] [lldb] Add completion support for direct ivars (PR #195187)
Dave Lee via lldb-commits
lldb-commits at lists.llvm.org
Sat May 2 18:07:17 PDT 2026
https://github.com/kastiglione updated https://github.com/llvm/llvm-project/pull/195187
>From d4be48e289dac926b20a001f58ad624fe6068bbd Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Sun, 26 Apr 2026 20:21:20 -0700
Subject: [PATCH 1/3] [lldb] Add completion support for direct ivars
---
lldb/source/Symbol/Variable.cpp | 39 +++++++++++++++++++
.../completion/TestCompletion.py | 8 ++++
2 files changed, 47 insertions(+)
diff --git a/lldb/source/Symbol/Variable.cpp b/lldb/source/Symbol/Variable.cpp
index eb4d740fa7efa..1a9843a3d753d 100644
--- a/lldb/source/Symbol/Variable.cpp
+++ b/lldb/source/Symbol/Variable.cpp
@@ -21,6 +21,7 @@
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ABI.h"
+#include "lldb/Target/Language.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
@@ -475,6 +476,28 @@ static void PrivateAutoComplete(
&prefix_path, // Anything that has been resolved already will be in here
const CompilerType &compiler_type, CompletionRequest &request);
+// Get the CompilerType of the instance variable (this/self) for direct ivar
+// completion. Returns an invalid CompilerType if not in a method context.
+static CompilerType GetInstanceVariableType(StackFrame &frame,
+ VariableList &variable_list) {
+ auto *lang = Language::FindPlugin(frame.GetLanguage().AsLanguageType());
+ if (!lang)
+ return {};
+ llvm::StringRef instance_name = lang->GetInstanceVariableName();
+ if (instance_name.empty())
+ return {};
+ VariableSP var_sp = variable_list.FindVariable(ConstString(instance_name));
+ if (!var_sp)
+ return {};
+ Type *var_type = var_sp->GetType();
+ if (!var_type)
+ return {};
+ CompilerType compiler_type = var_type->GetForwardCompilerType();
+ if (compiler_type.IsPointerType())
+ compiler_type = compiler_type.GetPointeeType();
+ return compiler_type.GetCanonicalType();
+}
+
static void PrivateAutoCompleteMembers(
StackFrame *frame, const std::string &partial_member_name,
llvm::StringRef partial_path,
@@ -598,6 +621,14 @@ static void PrivateAutoComplete(
if (variable_list) {
for (const VariableSP &var_sp : *variable_list)
request.AddCompletion(var_sp->GetName());
+
+ // Offer members of this/self so that direct ivar access can be
+ // completed (eg "frame variable member" for "this->member").
+ CompilerType instance_type =
+ GetInstanceVariableType(*frame, *variable_list);
+ if (instance_type)
+ PrivateAutoCompleteMembers(frame, "", "", "", instance_type,
+ request);
}
}
}
@@ -720,6 +751,14 @@ static void PrivateAutoComplete(
}
}
}
+
+ // Try also completing the token as a member of this/self (direct ivar
+ // access).
+ CompilerType instance_type =
+ GetInstanceVariableType(*frame, *variable_list);
+ if (instance_type)
+ PrivateAutoCompleteMembers(frame, token, remaining_partial_path,
+ prefix_path, instance_type, request);
}
}
break;
diff --git a/lldb/test/API/functionalities/completion/TestCompletion.py b/lldb/test/API/functionalities/completion/TestCompletion.py
index 8a972da9cc902..04253b15c041d 100644
--- a/lldb/test/API/functionalities/completion/TestCompletion.py
+++ b/lldb/test/API/functionalities/completion/TestCompletion.py
@@ -82,6 +82,14 @@ def do_test_variable_completion(self, command):
f"{command} ptr_container->Mem", f"{command} ptr_container->MemberVar"
)
+ def test_frame_variable_direct_ivar(self):
+ """Test that 'frame variable' completes members of 'this' directly."""
+ self.build()
+ lldbutil.run_to_name_breakpoint(self, "Bar")
+ self.completions_contain("frame variable ", ["t", "temp"])
+ self.complete_from_to("frame variable te", "frame variable temp")
+ self.complete_from_to("frame variable t.", "frame variable t.x")
+
def test_process_attach_dash_dash_con(self):
"""Test that 'process attach --con' completes to 'process attach --continue '."""
self.complete_from_to("process attach --con", "process attach --continue ")
>From aed6ab82b89bf4fe50c61203166e8a3c4cff84c4 Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Sat, 2 May 2026 18:06:48 -0700
Subject: [PATCH 2/3] Apply docstring suggestion from @JDevlieghere
Co-authored-by: Jonas Devlieghere <jonas at devlieghere.com>
---
lldb/source/Symbol/Variable.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lldb/source/Symbol/Variable.cpp b/lldb/source/Symbol/Variable.cpp
index 1a9843a3d753d..f1f873cdc403d 100644
--- a/lldb/source/Symbol/Variable.cpp
+++ b/lldb/source/Symbol/Variable.cpp
@@ -476,8 +476,8 @@ static void PrivateAutoComplete(
&prefix_path, // Anything that has been resolved already will be in here
const CompilerType &compiler_type, CompletionRequest &request);
-// Get the CompilerType of the instance variable (this/self) for direct ivar
-// completion. Returns an invalid CompilerType if not in a method context.
+/// Get the CompilerType of the instance variable (this/self) for direct ivar
+/// completion. Returns an invalid CompilerType if not in a method context.
static CompilerType GetInstanceVariableType(StackFrame &frame,
VariableList &variable_list) {
auto *lang = Language::FindPlugin(frame.GetLanguage().AsLanguageType());
>From 7f93fafe4f3e293ba3f7e855e09a91c56817f3b1 Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Sat, 2 May 2026 18:07:08 -0700
Subject: [PATCH 3/3] Apply IsValid suggestion from @JDevlieghere
Co-authored-by: Jonas Devlieghere <jonas at devlieghere.com>
---
lldb/source/Symbol/Variable.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lldb/source/Symbol/Variable.cpp b/lldb/source/Symbol/Variable.cpp
index f1f873cdc403d..fa3da1fc7fdf3 100644
--- a/lldb/source/Symbol/Variable.cpp
+++ b/lldb/source/Symbol/Variable.cpp
@@ -626,7 +626,7 @@ static void PrivateAutoComplete(
// completed (eg "frame variable member" for "this->member").
CompilerType instance_type =
GetInstanceVariableType(*frame, *variable_list);
- if (instance_type)
+ if (instance_type.IsValid())
PrivateAutoCompleteMembers(frame, "", "", "", instance_type,
request);
}
More information about the lldb-commits
mailing list