summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEnrico Granata <egranata@apple.com>2014-12-09 21:41:16 +0000
committerEnrico Granata <egranata@apple.com>2014-12-09 21:41:16 +0000
commit986fa5f4eb037877fd470770be0a7ca9ebeac9ca (patch)
tree576063bc56686401046bf959865b97cee01d2dab
parent93e9cf8aa43545d5ebe7ea10642eb19ec458554d (diff)
downloadbcm5719-llvm-986fa5f4eb037877fd470770be0a7ca9ebeac9ca.tar.gz
bcm5719-llvm-986fa5f4eb037877fd470770be0a7ca9ebeac9ca.zip
Extend ValueObject::GetExpressionPath() to do something reasonable for synthetic children
Because of the way they are created, synthetic children cannot (in general) have a sane expression path A solution to this would be letting the parent front-end generate expression paths for its children Doing so requires a significant amount of refactoring, and might not always lead to better results (esp. w.r.t. C++ templates) This commit takes a simpler approach: - if a synthetic child is of pointer type and it's a target pointer, then emit *((T)value) - if a synthetic child is a non-pointer, but its location is in the target, then emit *((T*)loadAddr) - if a synthetic child has a value, emit ((T)value) - else, don't emit anything Fixes rdar://18442386 llvm-svn: 223836
-rw-r--r--lldb/source/Core/ValueObject.cpp40
-rw-r--r--lldb/test/python_api/exprpath_synthetic/TestExprPathSynthetic.py3
-rw-r--r--lldb/test/python_api/exprpath_synthetic/main.mm20
3 files changed, 63 insertions, 0 deletions
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index 5487b601655..33e968d1c1b 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -2540,6 +2540,46 @@ ValueObject::IsBaseClass (uint32_t& depth)
void
ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat)
{
+ // synthetic children do not actually "exist" as part of the hierarchy, and sometimes they are consed up in ways
+ // that don't make sense from an underlying language/API standpoint. So, use a special code path here to return
+ // something that can hopefully be used in expression
+ if (m_is_synthetic_children_generated)
+ {
+ UpdateValueIfNeeded();
+
+ if (m_value.GetValueType() == Value::eValueTypeLoadAddress)
+ {
+ if (IsPointerOrReferenceType())
+ {
+ s.Printf("((%s)0x%" PRIx64 ")",
+ GetTypeName().AsCString("void"),
+ GetValueAsUnsigned(0));
+ return;
+ }
+ else
+ {
+ uint64_t load_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
+ if (load_addr != LLDB_INVALID_ADDRESS)
+ {
+ s.Printf("(*( (%s *)0x%" PRIx64 "))",
+ GetTypeName().AsCString("void"),
+ load_addr);
+ return;
+ }
+ }
+ }
+
+ if (CanProvideValue())
+ {
+ s.Printf("((%s)%s)",
+ GetTypeName().AsCString("void"),
+ GetValueAsCString());
+ return;
+ }
+
+ return;
+ }
+
const bool is_deref_of_parent = IsDereferenceOfParent ();
if (is_deref_of_parent && epformat == eGetExpressionPathFormatDereferencePointers)
diff --git a/lldb/test/python_api/exprpath_synthetic/TestExprPathSynthetic.py b/lldb/test/python_api/exprpath_synthetic/TestExprPathSynthetic.py
new file mode 100644
index 00000000000..a70d2ca7414
--- /dev/null
+++ b/lldb/test/python_api/exprpath_synthetic/TestExprPathSynthetic.py
@@ -0,0 +1,3 @@
+import lldbinline
+
+lldbinline.MakeInlineTest(__file__, globals())
diff --git a/lldb/test/python_api/exprpath_synthetic/main.mm b/lldb/test/python_api/exprpath_synthetic/main.mm
new file mode 100644
index 00000000000..f7383a5a14d
--- /dev/null
+++ b/lldb/test/python_api/exprpath_synthetic/main.mm
@@ -0,0 +1,20 @@
+//===-- main.mm --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#import <Cocoa/Cocoa.h>
+#include <vector>
+
+int main (int argc, char const *argv[])
+{
+ std::vector<int> v{1,2,3,4,5};
+ NSArray *a = @[@"Hello",@"World",@"From Me"];
+ return 0; //% v = self.frame().FindVariable("v"); v0 = v.GetChildAtIndex(0); s = lldb.SBStream(); v0.GetExpressionPath(s);
+ //% self.runCmd("expr %s = 12" % s.GetData()); self.assertTrue(v0.GetValueAsUnsigned() == 12, "value change via expr failed")
+ //% a = self.frame().FindVariable("a"); a1 = a.GetChildAtIndex(1); s = lldb.SBStream(); a1.GetExpressionPath(s);
+ //% self.expect("po %s" % s.GetData(), substrs = ["World"])
+}
OpenPOWER on IntegriCloud