friss updated this revision to Diff 239188.
friss added a comment.
use python formatting in docs
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D73053/new/
https://reviews.llvm.org/D73053
Files:
lldb/docs/use/variable.rst
lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py
lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/fooSynthProvider.py
lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp
lldb/source/Core/ValueObject.cpp
Index: lldb/source/Core/ValueObject.cpp
===================================================================
--- lldb/source/Core/ValueObject.cpp
+++ lldb/source/Core/ValueObject.cpp
@@ -2859,6 +2859,9 @@
GetSyntheticValue()
->GetChildMemberWithName(ConstString("$$dereference$$"), true)
.get();
+ } else if (IsSynthetic()) {
+ m_deref_valobj =
+ GetChildMemberWithName(ConstString("$$dereference$$"), true).get();
}
if (m_deref_valobj) {
Index: lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp
===================================================================
--- lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp
+++ lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp
@@ -46,11 +46,17 @@
wrapint(int X) : x(X) {}
};
+struct wrapfoo
+{
+ foo *ptr;
+};
+
int main()
{
foo f00_1(1);
foo *f00_ptr = new foo(12);
-
+ wrapfoo wrapper{f00_ptr};
+
f00_1.a++; // Set break point at this line.
wrapint test_cast('A' +
Index: lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/fooSynthProvider.py
===================================================================
--- lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/fooSynthProvider.py
+++ lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/fooSynthProvider.py
@@ -28,3 +28,29 @@
def update(self):
return True
+
+
+class wrapfooSynthProvider:
+
+ 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:
+ return self.valobj.GetChildMemberWithName('ptr').Dereference()
+ 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
Index: lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py
===================================================================
--- lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py
+++ lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py
@@ -38,19 +38,9 @@
def data_formatter_commands(self):
"""Test using Python synthetic children provider."""
- self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
-
- lldbutil.run_break_set_by_file_and_line(
- self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
-
- self.runCmd("run", RUN_SUCCEEDED)
-
- process = self.dbg.GetSelectedTarget().GetProcess()
- # The stop reason of the thread should be breakpoint.
- self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
- substrs=['stopped',
- 'stop reason = breakpoint'])
+ _, process, thread, _ = lldbutil.run_to_line_breakpoint(
+ self, lldb.SBFileSpec("main.cpp"), self.line)
# This is the function to remove the custom formats in order to have a
# clean slate for the next test case.
@@ -72,6 +62,7 @@
# now set up the synth
self.runCmd("script from fooSynthProvider import *")
self.runCmd("type synth add -l fooSynthProvider foo")
+ self.runCmd("type synth add -l wrapfooSynthProvider wrapfoo")
self.expect("type synthetic list foo", substrs=['fooSynthProvider'])
# note that the value of fake_a depends on target byte order
@@ -147,6 +138,10 @@
substrs=['r = 45',
'fake_a = %d' % fake_a_val,
'a = 12'])
+ self.expect("frame variable --ptr-depth 1 wrapper",
+ substrs=['r = 45',
+ 'fake_a = %d' % fake_a_val,
+ 'a = 12'])
# now add a filter.. it should fail
self.expect("type filter add foo --child b --child j", error=True,
@@ -160,9 +155,24 @@
substrs=['r = 45',
'fake_a = %d' % fake_a_val,
'a = 12'])
+ self.expect("frame variable --ptr-depth 1 wrapper",
+ substrs=['r = 45',
+ 'fake_a = %d' % fake_a_val,
+ 'a = 12'])
+
+ # Test that the custom dereference operator for `wrapfoo` works through
+ # the Python API. The synthetic children provider gets queried at
+ # slightly different times in this case.
+ wrapper_var = thread.GetSelectedFrame().FindVariable('wrapper')
+ foo_var = wrapper_var.Dereference()
+ self.assertEqual(foo_var.GetNumChildren(), 3)
+ self.assertEqual(foo_var.GetChildAtIndex(0).GetName(), 'a')
+ self.assertEqual(foo_var.GetChildAtIndex(1).GetName(), 'fake_a')
+ self.assertEqual(foo_var.GetChildAtIndex(2).GetName(), 'r')
# now delete the synth and add the filter
self.runCmd("type synth delete foo")
+ self.runCmd("type synth delete wrapfoo")
self.runCmd("type filter add foo --child b --child j")
self.expect('frame variable f00_1',
@@ -172,6 +182,10 @@
substrs=['r = 45',
'fake_a = %d' % fake_a_val,
'a = 12'])
+ self.expect("frame variable --ptr-depth 1 wrapper", matching=False,
+ substrs=['r = 45',
+ 'fake_a = %d' % fake_a_val,
+ 'a = 12'])
# now add the synth and it should fail
self.expect("type synth add -l fooSynthProvider foo", error=True,
@@ -197,6 +211,10 @@
substrs=['r = 45',
'fake_a = %d' % fake_a_val,
'a = 12'])
+ self.expect("frame variable --ptr-depth 1 wrapper",
+ substrs=['r = 45',
+ 'fake_a = %d' % fake_a_val,
+ 'a = 12'])
# check the listing
self.expect('type synth list',
Index: lldb/docs/use/variable.rst
===================================================================
--- lldb/docs/use/variable.rst
+++ lldb/docs/use/variable.rst
@@ -846,7 +846,7 @@
explicit notion of interface, by that word we mean a given set of methods must
be implemented by the Python class):
-::
+.. code-block:: python
class SyntheticChildrenProvider:
def __init__(self, valobj, internal_dict):
@@ -885,7 +885,28 @@
If a synthetic child provider supplies a special child named
``$$dereference$$`` then it will be used when evaluating ``operator *`` and
-``operator ->`` in the frame variable command and related SB API functions.
+``operator ->`` in the frame variable command and related SB API
+functions. It is possible to declare this synthetic child without
+including it in the range of children displayed by LLDB. For example,
+this subset of a synthetic children provider class would allow the
+synthetic value to be dereferenced without actually showing any
+synthtic children in the UI:
+
+.. code-block:: python
+
+ class SyntheticChildrenProvider:
+ [...]
+ def num_children(self):
+ return 0
+ def get_child_index(self, name):
+ if name == '$$dereference$$':
+ return 0
+ return -1
+ def get_child_at_index(self, index):
+ if index == 0:
+ return <valobj resulting of dereference>
+ return None
+
For examples of how synthetic children are created, you are encouraged to look
at examples/synthetic in the LLDB trunk. Please, be aware that the code in
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits