[Lldb-commits] [lldb] [LLDB] Update DIL to handle smart pointers; add more tests. (PR #143786)
via lldb-commits
lldb-commits at lists.llvm.org
Thu Jun 19 23:41:08 PDT 2025
https://github.com/cmtice updated https://github.com/llvm/llvm-project/pull/143786
>From 837e8dd36446104b207248c9dbf372a6da6ffbf1 Mon Sep 17 00:00:00 2001
From: Caroline Tice <cmtice at google.com>
Date: Wed, 11 Jun 2025 14:24:17 -0700
Subject: [PATCH 1/6] [LLDB] Update DIL to handle smart pointers; add more
tests.
This updates the DIL implementation to handle smart pointers (accessing
field members and dereferencing) in the same way the current 'frame
variable' implementation does. It also adds tests for handling smart pointers,
as well as some additional DIL tests.
---
lldb/source/ValueObject/DILEval.cpp | 9 +++-
.../frame/var-dil/basics/BitField/Makefile | 3 ++
.../BitField/TestFrameVarDILBitField.py | 38 ++++++++++++++++
.../frame/var-dil/basics/BitField/main.cpp | 44 +++++++++++++++++++
.../frame/var-dil/basics/Indirection/Makefile | 3 ++
.../Indirection/TestFrameVarDILIndirection.py | 36 +++++++++++++++
.../frame/var-dil/basics/Indirection/main.cpp | 14 ++++++
.../basics/PointerDereference/Makefile | 3 ++
.../TestFrameVarDILPointerDereference.py | 30 +++++++++++++
.../basics/PointerDereference/main.cpp | 32 ++++++++++++++
.../frame/var-dil/basics/QualifiedId/Makefile | 3 ++
.../QualifiedId/TestFrameVarDILQualifiedId.py | 29 ++++++++++++
.../frame/var-dil/basics/QualifiedId/main.cpp | 18 ++++++++
.../frame/var-dil/basics/SharedPtr/Makefile | 6 +++
.../SharedPtr/TestFrameVarDILSharedPtr.py | 36 +++++++++++++++
.../TestFrameVarDILSharedPtrDeref.py | 29 ++++++++++++
.../frame/var-dil/basics/SharedPtr/main.cpp | 26 +++++++++++
.../frame/var-dil/basics/UniquePtr/Makefile | 6 +++
.../UniquePtr/TestFrameVarDILUniquePtr.py | 28 ++++++++++++
.../TestFrameVarDILUniquePtrDeref.py | 29 ++++++++++++
.../frame/var-dil/basics/UniquePtr/main.cpp | 25 +++++++++++
21 files changed, 446 insertions(+), 1 deletion(-)
create mode 100644 lldb/test/API/commands/frame/var-dil/basics/BitField/Makefile
create mode 100644 lldb/test/API/commands/frame/var-dil/basics/BitField/TestFrameVarDILBitField.py
create mode 100644 lldb/test/API/commands/frame/var-dil/basics/BitField/main.cpp
create mode 100644 lldb/test/API/commands/frame/var-dil/basics/Indirection/Makefile
create mode 100644 lldb/test/API/commands/frame/var-dil/basics/Indirection/TestFrameVarDILIndirection.py
create mode 100644 lldb/test/API/commands/frame/var-dil/basics/Indirection/main.cpp
create mode 100644 lldb/test/API/commands/frame/var-dil/basics/PointerDereference/Makefile
create mode 100644 lldb/test/API/commands/frame/var-dil/basics/PointerDereference/TestFrameVarDILPointerDereference.py
create mode 100644 lldb/test/API/commands/frame/var-dil/basics/PointerDereference/main.cpp
create mode 100644 lldb/test/API/commands/frame/var-dil/basics/QualifiedId/Makefile
create mode 100644 lldb/test/API/commands/frame/var-dil/basics/QualifiedId/TestFrameVarDILQualifiedId.py
create mode 100644 lldb/test/API/commands/frame/var-dil/basics/QualifiedId/main.cpp
create mode 100644 lldb/test/API/commands/frame/var-dil/basics/SharedPtr/Makefile
create mode 100644 lldb/test/API/commands/frame/var-dil/basics/SharedPtr/TestFrameVarDILSharedPtr.py
create mode 100644 lldb/test/API/commands/frame/var-dil/basics/SharedPtr/TestFrameVarDILSharedPtrDeref.py
create mode 100644 lldb/test/API/commands/frame/var-dil/basics/SharedPtr/main.cpp
create mode 100644 lldb/test/API/commands/frame/var-dil/basics/UniquePtr/Makefile
create mode 100644 lldb/test/API/commands/frame/var-dil/basics/UniquePtr/TestFrameVarDILUniquePtr.py
create mode 100644 lldb/test/API/commands/frame/var-dil/basics/UniquePtr/TestFrameVarDILUniquePtrDeref.py
create mode 100644 lldb/test/API/commands/frame/var-dil/basics/UniquePtr/main.cpp
diff --git a/lldb/source/ValueObject/DILEval.cpp b/lldb/source/ValueObject/DILEval.cpp
index c8cb54aa18a93..adc34e25766b3 100644
--- a/lldb/source/ValueObject/DILEval.cpp
+++ b/lldb/source/ValueObject/DILEval.cpp
@@ -253,6 +253,12 @@ Interpreter::Visit(const UnaryOpNode *node) {
rhs = dynamic_rhs;
lldb::ValueObjectSP child_sp = rhs->Dereference(error);
+ if (!child_sp && m_use_synthetic) {
+ if (lldb::ValueObjectSP synth_obj_sp = rhs->GetSyntheticValue()) {
+ error.Clear();
+ child_sp = synth_obj_sp->Dereference(error);
+ }
+ }
if (error.Fail())
return llvm::make_error<DILDiagnosticError>(m_expr, error.AsCString(),
node->GetLocation());
@@ -280,6 +286,7 @@ Interpreter::Visit(const MemberOfNode *node) {
auto base_or_err = Evaluate(node->GetBase());
if (!base_or_err)
return base_or_err;
+ bool expr_is_ptr = node->GetIsArrow();
lldb::ValueObjectSP base = *base_or_err;
// Perform some basic type & correctness checking.
@@ -319,11 +326,11 @@ Interpreter::Visit(const MemberOfNode *node) {
return llvm::make_error<DILDiagnosticError>(
m_expr, errMsg, node->GetLocation(), node->GetFieldName().size());
}
+ expr_is_ptr = false;
}
}
if (m_check_ptr_vs_member) {
- bool expr_is_ptr = node->GetIsArrow();
bool base_is_ptr = base->IsPointerType();
if (expr_is_ptr != base_is_ptr) {
diff --git a/lldb/test/API/commands/frame/var-dil/basics/BitField/Makefile b/lldb/test/API/commands/frame/var-dil/basics/BitField/Makefile
new file mode 100644
index 0000000000000..99998b20bcb05
--- /dev/null
+++ b/lldb/test/API/commands/frame/var-dil/basics/BitField/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/commands/frame/var-dil/basics/BitField/TestFrameVarDILBitField.py b/lldb/test/API/commands/frame/var-dil/basics/BitField/TestFrameVarDILBitField.py
new file mode 100644
index 0000000000000..8b08ec7f62d5c
--- /dev/null
+++ b/lldb/test/API/commands/frame/var-dil/basics/BitField/TestFrameVarDILBitField.py
@@ -0,0 +1,38 @@
+"""
+Make sure 'frame var' using DIL parser/evaluator works for bit fields.
+"""
+
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+from lldbsuite.test import lldbutil
+
+import os
+import shutil
+import time
+
+class TestFrameVarDILBitField(TestBase):
+ # If your test case doesn't stress debug info, then
+ # set this to true. That way it won't be run once for
+ # each debug info format.
+ NO_DEBUG_INFO_TESTCASE = True
+
+ def test_frame_var(self):
+ self.build()
+ lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here",
+ lldb.SBFileSpec("main.cpp"))
+
+ self.runCmd("settings set target.experimental.use-DIL true")
+ self.expect_var_path("bf.a", value="1023")
+ self.expect_var_path("bf.b", value="9")
+ self.expect_var_path("bf.c", value="false")
+ self.expect_var_path("bf.d", value="true")
+
+ self.expect_var_path("abf.a", value="1023")
+ self.expect_var_path("abf.b", value="'\\x0f'")
+ self.expect_var_path("abf.c", value="3")
+
+ # Perform an operation to ensure we actually read the value.
+ # Address-of is not allowed for bit-fields.
+ self.expect("frame variable '&bf.a'", error=True,
+ substrs=["'bf.a' doesn't have a valid address"])
diff --git a/lldb/test/API/commands/frame/var-dil/basics/BitField/main.cpp b/lldb/test/API/commands/frame/var-dil/basics/BitField/main.cpp
new file mode 100644
index 0000000000000..bd9b23a44ebbe
--- /dev/null
+++ b/lldb/test/API/commands/frame/var-dil/basics/BitField/main.cpp
@@ -0,0 +1,44 @@
+#include <cstdint>
+
+int
+main(int argc, char **argv)
+{
+ enum BitFieldEnum : uint32_t { kZero, kOne };
+
+ struct BitFieldStruct {
+ uint16_t a : 10;
+ uint32_t b : 4;
+ bool c : 1;
+ bool d : 1;
+ int32_t e : 32;
+ uint32_t f : 32;
+ uint32_t g : 31;
+ uint64_t h : 31;
+ uint64_t i : 33;
+ BitFieldEnum j : 10;
+ };
+
+ BitFieldStruct bf;
+ bf.a = 0b1111111111;
+ bf.b = 0b1001;
+ bf.c = 0b0;
+ bf.d = 0b1;
+ bf.e = 0b1;
+ bf.f = 0b1;
+ bf.g = 0b1;
+ bf.h = 0b1;
+ bf.i = 0b1;
+ bf.j = BitFieldEnum::kOne;
+
+ struct AlignedBitFieldStruct {
+ uint16_t a : 10;
+ uint8_t b : 4;
+ unsigned char : 0;
+ uint16_t c : 2;
+ };
+
+ uint32_t data = ~0;
+ AlignedBitFieldStruct abf = (AlignedBitFieldStruct&)data;
+
+ return 0; // Set a breakpoint here
+}
diff --git a/lldb/test/API/commands/frame/var-dil/basics/Indirection/Makefile b/lldb/test/API/commands/frame/var-dil/basics/Indirection/Makefile
new file mode 100644
index 0000000000000..99998b20bcb05
--- /dev/null
+++ b/lldb/test/API/commands/frame/var-dil/basics/Indirection/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/commands/frame/var-dil/basics/Indirection/TestFrameVarDILIndirection.py b/lldb/test/API/commands/frame/var-dil/basics/Indirection/TestFrameVarDILIndirection.py
new file mode 100644
index 0000000000000..13acc4232bd7c
--- /dev/null
+++ b/lldb/test/API/commands/frame/var-dil/basics/Indirection/TestFrameVarDILIndirection.py
@@ -0,0 +1,36 @@
+"""
+Make sure 'frame var' using DIL parser/evaluator works for indirection.
+"""
+
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+from lldbsuite.test import lldbutil
+
+import os
+import shutil
+import time
+
+class TestFrameVarDILIndirection(TestBase):
+ # If your test case doesn't stress debug info, then
+ # set this to true. That way it won't be run once for
+ # each debug info format.
+ NO_DEBUG_INFO_TESTCASE = True
+
+ def test_frame_var(self):
+ self.build()
+ lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here",
+ lldb.SBFileSpec("main.cpp"))
+
+ self.runCmd("settings set target.experimental.use-DIL true")
+ self.expect_var_path("*p", value="1")
+ self.expect_var_path("p", type="int *")
+ self.expect_var_path("*my_p", value="1")
+ self.expect_var_path("my_p", type="myp")
+ self.expect_var_path("*my_pr", type="int *")
+ self.expect_var_path("my_pr", type="mypr")
+
+ self.expect("frame variable '*1'", error=True,
+ substrs=["Unexpected token: <'1' (numeric_constant)>"])
+ self.expect("frame variable '*val'", error=True,
+ substrs=["dereference failed: not a pointer, reference or array type: (int) val"])
diff --git a/lldb/test/API/commands/frame/var-dil/basics/Indirection/main.cpp b/lldb/test/API/commands/frame/var-dil/basics/Indirection/main.cpp
new file mode 100644
index 0000000000000..827968a71519a
--- /dev/null
+++ b/lldb/test/API/commands/frame/var-dil/basics/Indirection/main.cpp
@@ -0,0 +1,14 @@
+int
+main(int argc, char **argv)
+{
+ int val = 1;
+ int* p = &val;
+
+ typedef int* myp;
+ myp my_p = &val;
+
+ typedef int*& mypr;
+ mypr my_pr = p;
+
+ return 0; // Set a breakpoint here
+}
diff --git a/lldb/test/API/commands/frame/var-dil/basics/PointerDereference/Makefile b/lldb/test/API/commands/frame/var-dil/basics/PointerDereference/Makefile
new file mode 100644
index 0000000000000..99998b20bcb05
--- /dev/null
+++ b/lldb/test/API/commands/frame/var-dil/basics/PointerDereference/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/commands/frame/var-dil/basics/PointerDereference/TestFrameVarDILPointerDereference.py b/lldb/test/API/commands/frame/var-dil/basics/PointerDereference/TestFrameVarDILPointerDereference.py
new file mode 100644
index 0000000000000..7f5acc26dd40b
--- /dev/null
+++ b/lldb/test/API/commands/frame/var-dil/basics/PointerDereference/TestFrameVarDILPointerDereference.py
@@ -0,0 +1,30 @@
+"""
+Test DIL pointer dereferencing.
+"""
+
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+from lldbsuite.test import lldbutil
+
+import os
+import shutil
+import time
+
+class TestFrameVarDILPointerDereference(TestBase):
+ NO_DEBUG_INFO_TESTCASE = True
+
+ def test_frame_var(self):
+ self.build()
+ lldbutil.run_to_source_breakpoint(
+ self, "Set a breakpoint here", lldb.SBFileSpec("main.cpp")
+ )
+
+ self.runCmd("settings set target.experimental.use-DIL true")
+ self.expect_var_path("*p_int0", value="0")
+ self.expect_var_path("*cp_int5", value="5")
+ self.expect_var_path("&pp_void0[2]", type="void **")
+ self.expect_var_path("**pp_int0", value="0")
+ self.expect_var_path("&**pp_int0", type="int *")
+ self.expect("frame variable '&p_void[0]'", error=True,
+ substrs=["subscript of pointer to incomplete type 'void'"])
diff --git a/lldb/test/API/commands/frame/var-dil/basics/PointerDereference/main.cpp b/lldb/test/API/commands/frame/var-dil/basics/PointerDereference/main.cpp
new file mode 100644
index 0000000000000..719fa81b60830
--- /dev/null
+++ b/lldb/test/API/commands/frame/var-dil/basics/PointerDereference/main.cpp
@@ -0,0 +1,32 @@
+#include <cstddef>
+
+int main (int argc, char **argv) {
+ int* p_null = nullptr;
+ const char* p_char1 = "hello";
+
+ typedef const char* my_char_ptr;
+ my_char_ptr my_p_char1 = p_char1;
+
+ int offset = 5;
+ int array[10];
+ array[0] = 0;
+ array[offset] = offset;
+
+ int(&array_ref)[10] = array;
+
+ int* p_int0 = &array[0];
+ int** pp_int0 = &p_int0;
+ const int* cp_int0 = &array[0];
+ const int* cp_int5 = &array[offset];
+
+ typedef int* td_int_ptr_t;
+ td_int_ptr_t td_int_ptr0 = &array[0];
+
+ void* p_void = (void*)p_char1;
+ void** pp_void0 = &p_void;
+ void** pp_void1 = pp_void0 + 1;
+
+ std::nullptr_t std_nullptr_t = nullptr;
+
+ return 0; // Set a breakpoint here
+}
diff --git a/lldb/test/API/commands/frame/var-dil/basics/QualifiedId/Makefile b/lldb/test/API/commands/frame/var-dil/basics/QualifiedId/Makefile
new file mode 100644
index 0000000000000..99998b20bcb05
--- /dev/null
+++ b/lldb/test/API/commands/frame/var-dil/basics/QualifiedId/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/commands/frame/var-dil/basics/QualifiedId/TestFrameVarDILQualifiedId.py b/lldb/test/API/commands/frame/var-dil/basics/QualifiedId/TestFrameVarDILQualifiedId.py
new file mode 100644
index 0000000000000..3d91198ea3ab9
--- /dev/null
+++ b/lldb/test/API/commands/frame/var-dil/basics/QualifiedId/TestFrameVarDILQualifiedId.py
@@ -0,0 +1,29 @@
+"""
+Make sure 'frame var' using DIL parser/evaluator works for namespaces.
+"""
+
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+from lldbsuite.test import lldbutil
+
+import os
+import shutil
+import time
+
+class TestFrameVarDILQualifiedId(TestBase):
+ # If your test case doesn't stress debug info, then
+ # set this to true. That way it won't be run once for
+ # each debug info format.
+ NO_DEBUG_INFO_TESTCASE = True
+
+ def test_frame_var(self):
+ self.build()
+ lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here",
+ lldb.SBFileSpec("main.cpp"))
+
+ self.runCmd("settings set target.experimental.use-DIL true")
+ self.expect_var_path("::ns::i", value="1")
+ self.expect_var_path("ns::i", value="1")
+ self.expect_var_path("::ns::ns::i", value="2")
+ self.expect_var_path("ns::ns::i", value="2")
diff --git a/lldb/test/API/commands/frame/var-dil/basics/QualifiedId/main.cpp b/lldb/test/API/commands/frame/var-dil/basics/QualifiedId/main.cpp
new file mode 100644
index 0000000000000..3316d0b807868
--- /dev/null
+++ b/lldb/test/API/commands/frame/var-dil/basics/QualifiedId/main.cpp
@@ -0,0 +1,18 @@
+namespace ns {
+
+int i = 1;
+
+namespace ns {
+
+int i = 2;
+
+} // namespace ns
+
+} // namespace ns
+
+int
+main(int argc, char **argv)
+{
+
+ return 0; // Set a breakpoint here
+}
diff --git a/lldb/test/API/commands/frame/var-dil/basics/SharedPtr/Makefile b/lldb/test/API/commands/frame/var-dil/basics/SharedPtr/Makefile
new file mode 100644
index 0000000000000..af1baa7931b39
--- /dev/null
+++ b/lldb/test/API/commands/frame/var-dil/basics/SharedPtr/Makefile
@@ -0,0 +1,6 @@
+CXX_SOURCES := main.cpp
+CXXFLAGS_EXTRAS := -std=c++14
+
+USE_LIBCPP := 1
+
+include Makefile.rules
diff --git a/lldb/test/API/commands/frame/var-dil/basics/SharedPtr/TestFrameVarDILSharedPtr.py b/lldb/test/API/commands/frame/var-dil/basics/SharedPtr/TestFrameVarDILSharedPtr.py
new file mode 100644
index 0000000000000..94fe0340dc98c
--- /dev/null
+++ b/lldb/test/API/commands/frame/var-dil/basics/SharedPtr/TestFrameVarDILSharedPtr.py
@@ -0,0 +1,36 @@
+"""
+Make sure 'frame var' using DIL parser/evaluator works for shared/weak pointers.
+"""
+
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+from lldbsuite.test import lldbutil
+
+import os
+import shutil
+import time
+
+class TestFrameVarDILSharedPtr(TestBase):
+ # If your test case doesn't stress debug info, then
+ # set this to true. That way it won't be run once for
+ # each debug info format.
+ NO_DEBUG_INFO_TESTCASE = True
+
+ def test_frame_var(self):
+ self.build()
+ lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here",
+ lldb.SBFileSpec("main.cpp"))
+
+ self.runCmd("settings set target.experimental.use-DIL true")
+ self.expect_var_path("ptr_node.__ptr_",
+ type="std::shared_ptr<NodeS>::element_type *")
+ self.expect_var_path("ptr_node.__ptr_->value", value="1")
+ self.expect_var_path("ptr_node.__ptr_->next.__ptr_->value", value="2")
+
+ self.expect_var_path("ptr_int.__ptr_",
+ type="std::shared_ptr<int>::element_type *")
+ self.expect_var_path("*ptr_int.__ptr_", value="1")
+ self.expect_var_path("ptr_int_weak.__ptr_",
+ type="std::weak_ptr<int>::element_type *")
+ self.expect_var_path("*ptr_int_weak.__ptr_", value="1")
diff --git a/lldb/test/API/commands/frame/var-dil/basics/SharedPtr/TestFrameVarDILSharedPtrDeref.py b/lldb/test/API/commands/frame/var-dil/basics/SharedPtr/TestFrameVarDILSharedPtrDeref.py
new file mode 100644
index 0000000000000..32b389bec8fa4
--- /dev/null
+++ b/lldb/test/API/commands/frame/var-dil/basics/SharedPtr/TestFrameVarDILSharedPtrDeref.py
@@ -0,0 +1,29 @@
+"""
+Make sure 'frame var' using DIL parser/evaluator works for shared pointer deref.
+"""
+
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+from lldbsuite.test import lldbutil
+
+import os
+import shutil
+import time
+
+class TestFrameVarDILSharedPtrDeref(TestBase):
+ # If your test case doesn't stress debug info, then
+ # set this to true. That way it won't be run once for
+ # each debug info format.
+ NO_DEBUG_INFO_TESTCASE = True
+
+ def test_frame_var(self):
+ self.build()
+ lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here",
+ lldb.SBFileSpec("main.cpp"))
+
+ self.runCmd("settings set target.experimental.use-DIL true")
+ self.expect_var_path("ptr_node->value", value="1")
+ self.expect_var_path("ptr_node->next->value", value="2")
+ self.expect_var_path("(*ptr_node).value", value="1")
+ self.expect_var_path("(*(*ptr_node).next).value", value="2")
diff --git a/lldb/test/API/commands/frame/var-dil/basics/SharedPtr/main.cpp b/lldb/test/API/commands/frame/var-dil/basics/SharedPtr/main.cpp
new file mode 100644
index 0000000000000..642f5172a37f6
--- /dev/null
+++ b/lldb/test/API/commands/frame/var-dil/basics/SharedPtr/main.cpp
@@ -0,0 +1,26 @@
+#include <memory>
+
+int
+main(int argc, char **argv)
+{
+
+ struct NodeS {
+ std::shared_ptr<NodeS> next;
+ int value;
+ };
+ auto ptr_node = std::shared_ptr<NodeS>(new NodeS{nullptr, 2});
+ ptr_node = std::shared_ptr<NodeS>(new NodeS{std::move(ptr_node), 1});
+
+ std::shared_ptr<char> ptr_null;
+ auto ptr_int = std::make_shared<int>(1);
+ auto ptr_float = std::make_shared<float>(1.1f);
+
+ std::weak_ptr<int> ptr_int_weak = ptr_int;
+
+ std::shared_ptr<void> ptr_void = ptr_int;
+
+ // TestSharedPtr
+ // TestSharedPtrDeref
+ // TestSharedPtrCompare
+ return 0; // Set a breakpoint here
+}
diff --git a/lldb/test/API/commands/frame/var-dil/basics/UniquePtr/Makefile b/lldb/test/API/commands/frame/var-dil/basics/UniquePtr/Makefile
new file mode 100644
index 0000000000000..af1baa7931b39
--- /dev/null
+++ b/lldb/test/API/commands/frame/var-dil/basics/UniquePtr/Makefile
@@ -0,0 +1,6 @@
+CXX_SOURCES := main.cpp
+CXXFLAGS_EXTRAS := -std=c++14
+
+USE_LIBCPP := 1
+
+include Makefile.rules
diff --git a/lldb/test/API/commands/frame/var-dil/basics/UniquePtr/TestFrameVarDILUniquePtr.py b/lldb/test/API/commands/frame/var-dil/basics/UniquePtr/TestFrameVarDILUniquePtr.py
new file mode 100644
index 0000000000000..b7f9627f8a8c0
--- /dev/null
+++ b/lldb/test/API/commands/frame/var-dil/basics/UniquePtr/TestFrameVarDILUniquePtr.py
@@ -0,0 +1,28 @@
+"""
+Make sure 'frame var' using DIL parser/evaluator works for unique pointers.
+"""
+
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+from lldbsuite.test import lldbutil
+
+import os
+import shutil
+import time
+
+class TestFrameVarDILUniquePtr(TestBase):
+ # If your test case doesn't stress debug info, then
+ # set this to true. That way it won't be run once for
+ # each debug info format.
+ NO_DEBUG_INFO_TESTCASE = True
+
+ def test_frame_var(self):
+ self.build()
+ lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here",
+ lldb.SBFileSpec("main.cpp"))
+
+ self.runCmd("settings set target.experimental.use-DIL true")
+ self.expect_var_path("ptr_node.__ptr_", type="NodeU *")
+ self.expect_var_path("ptr_node.__ptr_->value", value="1")
+ self.expect_var_path("ptr_node.__ptr_->next.__ptr_->value", value="2")
diff --git a/lldb/test/API/commands/frame/var-dil/basics/UniquePtr/TestFrameVarDILUniquePtrDeref.py b/lldb/test/API/commands/frame/var-dil/basics/UniquePtr/TestFrameVarDILUniquePtrDeref.py
new file mode 100644
index 0000000000000..065fb9df33444
--- /dev/null
+++ b/lldb/test/API/commands/frame/var-dil/basics/UniquePtr/TestFrameVarDILUniquePtrDeref.py
@@ -0,0 +1,29 @@
+"""
+Make sure 'frame var' using DIL parser/evaluator works for unique pointer derefs.
+"""
+
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+from lldbsuite.test import lldbutil
+
+import os
+import shutil
+import time
+
+class TestFrameVarDILUniquePtrDeref(TestBase):
+ # If your test case doesn't stress debug info, then
+ # set this to true. That way it won't be run once for
+ # each debug info format.
+ NO_DEBUG_INFO_TESTCASE = True
+
+ def test_frame_var(self):
+ self.build()
+ lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here",
+ lldb.SBFileSpec("main.cpp"))
+
+ self.runCmd("settings set target.experimental.use-DIL true")
+ self.expect_var_path("ptr_node->value", value="1")
+ self.expect_var_path("ptr_node->next->value", value="2")
+ self.expect_var_path("(*ptr_node).value", value="1")
+ self.expect_var_path("(*(*ptr_node).next).value", value="2")
diff --git a/lldb/test/API/commands/frame/var-dil/basics/UniquePtr/main.cpp b/lldb/test/API/commands/frame/var-dil/basics/UniquePtr/main.cpp
new file mode 100644
index 0000000000000..f20f6f116a084
--- /dev/null
+++ b/lldb/test/API/commands/frame/var-dil/basics/UniquePtr/main.cpp
@@ -0,0 +1,25 @@
+#include <memory>
+
+int
+main(int argc, char **argv)
+{
+
+ struct NodeU {
+ std::unique_ptr<NodeU> next;
+ int value;
+ };
+ auto ptr_node = std::unique_ptr<NodeU>(new NodeU{nullptr, 2});
+ ptr_node = std::unique_ptr<NodeU>(new NodeU{std::move(ptr_node), 1});
+
+ std::unique_ptr<char> ptr_null;
+ auto ptr_int = std::make_unique<int>(1);
+ auto ptr_float = std::make_unique<float>(1.1f);
+
+ auto deleter = [](void const* data) { delete static_cast<int const*>(data); };
+ std::unique_ptr<void, decltype(deleter)> ptr_void(new int(42), deleter);
+
+ // TestUniquePtr
+ // TestUniquePtrDeref
+ // TestUniquePtrCompare
+ return 0; // Set a breakpoint here
+}
>From dde59df42dfbffe4e6cacbbaa16fbf5a0d6c9638 Mon Sep 17 00:00:00 2001
From: Caroline Tice <cmtice at google.com>
Date: Sun, 15 Jun 2025 22:22:09 -0700
Subject: [PATCH 2/6] Remove tests that depend on internals of smart ptr
implementation.
---
.../SharedPtr/TestFrameVarDILSharedPtr.py | 36 -------------------
.../UniquePtr/TestFrameVarDILUniquePtr.py | 28 ---------------
2 files changed, 64 deletions(-)
delete mode 100644 lldb/test/API/commands/frame/var-dil/basics/SharedPtr/TestFrameVarDILSharedPtr.py
delete mode 100644 lldb/test/API/commands/frame/var-dil/basics/UniquePtr/TestFrameVarDILUniquePtr.py
diff --git a/lldb/test/API/commands/frame/var-dil/basics/SharedPtr/TestFrameVarDILSharedPtr.py b/lldb/test/API/commands/frame/var-dil/basics/SharedPtr/TestFrameVarDILSharedPtr.py
deleted file mode 100644
index 94fe0340dc98c..0000000000000
--- a/lldb/test/API/commands/frame/var-dil/basics/SharedPtr/TestFrameVarDILSharedPtr.py
+++ /dev/null
@@ -1,36 +0,0 @@
-"""
-Make sure 'frame var' using DIL parser/evaluator works for shared/weak pointers.
-"""
-
-import lldb
-from lldbsuite.test.lldbtest import *
-from lldbsuite.test.decorators import *
-from lldbsuite.test import lldbutil
-
-import os
-import shutil
-import time
-
-class TestFrameVarDILSharedPtr(TestBase):
- # If your test case doesn't stress debug info, then
- # set this to true. That way it won't be run once for
- # each debug info format.
- NO_DEBUG_INFO_TESTCASE = True
-
- def test_frame_var(self):
- self.build()
- lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here",
- lldb.SBFileSpec("main.cpp"))
-
- self.runCmd("settings set target.experimental.use-DIL true")
- self.expect_var_path("ptr_node.__ptr_",
- type="std::shared_ptr<NodeS>::element_type *")
- self.expect_var_path("ptr_node.__ptr_->value", value="1")
- self.expect_var_path("ptr_node.__ptr_->next.__ptr_->value", value="2")
-
- self.expect_var_path("ptr_int.__ptr_",
- type="std::shared_ptr<int>::element_type *")
- self.expect_var_path("*ptr_int.__ptr_", value="1")
- self.expect_var_path("ptr_int_weak.__ptr_",
- type="std::weak_ptr<int>::element_type *")
- self.expect_var_path("*ptr_int_weak.__ptr_", value="1")
diff --git a/lldb/test/API/commands/frame/var-dil/basics/UniquePtr/TestFrameVarDILUniquePtr.py b/lldb/test/API/commands/frame/var-dil/basics/UniquePtr/TestFrameVarDILUniquePtr.py
deleted file mode 100644
index b7f9627f8a8c0..0000000000000
--- a/lldb/test/API/commands/frame/var-dil/basics/UniquePtr/TestFrameVarDILUniquePtr.py
+++ /dev/null
@@ -1,28 +0,0 @@
-"""
-Make sure 'frame var' using DIL parser/evaluator works for unique pointers.
-"""
-
-import lldb
-from lldbsuite.test.lldbtest import *
-from lldbsuite.test.decorators import *
-from lldbsuite.test import lldbutil
-
-import os
-import shutil
-import time
-
-class TestFrameVarDILUniquePtr(TestBase):
- # If your test case doesn't stress debug info, then
- # set this to true. That way it won't be run once for
- # each debug info format.
- NO_DEBUG_INFO_TESTCASE = True
-
- def test_frame_var(self):
- self.build()
- lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here",
- lldb.SBFileSpec("main.cpp"))
-
- self.runCmd("settings set target.experimental.use-DIL true")
- self.expect_var_path("ptr_node.__ptr_", type="NodeU *")
- self.expect_var_path("ptr_node.__ptr_->value", value="1")
- self.expect_var_path("ptr_node.__ptr_->next.__ptr_->value", value="2")
>From 7dc28d7cce514f46f45370e22873542570001b3b Mon Sep 17 00:00:00 2001
From: Caroline Tice <cmtice at google.com>
Date: Sun, 15 Jun 2025 22:59:55 -0700
Subject: [PATCH 3/6] Fix clang-format issues with tests.
---
.../BitField/TestFrameVarDILBitField.py | 13 +++++++---
.../frame/var-dil/basics/BitField/main.cpp | 6 ++---
.../Indirection/TestFrameVarDILIndirection.py | 22 +++++++++++-----
.../frame/var-dil/basics/Indirection/main.cpp | 10 +++----
.../TestFrameVarDILPointerDereference.py | 8 ++++--
.../basics/PointerDereference/main.cpp | 26 +++++++++----------
.../QualifiedId/TestFrameVarDILQualifiedId.py | 6 +++--
.../frame/var-dil/basics/QualifiedId/main.cpp | 8 +++---
.../TestFrameVarDILSharedPtrDeref.py | 6 +++--
.../frame/var-dil/basics/SharedPtr/main.cpp | 4 +--
.../TestFrameVarDILUniquePtrDeref.py | 6 +++--
.../frame/var-dil/basics/UniquePtr/main.cpp | 8 +++---
12 files changed, 70 insertions(+), 53 deletions(-)
diff --git a/lldb/test/API/commands/frame/var-dil/basics/BitField/TestFrameVarDILBitField.py b/lldb/test/API/commands/frame/var-dil/basics/BitField/TestFrameVarDILBitField.py
index 8b08ec7f62d5c..0e35069519093 100644
--- a/lldb/test/API/commands/frame/var-dil/basics/BitField/TestFrameVarDILBitField.py
+++ b/lldb/test/API/commands/frame/var-dil/basics/BitField/TestFrameVarDILBitField.py
@@ -11,6 +11,7 @@
import shutil
import time
+
class TestFrameVarDILBitField(TestBase):
# If your test case doesn't stress debug info, then
# set this to true. That way it won't be run once for
@@ -19,8 +20,9 @@ class TestFrameVarDILBitField(TestBase):
def test_frame_var(self):
self.build()
- lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here",
- lldb.SBFileSpec("main.cpp"))
+ lldbutil.run_to_source_breakpoint(
+ self, "Set a breakpoint here", lldb.SBFileSpec("main.cpp")
+ )
self.runCmd("settings set target.experimental.use-DIL true")
self.expect_var_path("bf.a", value="1023")
@@ -34,5 +36,8 @@ def test_frame_var(self):
# Perform an operation to ensure we actually read the value.
# Address-of is not allowed for bit-fields.
- self.expect("frame variable '&bf.a'", error=True,
- substrs=["'bf.a' doesn't have a valid address"])
+ self.expect(
+ "frame variable '&bf.a'",
+ error=True,
+ substrs=["'bf.a' doesn't have a valid address"],
+ )
diff --git a/lldb/test/API/commands/frame/var-dil/basics/BitField/main.cpp b/lldb/test/API/commands/frame/var-dil/basics/BitField/main.cpp
index bd9b23a44ebbe..5705cfb2df642 100644
--- a/lldb/test/API/commands/frame/var-dil/basics/BitField/main.cpp
+++ b/lldb/test/API/commands/frame/var-dil/basics/BitField/main.cpp
@@ -1,8 +1,6 @@
#include <cstdint>
-int
-main(int argc, char **argv)
-{
+int main(int argc, char **argv) {
enum BitFieldEnum : uint32_t { kZero, kOne };
struct BitFieldStruct {
@@ -38,7 +36,7 @@ main(int argc, char **argv)
};
uint32_t data = ~0;
- AlignedBitFieldStruct abf = (AlignedBitFieldStruct&)data;
+ AlignedBitFieldStruct abf = (AlignedBitFieldStruct &)data;
return 0; // Set a breakpoint here
}
diff --git a/lldb/test/API/commands/frame/var-dil/basics/Indirection/TestFrameVarDILIndirection.py b/lldb/test/API/commands/frame/var-dil/basics/Indirection/TestFrameVarDILIndirection.py
index 13acc4232bd7c..38c72131d797c 100644
--- a/lldb/test/API/commands/frame/var-dil/basics/Indirection/TestFrameVarDILIndirection.py
+++ b/lldb/test/API/commands/frame/var-dil/basics/Indirection/TestFrameVarDILIndirection.py
@@ -11,6 +11,7 @@
import shutil
import time
+
class TestFrameVarDILIndirection(TestBase):
# If your test case doesn't stress debug info, then
# set this to true. That way it won't be run once for
@@ -19,8 +20,9 @@ class TestFrameVarDILIndirection(TestBase):
def test_frame_var(self):
self.build()
- lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here",
- lldb.SBFileSpec("main.cpp"))
+ lldbutil.run_to_source_breakpoint(
+ self, "Set a breakpoint here", lldb.SBFileSpec("main.cpp")
+ )
self.runCmd("settings set target.experimental.use-DIL true")
self.expect_var_path("*p", value="1")
@@ -30,7 +32,15 @@ def test_frame_var(self):
self.expect_var_path("*my_pr", type="int *")
self.expect_var_path("my_pr", type="mypr")
- self.expect("frame variable '*1'", error=True,
- substrs=["Unexpected token: <'1' (numeric_constant)>"])
- self.expect("frame variable '*val'", error=True,
- substrs=["dereference failed: not a pointer, reference or array type: (int) val"])
+ self.expect(
+ "frame variable '*1'",
+ error=True,
+ substrs=["Unexpected token: <'1' (numeric_constant)>"],
+ )
+ self.expect(
+ "frame variable '*val'",
+ error=True,
+ substrs=[
+ "dereference failed: not a pointer, reference or array type: (int) val"
+ ],
+ )
diff --git a/lldb/test/API/commands/frame/var-dil/basics/Indirection/main.cpp b/lldb/test/API/commands/frame/var-dil/basics/Indirection/main.cpp
index 827968a71519a..9fbd99b219ce1 100644
--- a/lldb/test/API/commands/frame/var-dil/basics/Indirection/main.cpp
+++ b/lldb/test/API/commands/frame/var-dil/basics/Indirection/main.cpp
@@ -1,13 +1,11 @@
-int
-main(int argc, char **argv)
-{
+int main(int argc, char **argv) {
int val = 1;
- int* p = &val;
+ int *p = &val;
- typedef int* myp;
+ typedef int *myp;
myp my_p = &val;
- typedef int*& mypr;
+ typedef int *&mypr;
mypr my_pr = p;
return 0; // Set a breakpoint here
diff --git a/lldb/test/API/commands/frame/var-dil/basics/PointerDereference/TestFrameVarDILPointerDereference.py b/lldb/test/API/commands/frame/var-dil/basics/PointerDereference/TestFrameVarDILPointerDereference.py
index 7f5acc26dd40b..12b750bab07a9 100644
--- a/lldb/test/API/commands/frame/var-dil/basics/PointerDereference/TestFrameVarDILPointerDereference.py
+++ b/lldb/test/API/commands/frame/var-dil/basics/PointerDereference/TestFrameVarDILPointerDereference.py
@@ -11,6 +11,7 @@
import shutil
import time
+
class TestFrameVarDILPointerDereference(TestBase):
NO_DEBUG_INFO_TESTCASE = True
@@ -26,5 +27,8 @@ def test_frame_var(self):
self.expect_var_path("&pp_void0[2]", type="void **")
self.expect_var_path("**pp_int0", value="0")
self.expect_var_path("&**pp_int0", type="int *")
- self.expect("frame variable '&p_void[0]'", error=True,
- substrs=["subscript of pointer to incomplete type 'void'"])
+ self.expect(
+ "frame variable '&p_void[0]'",
+ error=True,
+ substrs=["subscript of pointer to incomplete type 'void'"],
+ )
diff --git a/lldb/test/API/commands/frame/var-dil/basics/PointerDereference/main.cpp b/lldb/test/API/commands/frame/var-dil/basics/PointerDereference/main.cpp
index 719fa81b60830..0849d1d381bd7 100644
--- a/lldb/test/API/commands/frame/var-dil/basics/PointerDereference/main.cpp
+++ b/lldb/test/API/commands/frame/var-dil/basics/PointerDereference/main.cpp
@@ -1,10 +1,10 @@
#include <cstddef>
-int main (int argc, char **argv) {
- int* p_null = nullptr;
- const char* p_char1 = "hello";
+int main(int argc, char **argv) {
+ int *p_null = nullptr;
+ const char *p_char1 = "hello";
- typedef const char* my_char_ptr;
+ typedef const char *my_char_ptr;
my_char_ptr my_p_char1 = p_char1;
int offset = 5;
@@ -12,19 +12,19 @@ int main (int argc, char **argv) {
array[0] = 0;
array[offset] = offset;
- int(&array_ref)[10] = array;
+ int (&array_ref)[10] = array;
- int* p_int0 = &array[0];
- int** pp_int0 = &p_int0;
- const int* cp_int0 = &array[0];
- const int* cp_int5 = &array[offset];
+ int *p_int0 = &array[0];
+ int **pp_int0 = &p_int0;
+ const int *cp_int0 = &array[0];
+ const int *cp_int5 = &array[offset];
- typedef int* td_int_ptr_t;
+ typedef int *td_int_ptr_t;
td_int_ptr_t td_int_ptr0 = &array[0];
- void* p_void = (void*)p_char1;
- void** pp_void0 = &p_void;
- void** pp_void1 = pp_void0 + 1;
+ void *p_void = (void *)p_char1;
+ void **pp_void0 = &p_void;
+ void **pp_void1 = pp_void0 + 1;
std::nullptr_t std_nullptr_t = nullptr;
diff --git a/lldb/test/API/commands/frame/var-dil/basics/QualifiedId/TestFrameVarDILQualifiedId.py b/lldb/test/API/commands/frame/var-dil/basics/QualifiedId/TestFrameVarDILQualifiedId.py
index 3d91198ea3ab9..b2ce9602e6a50 100644
--- a/lldb/test/API/commands/frame/var-dil/basics/QualifiedId/TestFrameVarDILQualifiedId.py
+++ b/lldb/test/API/commands/frame/var-dil/basics/QualifiedId/TestFrameVarDILQualifiedId.py
@@ -11,6 +11,7 @@
import shutil
import time
+
class TestFrameVarDILQualifiedId(TestBase):
# If your test case doesn't stress debug info, then
# set this to true. That way it won't be run once for
@@ -19,8 +20,9 @@ class TestFrameVarDILQualifiedId(TestBase):
def test_frame_var(self):
self.build()
- lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here",
- lldb.SBFileSpec("main.cpp"))
+ lldbutil.run_to_source_breakpoint(
+ self, "Set a breakpoint here", lldb.SBFileSpec("main.cpp")
+ )
self.runCmd("settings set target.experimental.use-DIL true")
self.expect_var_path("::ns::i", value="1")
diff --git a/lldb/test/API/commands/frame/var-dil/basics/QualifiedId/main.cpp b/lldb/test/API/commands/frame/var-dil/basics/QualifiedId/main.cpp
index 3316d0b807868..8a5c47a6f364c 100644
--- a/lldb/test/API/commands/frame/var-dil/basics/QualifiedId/main.cpp
+++ b/lldb/test/API/commands/frame/var-dil/basics/QualifiedId/main.cpp
@@ -6,13 +6,11 @@ namespace ns {
int i = 2;
-} // namespace ns
+} // namespace ns
-} // namespace ns
+} // namespace ns
-int
-main(int argc, char **argv)
-{
+int main(int argc, char **argv) {
return 0; // Set a breakpoint here
}
diff --git a/lldb/test/API/commands/frame/var-dil/basics/SharedPtr/TestFrameVarDILSharedPtrDeref.py b/lldb/test/API/commands/frame/var-dil/basics/SharedPtr/TestFrameVarDILSharedPtrDeref.py
index 32b389bec8fa4..bfcb827da47eb 100644
--- a/lldb/test/API/commands/frame/var-dil/basics/SharedPtr/TestFrameVarDILSharedPtrDeref.py
+++ b/lldb/test/API/commands/frame/var-dil/basics/SharedPtr/TestFrameVarDILSharedPtrDeref.py
@@ -11,6 +11,7 @@
import shutil
import time
+
class TestFrameVarDILSharedPtrDeref(TestBase):
# If your test case doesn't stress debug info, then
# set this to true. That way it won't be run once for
@@ -19,8 +20,9 @@ class TestFrameVarDILSharedPtrDeref(TestBase):
def test_frame_var(self):
self.build()
- lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here",
- lldb.SBFileSpec("main.cpp"))
+ lldbutil.run_to_source_breakpoint(
+ self, "Set a breakpoint here", lldb.SBFileSpec("main.cpp")
+ )
self.runCmd("settings set target.experimental.use-DIL true")
self.expect_var_path("ptr_node->value", value="1")
diff --git a/lldb/test/API/commands/frame/var-dil/basics/SharedPtr/main.cpp b/lldb/test/API/commands/frame/var-dil/basics/SharedPtr/main.cpp
index 642f5172a37f6..3b005a732470f 100644
--- a/lldb/test/API/commands/frame/var-dil/basics/SharedPtr/main.cpp
+++ b/lldb/test/API/commands/frame/var-dil/basics/SharedPtr/main.cpp
@@ -1,8 +1,6 @@
#include <memory>
-int
-main(int argc, char **argv)
-{
+int main(int argc, char **argv) {
struct NodeS {
std::shared_ptr<NodeS> next;
diff --git a/lldb/test/API/commands/frame/var-dil/basics/UniquePtr/TestFrameVarDILUniquePtrDeref.py b/lldb/test/API/commands/frame/var-dil/basics/UniquePtr/TestFrameVarDILUniquePtrDeref.py
index 065fb9df33444..d5f10faedd799 100644
--- a/lldb/test/API/commands/frame/var-dil/basics/UniquePtr/TestFrameVarDILUniquePtrDeref.py
+++ b/lldb/test/API/commands/frame/var-dil/basics/UniquePtr/TestFrameVarDILUniquePtrDeref.py
@@ -11,6 +11,7 @@
import shutil
import time
+
class TestFrameVarDILUniquePtrDeref(TestBase):
# If your test case doesn't stress debug info, then
# set this to true. That way it won't be run once for
@@ -19,8 +20,9 @@ class TestFrameVarDILUniquePtrDeref(TestBase):
def test_frame_var(self):
self.build()
- lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here",
- lldb.SBFileSpec("main.cpp"))
+ lldbutil.run_to_source_breakpoint(
+ self, "Set a breakpoint here", lldb.SBFileSpec("main.cpp")
+ )
self.runCmd("settings set target.experimental.use-DIL true")
self.expect_var_path("ptr_node->value", value="1")
diff --git a/lldb/test/API/commands/frame/var-dil/basics/UniquePtr/main.cpp b/lldb/test/API/commands/frame/var-dil/basics/UniquePtr/main.cpp
index f20f6f116a084..bc2c1c8c47d4d 100644
--- a/lldb/test/API/commands/frame/var-dil/basics/UniquePtr/main.cpp
+++ b/lldb/test/API/commands/frame/var-dil/basics/UniquePtr/main.cpp
@@ -1,8 +1,6 @@
#include <memory>
-int
-main(int argc, char **argv)
-{
+int main(int argc, char **argv) {
struct NodeU {
std::unique_ptr<NodeU> next;
@@ -15,7 +13,9 @@ main(int argc, char **argv)
auto ptr_int = std::make_unique<int>(1);
auto ptr_float = std::make_unique<float>(1.1f);
- auto deleter = [](void const* data) { delete static_cast<int const*>(data); };
+ auto deleter = [](void const *data) {
+ delete static_cast<int const *>(data);
+ };
std::unique_ptr<void, decltype(deleter)> ptr_void(new int(42), deleter);
// TestUniquePtr
>From 5144a9159c8d029d7094638c937bf57a9b368d55 Mon Sep 17 00:00:00 2001
From: Caroline Tice <cmtice at google.com>
Date: Thu, 19 Jun 2025 23:14:08 -0700
Subject: [PATCH 4/6] Add fake smart pointer test.
Test synthetic format provider similar to LibCxx smart pointers,
but independent of actual smart pointer implementation (so not brittle test).
---
.../data-formatter/fake-smart-ptr/Makefile | 3 ++
.../fake-smart-ptr/TestFakeSmartPtrs.py | 33 +++++++++++++++++++
.../data-formatter/fake-smart-ptr/main.cpp | 27 +++++++++++++++
.../fake-smart-ptr/smartPtrSynthProvider.py | 31 +++++++++++++++++
4 files changed, 94 insertions(+)
create mode 100644 lldb/test/API/functionalities/data-formatter/fake-smart-ptr/Makefile
create mode 100644 lldb/test/API/functionalities/data-formatter/fake-smart-ptr/TestFakeSmartPtrs.py
create mode 100644 lldb/test/API/functionalities/data-formatter/fake-smart-ptr/main.cpp
create mode 100644 lldb/test/API/functionalities/data-formatter/fake-smart-ptr/smartPtrSynthProvider.py
diff --git a/lldb/test/API/functionalities/data-formatter/fake-smart-ptr/Makefile b/lldb/test/API/functionalities/data-formatter/fake-smart-ptr/Makefile
new file mode 100644
index 0000000000000..99998b20bcb05
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/fake-smart-ptr/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/functionalities/data-formatter/fake-smart-ptr/TestFakeSmartPtrs.py b/lldb/test/API/functionalities/data-formatter/fake-smart-ptr/TestFakeSmartPtrs.py
new file mode 100644
index 0000000000000..418ccb35711f6
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/fake-smart-ptr/TestFakeSmartPtrs.py
@@ -0,0 +1,33 @@
+"""
+Test code that should work on smart pointers, but make it impl independent.
+"""
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class FakeSmartPtrDataFormatterTestCase(TestBase):
+ # If your test case doesn't stress debug info, then
+ # set this to true. That way it won't be run once for
+ # each debug info format.
+ NO_DEBUG_INFO_TESTCASE = True
+
+ def test_frame_var(self):
+ self.build()
+ lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here",
+ lldb.SBFileSpec("main.cpp"))
+
+ self.runCmd("settings set target.experimental.use-DIL true")
+ self.runCmd("script from smartPtrSynthProvider import *")
+ self.runCmd("type synth add -l smartPtrSynthProvider smart_ptr")
+
+ self.expect_var_path("ptr_node->value", value="1")
+ self.expect_var_path("ptr_node->next->value", value="2")
+ self.expect_var_path("(*ptr_node).value", value="1")
+ self.expect_var_path("(*(*ptr_node).next).value", value="2")
+
+ self.expect_var_path("ptr_node.__ptr_", type="NodeS *")
+ self.expect_var_path("ptr_node.__ptr_->value", value="1")
+ self.expect_var_path("ptr_node.__ptr_->next.__ptr_->value", value="2")
diff --git a/lldb/test/API/functionalities/data-formatter/fake-smart-ptr/main.cpp b/lldb/test/API/functionalities/data-formatter/fake-smart-ptr/main.cpp
new file mode 100644
index 0000000000000..abfdd0bb7f164
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/fake-smart-ptr/main.cpp
@@ -0,0 +1,27 @@
+#include <memory>
+
+struct NodeS;
+
+// Fake smart pointer definition.
+class smart_ptr {
+ public:
+ NodeS *__ptr_;
+
+ smart_ptr(NodeS *ptr) : __ptr_(ptr) {}
+};
+
+struct NodeS {
+ smart_ptr next;
+ int value;
+
+ NodeS(NodeS *ptr, int val) :
+ next(smart_ptr(ptr)), value(val) {}
+};
+
+int main(int argc, char**argv) {
+
+ // Make a short linked list of fake smart pointers.
+ auto ptr_node = smart_ptr(new NodeS(new NodeS(nullptr, 2), 1));
+
+ return 0; // Set a breakpoint here
+}
diff --git a/lldb/test/API/functionalities/data-formatter/fake-smart-ptr/smartPtrSynthProvider.py b/lldb/test/API/functionalities/data-formatter/fake-smart-ptr/smartPtrSynthProvider.py
new file mode 100644
index 0000000000000..321e5381ff57a
--- /dev/null
+++ b/lldb/test/API/functionalities/data-formatter/fake-smart-ptr/smartPtrSynthProvider.py
@@ -0,0 +1,31 @@
+import lldb
+
+class smartPtrSynthProvider:
+ def __init__(self, valobj, dict):
+ self.valobj = valobj
+
+ def num_children(self):
+ return 1
+
+ def get_child_at_index(self, index):
+ if index == 0:
+ return self.valobj.GetChildMemberWithName("__ptr_")
+ if index == 1:
+ internal_child = self.valobj.GetChildMemberWithName("__ptr_")
+ if not internal_child:
+ return None
+ value_type = internal_child.GetType().GetPointerType()
+ cast_ptr_sp = internal_child.Cast(value_type)
+ value = internal_child.Dereference()
+ return value
+ return None
+
+ def get_child_index(self, name):
+ if name == "__ptr_":
+ return 0
+ if name == "$$dereference$$":
+ return 1
+ return -1
+
+ def update(self):
+ return True
>From cb2a8aef21e141dd754573990043753e91273667 Mon Sep 17 00:00:00 2001
From: Caroline Tice <cmtice at google.com>
Date: Thu, 19 Jun 2025 23:34:48 -0700
Subject: [PATCH 5/6] Fix clang-format issues.
---
.../fake-smart-ptr/TestFakeSmartPtrs.py | 5 +-
.../data-formatter/fake-smart-ptr/main.cpp | 7 ++-
.../fake-smart-ptr/smartPtrSynthProvider.py | 46 +++++++++----------
3 files changed, 29 insertions(+), 29 deletions(-)
diff --git a/lldb/test/API/functionalities/data-formatter/fake-smart-ptr/TestFakeSmartPtrs.py b/lldb/test/API/functionalities/data-formatter/fake-smart-ptr/TestFakeSmartPtrs.py
index 418ccb35711f6..8bd7a09e1b85e 100644
--- a/lldb/test/API/functionalities/data-formatter/fake-smart-ptr/TestFakeSmartPtrs.py
+++ b/lldb/test/API/functionalities/data-formatter/fake-smart-ptr/TestFakeSmartPtrs.py
@@ -16,8 +16,9 @@ class FakeSmartPtrDataFormatterTestCase(TestBase):
def test_frame_var(self):
self.build()
- lldbutil.run_to_source_breakpoint(self, "Set a breakpoint here",
- lldb.SBFileSpec("main.cpp"))
+ lldbutil.run_to_source_breakpoint(
+ self, "Set a breakpoint here", lldb.SBFileSpec("main.cpp")
+ )
self.runCmd("settings set target.experimental.use-DIL true")
self.runCmd("script from smartPtrSynthProvider import *")
diff --git a/lldb/test/API/functionalities/data-formatter/fake-smart-ptr/main.cpp b/lldb/test/API/functionalities/data-formatter/fake-smart-ptr/main.cpp
index abfdd0bb7f164..49b616e5c983b 100644
--- a/lldb/test/API/functionalities/data-formatter/fake-smart-ptr/main.cpp
+++ b/lldb/test/API/functionalities/data-formatter/fake-smart-ptr/main.cpp
@@ -4,7 +4,7 @@ struct NodeS;
// Fake smart pointer definition.
class smart_ptr {
- public:
+public:
NodeS *__ptr_;
smart_ptr(NodeS *ptr) : __ptr_(ptr) {}
@@ -14,11 +14,10 @@ struct NodeS {
smart_ptr next;
int value;
- NodeS(NodeS *ptr, int val) :
- next(smart_ptr(ptr)), value(val) {}
+ NodeS(NodeS *ptr, int val) : next(smart_ptr(ptr)), value(val) {}
};
-int main(int argc, char**argv) {
+int main(int argc, char **argv) {
// Make a short linked list of fake smart pointers.
auto ptr_node = smart_ptr(new NodeS(new NodeS(nullptr, 2), 1));
diff --git a/lldb/test/API/functionalities/data-formatter/fake-smart-ptr/smartPtrSynthProvider.py b/lldb/test/API/functionalities/data-formatter/fake-smart-ptr/smartPtrSynthProvider.py
index 321e5381ff57a..19db95bd1877f 100644
--- a/lldb/test/API/functionalities/data-formatter/fake-smart-ptr/smartPtrSynthProvider.py
+++ b/lldb/test/API/functionalities/data-formatter/fake-smart-ptr/smartPtrSynthProvider.py
@@ -1,31 +1,31 @@
import lldb
class smartPtrSynthProvider:
- def __init__(self, valobj, dict):
- self.valobj = valobj
+ def __init__(self, valobj, dict):
+ self.valobj = valobj
- def num_children(self):
- return 1
+ def num_children(self):
+ return 1
- def get_child_at_index(self, index):
- if index == 0:
- return self.valobj.GetChildMemberWithName("__ptr_")
- if index == 1:
- internal_child = self.valobj.GetChildMemberWithName("__ptr_")
- if not internal_child:
+ def get_child_at_index(self, index):
+ if index == 0:
+ return self.valobj.GetChildMemberWithName("__ptr_")
+ if index == 1:
+ internal_child = self.valobj.GetChildMemberWithName("__ptr_")
+ if not internal_child:
+ return None
+ value_type = internal_child.GetType().GetPointerType()
+ cast_ptr_sp = internal_child.Cast(value_type)
+ value = internal_child.Dereference()
+ return value
return None
- value_type = internal_child.GetType().GetPointerType()
- cast_ptr_sp = internal_child.Cast(value_type)
- value = internal_child.Dereference()
- return value
- return None
- def get_child_index(self, name):
- if name == "__ptr_":
- return 0
- if name == "$$dereference$$":
- return 1
- return -1
+ def get_child_index(self, name):
+ if name == "__ptr_":
+ return 0
+ if name == "$$dereference$$":
+ return 1
+ return -1
- def update(self):
- return True
+ def update(self):
+ return True
>From e823fd71134ce8f0865ba8484c8ed0ed5c39c459 Mon Sep 17 00:00:00 2001
From: Caroline Tice <cmtice at google.com>
Date: Thu, 19 Jun 2025 23:40:32 -0700
Subject: [PATCH 6/6] Fix another clang-format issue.
---
.../data-formatter/fake-smart-ptr/smartPtrSynthProvider.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/lldb/test/API/functionalities/data-formatter/fake-smart-ptr/smartPtrSynthProvider.py b/lldb/test/API/functionalities/data-formatter/fake-smart-ptr/smartPtrSynthProvider.py
index 19db95bd1877f..c3a09cebe63f1 100644
--- a/lldb/test/API/functionalities/data-formatter/fake-smart-ptr/smartPtrSynthProvider.py
+++ b/lldb/test/API/functionalities/data-formatter/fake-smart-ptr/smartPtrSynthProvider.py
@@ -1,5 +1,6 @@
import lldb
+
class smartPtrSynthProvider:
def __init__(self, valobj, dict):
self.valobj = valobj
More information about the lldb-commits
mailing list