[Lldb-commits] [lldb] r267372 - Add a --element-count option to the expression command

Enrico Granata via lldb-commits lldb-commits at lists.llvm.org
Sun Apr 24 17:52:47 PDT 2016


Author: enrico
Date: Sun Apr 24 19:52:47 2016
New Revision: 267372

URL: http://llvm.org/viewvc/llvm-project?rev=267372&view=rev
Log:
Add a --element-count option to the expression command
This option evaluates an expression and, if the result is of pointer type, treats it as if it was an array of that many elements and displays such elements

This has a couple subtle points but is mostly as straightforward as it sounds

Add a parray N <expr> alias for this new mode

Also, extend the --object-description mode to do the moral equivalent of the above but display each element in --object-description mode
Add a poarray N <expr> alias for this


Added:
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/TestPrintArray.py
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/main.cpp
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/TestPrintObjectArray.py
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/main.mm
Modified:
    lldb/trunk/include/lldb/DataFormatters/DumpValueObjectOptions.h
    lldb/trunk/include/lldb/DataFormatters/ValueObjectPrinter.h
    lldb/trunk/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h
    lldb/trunk/source/Commands/CommandObjectExpression.cpp
    lldb/trunk/source/DataFormatters/DumpValueObjectOptions.cpp
    lldb/trunk/source/DataFormatters/ValueObjectPrinter.cpp
    lldb/trunk/source/Interpreter/CommandInterpreter.cpp
    lldb/trunk/source/Interpreter/OptionGroupValueObjectDisplay.cpp

Modified: lldb/trunk/include/lldb/DataFormatters/DumpValueObjectOptions.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/DumpValueObjectOptions.h?rev=267372&r1=267371&r2=267372&view=diff
==============================================================================
--- lldb/trunk/include/lldb/DataFormatters/DumpValueObjectOptions.h (original)
+++ lldb/trunk/include/lldb/DataFormatters/DumpValueObjectOptions.h Sun Apr 24 19:52:47 2016
@@ -152,6 +152,9 @@ public:
 
     DumpValueObjectOptions&
     SetRevealEmptyAggregates (bool reveal = true);
+    
+    DumpValueObjectOptions&
+    SetElementCount (uint32_t element_count = 0);
 
 public:
     uint32_t m_max_depth = UINT32_MAX;
@@ -163,6 +166,7 @@ public:
     lldb::LanguageType m_varformat_language = lldb::eLanguageTypeUnknown;
     PointerDepth m_max_ptr_depth;
     DeclPrintingHelper m_decl_printing_helper;
+    uint32_t m_element_count = 0;
     bool m_use_synthetic : 1;
     bool m_scope_already_checked : 1;
     bool m_flat_output : 1;

Modified: lldb/trunk/include/lldb/DataFormatters/ValueObjectPrinter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/ValueObjectPrinter.h?rev=267372&r1=267371&r2=267372&view=diff
==============================================================================
--- lldb/trunk/include/lldb/DataFormatters/ValueObjectPrinter.h (original)
+++ lldb/trunk/include/lldb/DataFormatters/ValueObjectPrinter.h Sun Apr 24 19:52:47 2016
@@ -153,6 +153,10 @@ protected:
     void
     PrintChildrenPostamble (bool print_dotdotdot);
     
+    lldb::ValueObjectSP
+    GenerateChild (ValueObject* synth_valobj,
+                   size_t idx);
+    
     void
     PrintChild (lldb::ValueObjectSP child_sp,
                 const DumpValueObjectOptions::PointerDepth& curr_ptr_depth);

Modified: lldb/trunk/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h?rev=267372&r1=267371&r2=267372&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h (original)
+++ lldb/trunk/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h Sun Apr 24 19:52:47 2016
@@ -77,6 +77,7 @@ public:
     uint32_t no_summary_depth;
     uint32_t max_depth;
     uint32_t ptr_depth;
