[Lldb-commits] [lldb] r299251 - Add support for sythetic operator dereference
Tamas Berghammer via lldb-commits
lldb-commits at lists.llvm.org
Fri Mar 31 13:23:22 PDT 2017
Author: tberghammer
Date: Fri Mar 31 15:23:22 2017
New Revision: 299251
URL: http://llvm.org/viewvc/llvm-project?rev=299251&view=rev
Log:
Add support for sythetic operator dereference
Summary:
After this change a sythetic child provider can generate a special child
named "$$dereference$$" what if present is used when "operator*" or
"operator->" used on a ValueObject. The goal of the change is to make
expressions like "up->foo" work inside the "frame variable" command.
Reviewers: labath, jingham
Subscribers: lldb-commits
Differential Revision: https://reviews.llvm.org/D31368
Modified:
lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/TestDataFormatterStdUniquePtr.py
lldb/trunk/source/Core/ValueObject.cpp
lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
lldb/trunk/source/Target/StackFrame.cpp
lldb/trunk/www/varformats.html
Modified: lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/TestDataFormatterStdUniquePtr.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/TestDataFormatterStdUniquePtr.py?rev=299251&r1=299250&r2=299251&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/TestDataFormatterStdUniquePtr.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/unique_ptr/TestDataFormatterStdUniquePtr.py Fri Mar 31 15:23:22 2017
@@ -42,13 +42,17 @@ class StdUniquePtrDataFormatterTestCase(
self.expect("frame variable sdp", substrs=['sdp = 0x', 'deleter = ', 'a = 3', 'b = 4'])
self.assertEqual(123, frame.GetValueForVariablePath("iup.object").GetValueAsUnsigned())
+ self.assertEqual(123, frame.GetValueForVariablePath("*iup").GetValueAsUnsigned())
self.assertFalse(frame.GetValueForVariablePath("iup.deleter").IsValid())
self.assertEqual('"foobar"', frame.GetValueForVariablePath("sup.object").GetSummary())
+ self.assertEqual('"foobar"', frame.GetValueForVariablePath("*sup").GetSummary())
self.assertFalse(frame.GetValueForVariablePath("sup.deleter").IsValid())
self.assertEqual(456, frame.GetValueForVariablePath("idp.object").GetValueAsUnsigned())
+ self.assertEqual(456, frame.GetValueForVariablePath("*idp").GetValueAsUnsigned())
self.assertEqual('"baz"', frame.GetValueForVariablePath("sdp.object").GetSummary())
+ self.assertEqual('"baz"', frame.GetValueForVariablePath("*sdp").GetSummary())
idp_deleter = frame.GetValueForVariablePath("idp.deleter")
self.assertTrue(idp_deleter.IsValid())
@@ -86,5 +90,7 @@ class StdUniquePtrDataFormatterTestCase(
frame = self.frame()
self.assertTrue(frame.IsValid())
self.assertEqual(2, frame.GetValueForVariablePath("f1->fp.object.data").GetValueAsUnsigned())
+ self.assertEqual(2, frame.GetValueForVariablePath("f1->fp->data").GetValueAsUnsigned())
self.assertEqual(1, frame.GetValueForVariablePath("f1->fp.object.fp.object.data").GetValueAsUnsigned())
+ self.assertEqual(1, frame.GetValueForVariablePath("f1->fp->fp->data").GetValueAsUnsigned())
Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=299251&r1=299250&r2=299251&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Fri Mar 31 15:23:22 2017
@@ -2889,6 +2889,11 @@ ValueObjectSP ValueObject::Dereference(E
child_is_base_class, child_is_deref_of_parent, eAddressTypeInvalid,
language_flags);
}
+ } else if (HasSyntheticValue()) {
+ m_deref_valobj =
+ GetSyntheticValue()
+ ->GetChildMemberWithName(ConstString("$$dereference$$"), true)
+ .get();
}
if (m_deref_valobj) {
Modified: lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp?rev=299251&r1=299250&r2=299251&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp (original)
+++ lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp Fri Mar 31 15:23:22 2017
@@ -114,7 +114,8 @@ size_t LibStdcppUniquePtrSyntheticFrontE
return 0;
if (name == ConstString("del") || name == ConstString("deleter"))
return 1;
- if (name == ConstString("obj") || name == ConstString("object"))
+ if (name == ConstString("obj") || name == ConstString("object") ||
+ name == ConstString("$$dereference$$"))
return 2;
return UINT32_MAX;
}
Modified: lldb/trunk/source/Target/StackFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=299251&r1=299250&r2=299251&view=diff
==============================================================================
--- lldb/trunk/source/Target/StackFrame.cpp (original)
+++ lldb/trunk/source/Target/StackFrame.cpp Fri Mar 31 15:23:22 2017
@@ -606,8 +606,10 @@ ValueObjectSP StackFrame::GetValueForVar
// Calculate the next separator index ahead of time
ValueObjectSP child_valobj_sp;
const char separator_type = var_expr[0];
+ bool expr_is_ptr = false;
switch (separator_type) {
case '-':
+ expr_is_ptr = true;
if (var_expr.size() >= 2 && var_expr[1] != '>')
return ValueObjectSP();
@@ -624,11 +626,32 @@ ValueObjectSP StackFrame::GetValueForVar
return ValueObjectSP();
}
}
+
+ // If we have a non pointer type with a sythetic value then lets check if
+ // we have an sythetic dereference specified.
+ if (!valobj_sp->IsPointerType() && valobj_sp->HasSyntheticValue()) {
+ Error deref_error;
+ if (valobj_sp->GetCompilerType().IsReferenceType()) {
+ valobj_sp = valobj_sp->GetSyntheticValue()->Dereference(deref_error);
+ if (error.Fail()) {
+ error.SetErrorStringWithFormatv(
+ "Failed to dereference reference type: %s", deref_error);
+ return ValueObjectSP();
+ }
+ }
+
+ valobj_sp = valobj_sp->Dereference(deref_error);
+ if (error.Fail()) {
+ error.SetErrorStringWithFormatv(
+ "Failed to dereference sythetic value: %s", deref_error);
+ return ValueObjectSP();
+ }
+ expr_is_ptr = false;
+ }
+
var_expr = var_expr.drop_front(); // Remove the '-'
LLVM_FALLTHROUGH;
case '.': {
- const bool expr_is_ptr = var_expr[0] == '>';
-
var_expr = var_expr.drop_front(); // Remove the '.' or '>'
separator_idx = var_expr.find_first_of(".-[");
ConstString child_name(var_expr.substr(0, var_expr.find_first_of(".-[")));
Modified: lldb/trunk/www/varformats.html
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/www/varformats.html?rev=299251&r1=299250&r2=299251&view=diff
==============================================================================
--- lldb/trunk/www/varformats.html (original)
+++ lldb/trunk/www/varformats.html Fri Mar 31 15:23:22 2017
@@ -1068,6 +1068,7 @@ def function (valobj,internal_dict):<br/
<sup>[2]</sup> This method is optional (starting with SVN rev166495/LLDB-175). While implementing it in terms of <code>num_children</code> is acceptable, implementors are encouraged to look for optimized coding alternatives whenever reasonable.
<br/>
<sup>[3]</sup> This method is optional (starting with SVN revision 219330). The SBValue you return here will most likely be a numeric type (int, float, ...) as its value bytes will be used as-if they were the value of the root SBValue proper. As a shortcut for this, you can inherit from lldb.SBSyntheticValueProvider, and just define get_value as other methods are defaulted in the superclass as returning default no-children responses.
+<p>If a synthetic child provider supplies a special child named <code>$$dereference$$</code> then it will be used when evaluating <code>opertaor*</code> and <code>operator-></code> in the <code>frame variable</code> command and related SB API functions.</p>
<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. Please, be aware that the code in those files (except bitfield/)
is legacy code and is not maintained.
You may especially want to begin looking at <a href="http://llvm.org/svn/llvm-project/lldb/trunk/examples/synthetic/bitfield">this example</a> to get
More information about the lldb-commits
mailing list