[Lldb-commits] [lldb] r223836 - Extend ValueObject::GetExpressionPath() to do something reasonable for synthetic children

Enrico Granata egranata at apple.com
Tue Dec 9 13:41:16 PST 2014


Author: enrico
Date: Tue Dec  9 15:41:16 2014
New Revision: 223836

URL: http://llvm.org/viewvc/llvm-project?rev=223836&view=rev
Log:
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


Added:
    lldb/trunk/test/python_api/exprpath_synthetic/
    lldb/trunk/test/python_api/exprpath_synthetic/TestExprPathSynthetic.py
    lldb/trunk/test/python_api/exprpath_synthetic/main.mm
Modified:
    lldb/trunk/source/Core/ValueObject.cpp

Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=223836&r1=223835&r2=223836&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Tue Dec  9 15:41:16 2014
@@ -2540,6 +2540,46 @@ ValueObject::IsBaseClass (uint32_t& dept
 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)

Added: lldb/trunk/test/python_api/exprpath_synthetic/TestExprPathSynthetic.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/exprpath_synthetic/TestExprPathSynthetic.py?rev=223836&view=auto
==============================================================================
--- lldb/trunk/test/python_api/exprpath_synthetic/TestExprPathSynthetic.py (added)
+++ lldb/trunk/test/python_api/exprpath_synthetic/TestExprPathSynthetic.py Tue Dec  9 15:41:16 2014
@@ -0,0 +1,3 @@
+import lldbinline
+
+lldbinline.MakeInlineTest(__file__, globals())

Added: lldb/trunk/test/python_api/exprpath_synthetic/main.mm
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/exprpath_synthetic/main.mm?rev=223836&view=auto
==============================================================================
--- lldb/trunk/test/python_api/exprpath_synthetic/main.mm (added)
+++ lldb/trunk/test/python_api/exprpath_synthetic/main.mm Tue Dec  9 15:41:16 2014
@@ -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"])
+}





More information about the lldb-commits mailing list