[Lldb-commits] [lldb] r138384 - in /lldb/trunk: source/Core/Debugger.cpp source/Core/FormatManager.cpp source/Core/ValueObject.cpp test/functionalities/data-formatter/rdar-9974002/ test/functionalities/data-formatter/rdar-9974002/Makefile test/functionalities/data-formatter/rdar-9974002/Test-rdar-9974002.py test/functionalities/data-formatter/rdar-9974002/main.cpp www/varformats.html
Enrico Granata
granata.enrico at gmail.com
Tue Aug 23 14:26:09 PDT 2011
Author: enrico
Date: Tue Aug 23 16:26:09 2011
New Revision: 138384
URL: http://llvm.org/viewvc/llvm-project?rev=138384&view=rev
Log:
Improved the user-friendliness of errors shown by the summary feature in certain areas
Renamed format "signed decimal" to be "decimal". "unsigned decimal" remains unchanged:
- the name "signed decimal" was interfering with symbol %S (use summary) in summary strings.
because of the way summary strings are implemented, this did not really lead to a bug, but
simply to performing more steps than necessary to display a summary. this is fixed.
Documentation improvements (more on synthetic children, some information on filters). This is still a WIP.
Added:
lldb/trunk/test/functionalities/data-formatter/rdar-9974002/
lldb/trunk/test/functionalities/data-formatter/rdar-9974002/Makefile
lldb/trunk/test/functionalities/data-formatter/rdar-9974002/Test-rdar-9974002.py
lldb/trunk/test/functionalities/data-formatter/rdar-9974002/main.cpp
Modified:
lldb/trunk/source/Core/Debugger.cpp
lldb/trunk/source/Core/FormatManager.cpp
lldb/trunk/source/Core/ValueObject.cpp
lldb/trunk/www/varformats.html
Modified: lldb/trunk/source/Core/Debugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=138384&r1=138383&r2=138384&view=diff
==============================================================================
--- lldb/trunk/source/Core/Debugger.cpp (original)
+++ lldb/trunk/source/Core/Debugger.cpp Tue Aug 23 16:26:09 2011
@@ -1186,11 +1186,16 @@
}
else
{
- // if ${var}
- if (was_plain_var)
+ if (was_plain_var) // if ${var}
{
s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
}
+ else if (is_pointer) // if pointer, value is the address stored
+ {
+ var_success = target->GetPrintableRepresentation(s,
+ val_obj_display,
+ custom_format);
+ }
else
{
s << "<invalid usage of pointer value as object>";
Modified: lldb/trunk/source/Core/FormatManager.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FormatManager.cpp?rev=138384&r1=138383&r2=138384&view=diff
==============================================================================
--- lldb/trunk/source/Core/FormatManager.cpp (original)
+++ lldb/trunk/source/Core/FormatManager.cpp Tue Aug 23 16:26:09 2011
@@ -39,7 +39,7 @@
{ eFormatCharPrintable , 'C' , "printable character" },
{ eFormatComplexFloat , 'F' , "complex float" },
{ eFormatCString , 's' , "c-string" },
- { eFormatDecimal , 'i' , "signed decimal" },
+ { eFormatDecimal , 'i' , "decimal" },
{ eFormatEnum , 'E' , "enumeration" },
{ eFormatHex , 'x' , "hex" },
{ eFormatFloat , 'f' , "float" },
Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=138384&r1=138383&r2=138384&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Tue Aug 23 16:26:09 2011
@@ -1021,7 +1021,18 @@
if (return_value)
s.PutCString(return_value);
else
- s.PutCString("<no printable representation>");
+ {
+ if (m_error.Fail())
+ s.Printf("<%s>", m_error.AsCString());
+ else if (val_obj_display == eDisplaySummary)
+ s.PutCString("<no summary available>");
+ else if (val_obj_display == eDisplayValue)
+ s.PutCString("<no value available>");
+ else if (val_obj_display == eDisplayLanguageSpecific)
+ s.PutCString("<not a valid Objective-C object>"); // edit this if we have other runtimes that support a description
+ else
+ s.PutCString("<no printable representation>");
+ }
// we should only return false here if we could not do *anything*
// even if we have an error message as output, that's a success
Added: lldb/trunk/test/functionalities/data-formatter/rdar-9974002/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/rdar-9974002/Makefile?rev=138384&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/rdar-9974002/Makefile (added)
+++ lldb/trunk/test/functionalities/data-formatter/rdar-9974002/Makefile Tue Aug 23 16:26:09 2011
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
Added: lldb/trunk/test/functionalities/data-formatter/rdar-9974002/Test-rdar-9974002.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/rdar-9974002/Test-rdar-9974002.py?rev=138384&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/rdar-9974002/Test-rdar-9974002.py (added)
+++ lldb/trunk/test/functionalities/data-formatter/rdar-9974002/Test-rdar-9974002.py Tue Aug 23 16:26:09 2011
@@ -0,0 +1,146 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+
+class DataFormatterTestCase(TestBase):
+
+ # test for rdar://problem/9974002 ()
+ mydir = os.path.join("functionalities", "data-formatter", "rdar-9974002")
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ def test_with_dsym_and_run_command(self):
+ """Test data formatter commands."""
+ self.buildDsym()
+ self.data_formatter_commands()
+
+ def test_with_dwarf_and_run_command(self):
+ """Test data formatter commands."""
+ self.buildDwarf()
+ self.data_formatter_commands()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break at.
+ self.line = line_number('main.cpp', '// Set break point at this line.')
+
+ def data_formatter_commands(self):
+ """Test that that file and class static variables display correctly."""
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ self.expect("breakpoint set -f main.cpp -l %d" % self.line,
+ BREAKPOINT_CREATED,
+ startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" %
+ self.line)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # This is the function to remove the custom formats in order to have a
+ # clean slate for the next test case.
+ def cleanup():
+ self.runCmd('type summary clear', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.runCmd("type summary add -s \"${var.scalar} and ${var.pointer.first}\" container")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ '1', '<parent is NULL>'])
+
+ self.runCmd("type summary add -s \"${var.scalar} and ${var.pointer}\" container")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ '1', '0x000000'])
+
+ self.runCmd("type summary add -s \"${var.scalar} and ${var.pointer%S}\" container")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ '1', '0x000000'])
+
+ self.runCmd("type summary add -s foo contained")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ '1', 'foo'])
+
+ self.runCmd("type summary add -s \"${var.scalar} and ${var.pointer}\" container")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ '1', 'foo'])
+
+ self.runCmd("type summary add -s \"${var.scalar} and ${var.pointer%V}\" container")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ '1', '0x000000'])
+
+ self.runCmd("type summary add -s \"${var.scalar} and ${var.pointer.first}\" container")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ '1', '<parent is NULL>'])
+
+ self.runCmd("type summary delete contained")
+ self.runCmd("n")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ '1', '<parent is NULL>'])
+
+ self.runCmd("type summary add -s \"${var.scalar} and ${var.pointer}\" container")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ '1', '0x000000'])
+
+ self.runCmd("type summary add -s \"${var.scalar} and ${var.pointer%S}\" container")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ '1', '0x000000'])
+
+ self.runCmd("type summary add -s foo contained")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ '1', 'foo'])
+
+ self.runCmd("type summary add -s \"${var.scalar} and ${var.pointer}\" container")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ '1', 'foo'])
+
+ self.runCmd("type summary add -s \"${var.scalar} and ${var.pointer%V}\" container")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ '1', '0x000000'])
+
+ self.runCmd("type summary add -s \"${var.scalar} and ${var.pointer.first}\" container")
+
+ self.expect('frame variable mine',
+ substrs = ['mine = ',
+ '1', '<parent is NULL>'])
+
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Added: lldb/trunk/test/functionalities/data-formatter/rdar-9974002/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/rdar-9974002/main.cpp?rev=138384&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/rdar-9974002/main.cpp (added)
+++ lldb/trunk/test/functionalities/data-formatter/rdar-9974002/main.cpp Tue Aug 23 16:26:09 2011
@@ -0,0 +1,30 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+
+struct contained
+{
+ int first;
+ int second;
+};
+
+struct container
+{
+ int scalar;
+ struct contained *pointer;
+};
+
+int main ()
+{
+ struct container mine = {1, 0};
+ printf ("Mine's scalar is the only thing that is good: %d.\n", mine.scalar); // Set break point at this line.
+ return 0;
+}
+
Modified: lldb/trunk/www/varformats.html
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/www/varformats.html?rev=138384&r1=138383&r2=138384&view=diff
==============================================================================
--- lldb/trunk/www/varformats.html (original)
+++ lldb/trunk/www/varformats.html Tue Aug 23 16:26:09 2011
@@ -159,11 +159,11 @@
<p> <code> <b>(lldb)</b> type format add -f float32[]
int<br>
- <b>(lldb)</b> fr var pointer *pointer -T<br>
+ <b>(lldb)</b> frame variable pointer *pointer -T<br>
(int *) pointer = {1.46991e-39 1.4013e-45}<br>
(int) *pointer = {1.53302e-42}<br>
<b>(lldb)</b> type format add -f float32[] int -p<br>
- <b>(lldb)</b> fr var pointer *pointer -T<br>
+ <b>(lldb)</b> frame variable pointer *pointer -T<br>
(int *) pointer = 0x0000000100100180<br>
(int) *pointer = {1.53302e-42}<br>
</code> </p>
@@ -390,7 +390,7 @@
information from classes, structures, ... (<i>aggregate types</i>)
and arranging it in a user-defined format, as in the following example:</p>
<p> <i>before adding a summary...</i><br>
- <code> <b>(lldb)</b> fr var -T one<br>
+ <code> <b>(lldb)</b> frame variable -T one<br>
(i_am_cool) one = {<br>
(int) integer = 3<br>
(float) floating = 3.14159<br>
@@ -398,7 +398,7 @@
}<br>
</code> <br>
<i>after adding a summary...</i><br>
- <code> <b>(lldb)</b> fr var one<br>
+ <code> <b>(lldb)</b> frame variable one<br>
(i_am_cool) one = int = 3, float = 3.14159, char = 69<br>
</code> </p>
@@ -409,7 +409,7 @@
<p>In the example, the command we type was:</p>
<table class="stats" width="620" cellspacing="0">
<td class="content">
- <b>(lldb)</b> type summary add -f "int = ${var.integer}, float = ${var.floating}, char = ${var.character%u}" i_am_cool
+ <b>(lldb)</b> type summary add --summary-string "int = ${var.integer}, float = ${var.floating}, char = ${var.character%u}" i_am_cool
</td>
<table>
@@ -546,7 +546,7 @@
dereferencing symbol only applies to the result of the
whole expression path traversing. <br>
e.g. <code> <br>
- <b>(lldb)</b> fr var -T c<br>
+ <b>(lldb)</b> frame variable -T c<br>
(Couple) c = {<br>
(SimpleWithPointers) sp = {<br>
(int *) x = 0x00000001001000b0<br>
@@ -561,7 +561,7 @@
<table class="stats" width="620" cellspacing="0">
<td class="content">
- <b>(lldb)</b> type summary add -f "int = ${*var.sp.x},
+ <b>(lldb)</b> type summary add --summary-string "int = ${*var.sp.x},
float = ${*var.sp.y}, char = ${*var.sp.z%u}, Simple =
${*var.s}" Couple<br>
<b>(lldb)</b> type summary add -c -p Simple<br>
@@ -570,7 +570,7 @@
the output becomes: <br><code>
- <b>(lldb)</b> fr var c<br>
+ <b>(lldb)</b> frame variable c<br>
(Couple) c = int = 9, float = 9.99, char = 88, Simple
= (x=9, y=9.99, z='X')<br>
</code> </p>
@@ -584,7 +584,7 @@
produce the same output:
<table class="stats" width="620" cellspacing="0">
<td class="content">
- <b>(lldb)</b> type summary add -f "int = ${*var.sp.x},
+ <b>(lldb)</b> type summary add --summary-string "int = ${*var.sp.x},
float = ${*var.sp.y}, char = ${*var.sp.z%u}, Simple =
${var.s}" Couple<br>
<b>(lldb)</b> type summary add -c Simple<br>
@@ -612,18 +612,18 @@
similar to that used for arrays, just you can also give
a pair of indices separated by a <code>-</code>. <br>
e.g. <br>
- <code> <b>(lldb)</b> fr var float_point<br>
+ <code> <b>(lldb)</b> frame variable float_point<br>
(float) float_point = -3.14159<br> </code>
<table class="stats" width="620" cellspacing="0">
<td class="content">
- <b>(lldb)</b> type summary add -f "Sign: ${var[31]%B}
+ <b>(lldb)</b> type summary add --summary-string "Sign: ${var[31]%B}
Exponent: ${var[30-23]%x} Mantissa: ${var[0-22]%u}"
float
</td>
<table><br>
<code>
- <b>(lldb)</b> fr var float_point<br>
+ <b>(lldb)</b> frame variable float_point<br>
(float) float_point = -3.14159 Sign: true Exponent:
0x00000080 Mantissa: 4788184<br>
</code> In this example, LLDB shows the internal
@@ -645,7 +645,7 @@
LLDB to format arrays in special ways, possibly
independent of the way the array members' datatype is formatted. <br>
e.g. <br>
- <code> <b>(lldb)</b> fr var sarray<br>
+ <code> <b>(lldb)</b> frame variable sarray<br>
(Simple [3]) sarray = {<br>
[0] = {<br>
x = 1<br>
@@ -666,13 +666,13 @@
<table class="stats" width="620" cellspacing="0">
<td class="content">
- <b>(lldb)</b> type summary add -f "${var[].x}" "Simple
+ <b>(lldb)</b> type summary add --summary-string "${var[].x}" "Simple
[3]"
</td>
<table><br>
<code>
- <b>(lldb)</b> fr var sarray<br>
+ <b>(lldb)</b> frame variable sarray<br>
(Simple [3]) sarray = [1,4,7]<br></code></p>
<p>The <code>[]</code> symbol amounts to: <i>if <code>var</code>
@@ -683,7 +683,7 @@
If you find some of those integers anomalous, you can
then inspect that one item in greater detail, without
the array format getting in the way: <br>
- <code> <b>(lldb)</b> fr var sarray[1]<br>
+ <code> <b>(lldb)</b> frame variable sarray[1]<br>
(Simple) sarray[1] = {<br>
x = 4<br>
y = 5<br>
@@ -695,12 +695,12 @@
for bitfields:
<table class="stats" width="620" cellspacing="0">
<td class="content">
- <b>(lldb)</b> type summary add -f "${var[1-2].x}" "Simple
+ <b>(lldb)</b> type summary add --summary-string "${var[1-2].x}" "Simple
[3]"
</td>
<table><br>
<code>
- <b>(lldb)</b> fr var sarray<br>
+ <b>(lldb)</b> frame variable sarray<br>
(Simple [3]) sarray = [4,7]<br></code></p>
<p>The same logic works if you are printing a pointer
@@ -716,7 +716,7 @@
omitting square brackets, as in:
<table class="stats" width="620" cellspacing="0">
<td class="content">
- <b>(lldb)</b> type summary add -f "${var%s}" "char *"
+ <b>(lldb)</b> type summary add --summary-string "${var%s}" "char *"
</td>
<table>
@@ -734,7 +734,7 @@
type, even if square brackets are omitted.
<table class="stats" width="620" cellspacing="0">
<td class="content">
- <b>(lldb)</b> type summary add -f "${var%int32_t[]}" "int [10]"
+ <b>(lldb)</b> type summary add --summary-string "${var%int32_t[]}" "int [10]"
</td>
<table>
@@ -836,7 +836,7 @@
</p>
<p>If you need to delve into several levels of hierarchy, as you can do with summary
- strings, you must use the method <code>GetValueForExpressionPath()</code>, passing it
+ strings, you can use the method <code>GetValueForExpressionPath()</code>, passing it
an expression path just like those you could use for summary strings. However, if you need
to access array slices, you cannot do that (yet) via this method call, and you must
use <code>GetChildMemberWithName()</code> querying it for the array items one by one.
@@ -845,12 +845,12 @@
to input a Python script as a summary:
<ul>
- <li> using the -s option to <code>type summary add </code> and typing the script
+ <li> using the --python-script option to <code>type summary add </code> and typing the script
code as an option argument; as in: </ul>
<table class="stats" width="620" cellspacing="0">
<td class="content">
- <b>(lldb)</b> type summary add -s "height =
+ <b>(lldb)</b> type summary add --python-script "height =
int(valobj.GetChildMemberWithName('height').GetValue());width =
int(valobj.GetChildMemberWithName('width').GetValue());
return 'Area: ' + str(height*width)" Rectangle<br/>
@@ -885,13 +885,13 @@
<table class="stats" width="620" cellspacing="0">
<td class="content">
- <b>(lldb)</b> type summary add -f "${var[].x}"
+ <b>(lldb)</b> type summary add --summary-string "${var[].x}"
-x "Simple \[[0-9]+\]"
</td>
<table>
<code>
- <b>(lldb)</b> fr var sarray<br>
+ <b>(lldb)</b> frame variable sarray<br>
(Simple [3]) sarray = [1,4,7]<br>
</code> The above scenario works for <code>Simple [3]</code>
as well as for any other array of <code>Simple</code>
@@ -905,6 +905,9 @@
matching. Thus, if your type has a base class with a
cascading summary, this will be preferred over any
regular expression match for your type itself.</p>
+
+ <p>The regular expression language used by LLDB is <a href="http://en.wikipedia.org/wiki/Regular_expression#POSIX_Extended_Regular_Expressions">the POSIX extended regular expression language</a>, as defined by <a href="http://pubs.opengroup.org/onlinepubs/7908799/xsh/regex.h.html">the SUS</a>.
+
</div>
</div>
@@ -924,12 +927,12 @@
<table class="stats" width="620" cellspacing="0">
<td class="content">
- <b>(lldb)</b> type summary add -f "x=${var.integer}" --name NamedSummary
+ <b>(lldb)</b> type summary add --summary-string "x=${var.integer}" --name NamedSummary
</td>
<table>
- <code> <b>(lldb)</b> fr var one<br>
+ <code> <b>(lldb)</b> frame variable one<br>
(i_am_cool) one = int = 3, float = 3.14159, char = 69<br>
- <b>(lldb)</b> fr var one --summary NamedSummary<br>
+ <b>(lldb)</b> frame variable one --summary NamedSummary<br>
(i_am_cool) one = x=3<br>
</code> </p>
@@ -959,9 +962,9 @@
<p>For instance, consider an STL vector:</p>
<code>
<b>(lldb)</b> frame variable numbers -T<br/>
- (std::vector<int>) numbers = {<br/>
- (std::_Vector_base<int, std::allocator<int> >) std::_Vector_base<int, std::allocator<int> > = {<br/>
- (std::_Vector_base<int, std::allocator<int> >::_Vector_impl) _M_impl = {<br/>
+ (std::vector<int>) numbers = {<br/>
+ (std::_Vector_base<int, std::allocator<int> >) std::_Vector_base<int, std::allocator<int> > = {<br/>
+ (std::_Vector_base<int, std::allocator&tl;int> >::_Vector_impl) _M_impl = {<br/>
(int *) _M_start = 0x00000001001008a0<br/>
(int *) _M_finish = 0x00000001001008a8<br/>
(int *) _M_end_of_storage = 0x00000001001008a8<br/>
@@ -974,7 +977,7 @@
<p>What you would like to see is probably something like:</p>
<code>
<b>(lldb)</b> frame variable numbers -T<br/>
- (std::vector<int>) numbers = {<br/>
+ (std::vector<int>) numbers = {<br/>
(int) [0] = 1<br/>
(int) [1] = 12<br/>
(int) [2] = 123<br/>
@@ -1004,8 +1007,83 @@
of LLDB.<br/>
</code>
<p>For examples of how synthetic children are created, you are encouraged to look at <a href="http://llvm.org/svn/llvm-project/lldb/trunk/examples/synthetic/">examples/synthetic</a> in the LLDB trunk.</p>
+
+ <p>Once a synthetic children provider is written, one must load it into LLDB before it can be used.
+ Currently, one can use the LLDB <code>script</code> command to type Python code interactively,
+ or use the <code>script import <i>module</i></code> command to load Python code from a Python module
+ (ordinary rules apply to importing modules this way). A third option is to type the code for
+ the provider class interactively while adding it.</p>
+
+ <p>For example, let's pretend we have a class Foo for which a synthetic children provider class Foo_Provider
+ is available, in a Python module named Foo_Tools. The following interaction sets Foo_Provider as a synthetic
+ children provider in LLDB:</p>
+
+ <table class="stats" width="620" cellspacing="0">
+ <td class="content">
+ <b>(lldb)</b> script import Foo_Tools<br/>
+ <b>(lldb)</b> type synthetic add Foo --python-class Foo_Tools.Foo_Provider
+ </td>
+ <table>
+ <code> <b>(lldb)</b> frame variable a_foo<br/>
+ (Foo) a_foo = {<br/>
+ x = 1<br/>
+ y = "Hello world"<br/>
+ } <br/>
+ </code> </p>
+
+ <p>Currently, in LLDB <a href="http://llvm.org/svn/llvm-project/lldb/trunk/">top of tree</a>, synthetic children providers are enabled for
+ <code>std::vector<T></code>, <code>std::list<T></code> and <code>std::map<K,V></code>.</p>
+
+ <p>Synthetic children enable a new symbol for summary strings, <code>${svar</code>. This symbol tells LLDB to refer expression paths to the
+ synthetic children instead of the real ones. While in certain cases, you can use <code>${var.<i>synthetic-child-path</i>}</code> and LLDB will
+ access the synthetic child correctly, it is best to always use <code>${svar</code> to refer to synthetic children. For instance,</p>
+
+ <table class="stats" width="620" cellspacing="0">
+ <td class="content">
+ <b>(lldb)</b> type summary add --expand -x "std::vector<" --summary-string "${svar%#} items"
+ </td>
+ <table>
+ <code> <b>(lldb)</b> frame variable numbers<br/>
+ (std::vector<int>) numbers = 4 items {<br/>
+ (int) [0] = 1<br/>
+ (int) [1] = 12<br/>
+ (int) [2] = 123<br/>
+ (int) [3] = 1234<br/>
+ }<br/>
+ </code> </p>
+
</div>
</div>
+
+ <div class="post">
+ <h1 class="postheader">Filters</h1>
+ <div class="postcontent">
+
+ <p>Filters are a solution to the display of complex classes.
+ At times, classes have many member variables but not all of these are actually
+ necessary for the user to see.</p>
+ <p>A filter will solve this issue by only letting the user see those member
+ variables he cares about. Of course, the equivalent of a filter can be implemented easily
+ using synthetic children, but a filter lets you get the job done without having to write
+ Python code.</p>
+ <p>For instance, if your class <code>Foobar</code> has member variables named <code>A</code> thru <code>Z</code>, but you only need to see
+ the ones named <code>B</code>, <code>H</code> and <code>Q</code>, you can define a filter:
+ <table class="stats" width="620" cellspacing="0">
+ <td class="content">
+ <b>(lldb)</b> type filter add Foo --child B --child H --child Q
+ </td>
+ <table>
+ <code> <b>(lldb)</b> frame variable a_foobar<br/>
+ (Foobar) a_foobar = {<br/>
+ (int) B = 1<br/>
+ (char) H = 'H'<br/>
+ (std::string) Q = "Hello world"<br/>
+ }<br/>
+ </code> </p>
+
+ </div>
+ </div>
+
<div class="post">
<h1 class="postheader">Finding formatters 101</h1>
More information about the lldb-commits
mailing list