Fix an issue where the oneliner printing of variables would ignore custom formatting
authorEnrico Granata <egranata@apple.com>
Wed, 17 Jun 2015 02:06:24 +0000 (02:06 +0000)
committerEnrico Granata <egranata@apple.com>
Wed, 17 Jun 2015 02:06:24 +0000 (02:06 +0000)
Because vector types use their formats in special ways (i.e. children get generated based on them), this change by itself would cause a regression in printing vector types with some custom formats
Work around that issue by special casing vector types out of this format-passdown mode. I believe there is a more general feature to be designed in this space, but until I see more cases of interest, I am going to leave this as a special case

Fixes rdar://20810062

llvm-svn: 239873

lldb/include/lldb/DataFormatters/ValueObjectPrinter.h
lldb/source/DataFormatters/ValueObjectPrinter.cpp
lldb/test/functionalities/data-formatter/format-propagation/TestFormatPropagation.py
lldb/test/functionalities/data-formatter/vector-types/TestVectorTypesFormatting.py

index dc05fd4..847b39e 100644 (file)
@@ -22,6 +22,8 @@
 #include "lldb/Core/ValueObject.h"
 #include "lldb/DataFormatters/TypeSummary.h"
 
+#include "llvm/ADT/Optional.h"
+
 namespace lldb_private {
 
 struct DumpValueObjectOptions
@@ -371,6 +373,9 @@ protected:
     bool
     PrintChildrenOneLiner (bool hide_names);
     
+    lldb::Format
+    GetFormatForChildElements ();
+    
 private:
     
     ValueObject *m_orig_valobj;
@@ -391,6 +396,7 @@ private:
     std::string m_summary;
     std::string m_error;
     std::pair<TypeValidatorResult,std::string> m_validation;
+    llvm::Optional<lldb::Format> m_children_format;
     
     friend struct StringSummaryFormat;
     
index 7c794ee..822c25b 100644 (file)
@@ -83,6 +83,7 @@ ValueObjectPrinter::Init (ValueObject* valobj,
     m_value.assign("");
     m_summary.assign("");
     m_error.assign("");
+    m_children_format.reset();
 }
 
 bool
@@ -502,12 +503,25 @@ ValueObjectPrinter::PrintChildrenPreamble ()
     }
 }
 
+lldb::Format
+ValueObjectPrinter::GetFormatForChildElements ()
+{
+    // we special case vector types here because for a vector type the format is not trivially passed down but is one of the things
+    // the synthetic child provider uses to decide how to produce children in the first place - in general this might be something
+    // we'd want to expose in some cleaner way, but until there is more than one instance of this, it's hard to design this capability
+    // in a sensible way, so for now, leave this alone as a special case
+    if (m_children_format.hasValue())
+        return m_children_format.getValue();
+    
+    return (m_children_format = m_clang_type.IsVectorType(nullptr, nullptr) ? lldb::eFormatInvalid : options.m_format).getValue();
+}
+
 void
 ValueObjectPrinter::PrintChild (ValueObjectSP child_sp,
                                 uint32_t curr_ptr_depth)
 {
     DumpValueObjectOptions child_options(options);
-    child_options.SetFormat(options.m_format).SetSummary().SetRootValueObjectName();
+    child_options.SetFormat(GetFormatForChildElements()).SetSummary().SetRootValueObjectName();
     child_options.SetScopeChecked(true).SetHideName(options.m_hide_name).SetHideValue(options.m_hide_value)
     .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 ? child_options.m_omit_summary_depth - 1 : 0);
     if (child_sp.get())
@@ -630,7 +644,7 @@ ValueObjectPrinter::PrintChildrenOneLiner (bool hide_names)
                 }
                 child_sp->DumpPrintableRepresentation(*m_stream,
                                                       ValueObject::eValueObjectRepresentationStyleSummary,
-                                                      lldb::eFormatInvalid,
+                                                      GetFormatForChildElements(),
                                                       ValueObject::ePrintableRepresentationSpecialCasesDisable);
             }
         }
index c4fd55f..816f877 100644 (file)
@@ -83,6 +83,9 @@ class FormatPropagationTestCase(TestBase):
         Y.SetFormat(lldb.eFormatDefault)
         self.assertTrue(X.GetValue() == "0x00000004", "X is not hex as it asked")
         self.assertTrue(Y.GetValue() == "2", "Y is not defaulted")
+        
+        # check that 'frame variable' propagates the format correctly
+        self.expect('frame variable -f x', substrs=['0x00000004', '0x00000002'])
 
 if __name__ == '__main__':
     import atexit
index 14cc63f..cc2a7a0 100644 (file)
@@ -71,6 +71,7 @@ class VectorTypesFormattingTestCase(TestBase):
         
         self.expect("expr -f int16_t[] -- v", substrs=['[0] = 0', '[1] = 16288', '[2] = 0', '[3] = 16288', '[4] = 0', '[5] = 16416', '[6] = 0', '[7] = 16416'])
         self.expect("expr -f uint128_t[] -- v", substrs=['[0] = 85236745249553456609335044694184296448'])
+        self.expect("expr -f x -- v", substrs=['[0] = 0x3fa00000', '[3] = 0x40200000'])
         
         oldValue = v.GetChildAtIndex(0).GetValue()
         v.SetFormat(lldb.eFormatHex)