+    uint32_t elem_count;
     lldb::DynamicValueType use_dynamic;
 };
 

Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/Makefile?rev=267372&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/Makefile Sun Apr 24 19:52:47 2016
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/TestPrintArray.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/TestPrintArray.py?rev=267372&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/TestPrintArray.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/TestPrintArray.py Sun Apr 24 19:52:47 2016
@@ -0,0 +1,70 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import datetime
+import os, time
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class PrintArrayTestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    def test_print_array(self):
+        """Test that expr -Z works"""
+        self.build()
+        self.printarray_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', 'break here')
+
+    def printarray_data_formatter_commands(self):
+        """Test that expr -Z works"""
+        self.runCmd("file 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)
+
+        # 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 format clear', check=False)
+            self.runCmd('type summary clear', check=False)
+            self.runCmd('type synth clear', check=False)
+
+        # Execute the cleanup function during test case tear down.
+        self.addTearDownHook(cleanup)
+        
+        self.expect('expr --element-count 3 -- data', substrs=['[0] = 1', '[1] = 3', '[2] = 5'])
+        self.expect('expr data', substrs=['int *', '$', '0x'])
+        self.expect('expr -f binary --element-count 0 -- data', substrs=['int *', '$', '0b'])
+        self.expect('expr -f hex --element-count 3 -- data', substrs=['[0] = 0x', '1', '[1] = 0x', '3', '[2] = 0x', '5'])
+        self.expect('expr -f binary --element-count 2 -- data', substrs=['int *', '$', '0x', '[0] = 0b', '1', '[1] = 0b', '11'])
+        self.expect('parray 3 data', substrs=['[0] = 1', '[1] = 3', '[2] = 5'])
+        self.expect('parray `1 + 1 + 1` data', substrs=['[0] = 1', '[1] = 3', '[2] = 5'])
+        self.expect('parray `data[1]` data', substrs=['[0] = 1', '[1] = 3', '[2] = 5'])
+        self.expect('parray/x 3 data', substrs=['[0] = 0x', '1', '[1] = 0x', '3', '[2] = 0x', '5'])
+        self.expect('parray/x `data[1]` data', substrs=['[0] = 0x', '1', '[1] = 0x', '3', '[2] = 0x', '5'])
+
+        # check error conditions
+        self.expect('expr --element-count 10 -- 123', error=True, substrs=['expression cannot be used with --element-count as it does not refer to a pointer'])
+        self.expect('expr --element-count 10 -- (void*)123', error=True, substrs=['expression cannot be used with --element-count as it refers to a pointer to void'])
+        self.expect('parray data', error=True, substrs=["invalid element count 'data'"])
+        self.expect('parray data data', error=True, substrs=["invalid element count 'data'"])
+        self.expect('parray', error=True, substrs=['Not enough arguments provided'])

Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/main.cpp?rev=267372&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/main.cpp (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/main.cpp Sun Apr 24 19:52:47 2016
@@ -0,0 +1,29 @@
+//===-- 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 <functional>
+#include <stdlib.h>
+
+template<typename ElemType>
+ElemType* alloc(size_t count, std::function<ElemType(size_t)> get)
+{
+  ElemType *elems = new ElemType[count];
+  for(size_t i = 0; i < count; i++)
+    elems[i] = get(i);
+  return elems;
+}
+
+int main (int argc, const char * argv[])
+{
+  int* data = alloc<int>(5, [] (size_t idx) -> int {
+    return 2 * idx + 1;
+  });
+  return 0; // break here
+}
+

Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/Makefile?rev=267372&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/Makefile Sun Apr 24 19:52:47 2016
@@ -0,0 +1,9 @@
+LEVEL = ../../../make
+
+OBJCXX_SOURCES := main.mm
+
+CFLAGS_EXTRAS += -w
+
+include $(LEVEL)/Makefile.rules
+
+LDFLAGS += -framework Foundation

Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/TestPrintObjectArray.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/TestPrintObjectArray.py?rev=267372&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/TestPrintObjectArray.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/TestPrintObjectArray.py Sun Apr 24 19:52:47 2016
@@ -0,0 +1,60 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+from __future__ import print_function
+
+
+
+import datetime
+import os, time
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class PrintObjectArrayTestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    @skipUnlessDarwin
+    def test_print_array(self):
+        """Test that expr -O -Z works"""
+        self.build()
+        self.printarray_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.mm', 'break here')
+
+    def printarray_data_formatter_commands(self):
+        """Test that expr -O -Z works"""
+        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+        lldbutil.run_break_set_by_file_and_line (self, "main.mm", self.line, num_expected_locations=1, loc_exact=True)
+
+        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 format clear', check=False)
+            self.runCmd('type summary clear', check=False)
+            self.runCmd('type synth clear', check=False)
+
+        # Execute the cleanup function during test case tear down.
+        self.addTearDownHook(cleanup)
+
+        self.expect('expr --element-count 3 --object-description -- objects', substrs=['3735928559', '4276993775', '3203398366', 'Hello', 'World', 'Two =', '1 ='])
+        self.expect('poarray 3 objects', substrs=['3735928559', '4276993775', '3203398366', 'Hello', 'World', 'Two =', '1 ='])
+        self.expect('expr --element-count 3 --object-description --description-verbosity=full -- objects', substrs=['[0] =', '3735928559', '4276993775', '3203398366', '[1] =', 'Hello', 'World', '[2] =', 'Two =', '1 ='])
+        self.expect('parray 3 objects', substrs=['[0] = 0x', '[1] = 0x', '[2] = 0x'])
+        self.expect('expr --element-count 3 -d run -- objects', substrs=['3 elements', '2 elements', '2 key/value pairs'])
+        self.expect('expr --element-count 3 -d run --ptr-depth=1 -- objects', substrs=['3 elements', '2 elements', '2 key/value pairs', '3735928559', '4276993775', '3203398366', '"Hello"', '"World"'])

Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/main.mm
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/main.mm?rev=267372&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/main.mm (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/main.mm Sun Apr 24 19:52:47 2016
@@ -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.
+//
+//===----------------------------------------------------------------------===//
+
+#import <Foundation/Foundation.h>
+
+struct ThreeObjects
+{
+  id one;
+  id two;
+  id three;
+};
+
+int main()
+{
+  NSArray *array1 = @[@0xDEADBEEF, @0xFEEDBEEF, @0xBEEFFADE];
+  NSArray *array2 = @[@"Hello", @"World"];
+  NSDictionary *dictionary = @{@1: array2, @"Two": array2};
+  ThreeObjects *tobjects = new ThreeObjects();
+  tobjects->one = array1;
+  tobjects->two = array2;
+  tobjects->three = dictionary;
+  id* objects = (id*)tobjects;
+  return 0; // break here
+}

Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=267372&r1=267371&r2=267372&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Sun Apr 24 19:52:47 2016
@@ -282,6 +282,18 @@ CommandObjectExpression::GetOptions ()
     return &m_option_group;
 }
 
+static lldb_private::Error
+CanBeUsedForElementCountPrinting (ValueObject& valobj)
+{
+    CompilerType type(valobj.GetCompilerType());
+    CompilerType pointee;
+    if (!type.IsPointerType(&pointee))
+        return Error("as it does not refer to a pointer");
+    if (pointee.IsVoidType())
+        return Error("as it refers to a pointer to void");
+    return Error();
+}
+
 bool
 CommandObjectExpression::EvaluateExpression(const char *expr,
                                             Stream *output_stream,
@@ -356,6 +368,17 @@ CommandObjectExpression::EvaluateExpress
                     if (format != eFormatDefault)
                         result_valobj_sp->SetFormat (format);
 
+                    if (m_varobj_options.elem_count > 0)
+                    {
+                        Error error(CanBeUsedForElementCountPrinting(*result_valobj_sp));
+                        if (error.Fail())
+                        {
+                            result->AppendErrorWithFormat("expression cannot be used with --element-count %s\n", error.AsCString(""));
+                            result->SetStatus(eReturnStatusFailed);
+                            return false;
+                        }
+                    }
+
                     DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(m_command_options.m_verbosity,format));
                     options.SetVariableFormatDisplayLanguage(result_valobj_sp->GetPreferredDisplayLanguage());
 

Modified: lldb/trunk/source/DataFormatters/DumpValueObjectOptions.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/DataFormatters/DumpValueObjectOptions.cpp?rev=267372&r1=267371&r2=267372&view=diff
==============================================================================
--- lldb/trunk/source/DataFormatters/DumpValueObjectOptions.cpp (original)
+++ lldb/trunk/source/DataFormatters/DumpValueObjectOptions.cpp Sun Apr 24 19:52:47 2016
@@ -242,4 +242,10 @@ DumpValueObjectOptions::SetRevealEmptyAg
     m_reveal_empty_aggregates = reveal;
     return *this;
 }
-                                
+
+DumpValueObjectOptions&
+DumpValueObjectOptions::SetElementCount (uint32_t element_count)
+{
+    m_element_count = element_count;
+    return *this;
+}

Modified: lldb/trunk/source/DataFormatters/ValueObjectPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/DataFormatters/ValueObjectPrinter.cpp?rev=267372&r1=267371&r2=267372&view=diff
==============================================================================
--- lldb/trunk/source/DataFormatters/ValueObjectPrinter.cpp (original)
+++ lldb/trunk/source/DataFormatters/ValueObjectPrinter.cpp Sun Apr 24 19:52:47 2016
@@ -416,11 +416,12 @@ ValueObjectPrinter::GetValueSummaryError
                                           std::string& summary,
                                           std::string& error)
 {
-    if (m_options.m_format != eFormatDefault && m_options.m_format != m_valobj->GetFormat())
-    {
-        m_valobj->GetValueAsCString(m_options.m_format,
-                                    value);
-    }
+    lldb::Format format = m_options.m_format;
+    // if I am printing synthetized elements, apply the format to those elements only
+    if (m_options.m_element_count > 0)
+        m_valobj->GetValueAsCString(lldb::eFormatDefault, value);
+    else if (format != eFormatDefault && format != m_valobj->GetFormat())
+        m_valobj->GetValueAsCString(format, value);
     else
     {
         const char* val_cstr = m_valobj->GetValueAsCString();
@@ -514,7 +515,7 @@ ValueObjectPrinter::PrintObjectDescripti
     if (ShouldPrintValueObject())
     {
         // let's avoid the overly verbose no description error for a nil thing
-        if (m_options.m_use_objc && !IsNil() && !IsUninitialized())
+        if (m_options.m_use_objc && !IsNil() && !IsUninitialized() && (m_options.m_element_count == 0))
         {
             if (!m_options.m_hide_value || !m_options.m_hide_name)
                 m_stream->Printf(" ");
@@ -587,6 +588,11 @@ ValueObjectPrinter::ShouldPrintChildren
     if (is_uninit)
         return false;
     
+    // if the user has specified an element count, always print children
+    // as it is explicit user demand being honored
+    if (m_options.m_element_count > 0)
+        return true;
+    
     TypeSummaryImpl* entry = GetSummaryFormatter();
     
     if (m_options.m_use_objc)
@@ -667,18 +673,22 @@ void
 ValueObjectPrinter::PrintChild (ValueObjectSP child_sp,
                                 const DumpValueObjectOptions::PointerDepth& curr_ptr_depth)
 {
+    const uint32_t consumed_depth = (m_options.m_element_count == 0) ? 1 : 0;
+    const bool does_consume_ptr_depth = ((IsPtr() && m_options.m_element_count == 0) || IsRef());
+
     DumpValueObjectOptions child_options(m_options);
     child_options.SetFormat(m_options.m_format).SetSummary().SetRootValueObjectName();
     child_options.SetScopeChecked(true).SetHideName(m_options.m_hide_name).SetHideValue(m_options.m_hide_value)
-    .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 ? child_options.m_omit_summary_depth - 1 : 0);
+    .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 ? child_options.m_omit_summary_depth - consumed_depth : 0)
+    .SetElementCount(0);
     
     if (child_sp.get())
     {
         ValueObjectPrinter child_printer(child_sp.get(),
                                          m_stream,
                                          child_options,
-                                         (IsPtr() || IsRef()) ? --curr_ptr_depth : curr_ptr_depth,
-                                         m_curr_depth + 1,
+                                         does_consume_ptr_depth ? --curr_ptr_depth : curr_ptr_depth,
+                                         m_curr_depth + consumed_depth,
                                          m_printed_instance_pointers);
         child_printer.PrintValueObject();
     }
@@ -689,6 +699,9 @@ ValueObjectPrinter::GetMaxNumChildrenToP
 {
     ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
     
+    if (m_options.m_element_count > 0)
+        return m_options.m_element_count;
+    
     size_t num_children = synth_m_valobj->GetNumChildren();
     print_dotdotdot = false;
     if (num_children)
@@ -743,6 +756,21 @@ ValueObjectPrinter::ShouldPrintEmptyBrac
     return true;
 }
 
+ValueObjectSP
+ValueObjectPrinter::GenerateChild (ValueObject* synth_valobj, size_t idx)
+{
+    if (m_options.m_element_count > 0)
+    {
+        // if generating pointer-as-array children, use GetSyntheticArrayMember
+        return synth_valobj->GetSyntheticArrayMember(idx, true);
+    }
+    else
+    {
+        // otherwise, do the usual thing
+        return synth_valobj->GetChildAtIndex(idx, true);
+    }
+}
+
 void
 ValueObjectPrinter::PrintChildren (bool value_printed,
                                    bool summary_printed,
@@ -758,8 +786,7 @@ ValueObjectPrinter::PrintChildren (bool
         
         for (size_t idx=0; idx<num_children; ++idx)
         {
-            ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true));
-            if (child_sp)
+            if (ValueObjectSP child_sp = GenerateChild(synth_m_valobj, idx))
             {
                 if (!any_children_printed)
                 {
@@ -866,6 +893,7 @@ ValueObjectPrinter::PrintChildrenIfNeede
                           m_options.m_show_types ||
                           !m_options.m_allow_oneliner_mode ||
                           m_options.m_flat_output ||
+                          (m_options.m_element_count > 0) ||
                           m_options.m_show_location) ? false : DataVisualization::ShouldPrintAsOneLiner(*m_valobj);
     bool is_instance_ptr = IsInstancePointer();
     uint64_t instance_ptr_value = LLDB_INVALID_ADDRESS;

Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=267372&r1=267371&r2=267372&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Sun Apr 24 19:52:47 2016
@@ -348,6 +348,8 @@ CommandInterpreter::Initialize ()
             po->SetHelp("Evaluate an expression in the current program context, using user defined variables and variables currently in scope, and display the result of evaluation in a language-specific manner.");
             po->SetHelpLong("");
         }
+        AddAlias("parray", cmd_obj_sp, "--element-count %1 --")->SetHelpLong("");
+        AddAlias("poarray", cmd_obj_sp, "--object-description --element-count %1 --")->SetHelpLong("");
     }
     
     cmd_obj_sp = GetCommandSPExact ("process kill", false);

Modified: lldb/trunk/source/Interpreter/OptionGroupValueObjectDisplay.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/OptionGroupValueObjectDisplay.cpp?rev=267372&r1=267371&r2=267372&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/OptionGroupValueObjectDisplay.cpp (original)
+++ lldb/trunk/source/Interpreter/OptionGroupValueObjectDisplay.cpp Sun Apr 24 19:52:47 2016
@@ -44,7 +44,8 @@ g_option_table[] =
     { LLDB_OPT_SET_1, false, "no-summary-depth",   'Y', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeCount,     "Set the depth at which omitting summary information stops (default is 1)."},
     { LLDB_OPT_SET_1, false, "raw-output",         'R', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,      "Don't use formatting options."},
     { LLDB_OPT_SET_1, false, "show-all-children",  'A', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,      "Ignore the upper bound on the number of children to show."},
-    { LLDB_OPT_SET_1, false, "validate",           'V',  OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,   "Show results of type validators."},
+    { LLDB_OPT_SET_1, false, "validate",           'V',  OptionParser::eRequiredArgument, nullptr, nullptr,0, eArgTypeBoolean,   "Show results of type validators."},
+    { LLDB_OPT_SET_1, false, "element-count",      'Z', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount,     "Treat the result of the expression as if its type is an array of this many values."},
     { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
 };
 
@@ -92,6 +93,12 @@ OptionGroupValueObjectDisplay::SetOption
             if (!success)
                 error.SetErrorStringWithFormat("invalid max depth '%s'", option_arg);
             break;
+
+        case 'Z':
+            elem_count = StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0, &success);
+            if (!success)
+                error.SetErrorStringWithFormat("invalid element count '%s'", option_arg);
+            break;
             
         case 'P':
             ptr_depth = StringConvert::ToUInt32 (option_arg, 0, 0, &success);
@@ -141,6 +148,7 @@ OptionGroupValueObjectDisplay::OptionPar
     use_objc          = false;
     max_depth         = UINT32_MAX;
     ptr_depth         = 0;
+    elem_count        = 0;
     use_synth         = true;
     be_raw            = false;
     ignore_cap        = false;
@@ -187,6 +195,8 @@ OptionGroupValueObjectDisplay::GetAsDump
         options.SetRawDisplay();
     
     options.SetRunValidator(run_validator);
+    
+    options.SetElementCount(elem_count);
 
     return options;
 }




More information about the lldb-commits mailing list