evgeny777 updated this revision to Diff 37733.
evgeny777 added a comment.

Review updated to reflect Enrico comments regarding signed/unsigned char.
Now all character types are evaluated as ASCII code (signed or unsigned) + 
value.

Additional method introduced to SBValue to check if type is signed or unsigned 
integer


http://reviews.llvm.org/D13799

Files:
  include/lldb/API/SBValue.h
  source/API/SBValue.cpp
  test/tools/lldb-mi/data/TestMiData.py
  test/tools/lldb-mi/symbol/TestMiSymbol.py
  tools/lldb-mi/MICmnLLDBDebugger.cpp
  tools/lldb-mi/MICmnLLDBDebugger.h
  tools/lldb-mi/MICmnLLDBUtilSBValue.cpp
  tools/lldb-mi/MICmnLLDBUtilSBValue.h

Index: tools/lldb-mi/MICmnLLDBUtilSBValue.h
===================================================================
--- tools/lldb-mi/MICmnLLDBUtilSBValue.h
+++ tools/lldb-mi/MICmnLLDBUtilSBValue.h
@@ -51,11 +51,8 @@
   private:
     template <typename charT> CMIUtilString ReadCStringFromHostMemory(lldb::SBValue &vrValue, const MIuint vnMaxLen = UINT32_MAX) const;
     bool GetSimpleValue(const bool vbHandleArrayType, CMIUtilString &vrValue) const;
-    CMIUtilString GetSimpleValueChar() const;
-    CMIUtilString GetSimpleValueCStringPointer() const;
-    CMIUtilString GetSimpleValueCStringArray() const;
     bool GetCompositeValue(const bool vbPrintFieldNames, CMICmnMIValueTuple &vwrMiValueTuple, const MIuint vnDepth = 1) const;
-    CMIUtilString GetValueSummary() const;
+    CMIUtilString GetValueSummary(bool valueOnly, const CMIUtilString& failVal = CMIUtilString()) const;
 
     // Statics:
   private:
Index: tools/lldb-mi/MICmnLLDBUtilSBValue.cpp
===================================================================
--- tools/lldb-mi/MICmnLLDBUtilSBValue.cpp
+++ tools/lldb-mi/MICmnLLDBUtilSBValue.cpp
@@ -123,31 +123,13 @@
     const MIuint nChildren = m_rValue.GetNumChildren();
     if (nChildren == 0)
     {
-        if (m_bHandleCharType && IsCharType())
-        {
-            vwrValue = GetSimpleValueChar();
-            return MIstatus::success;
-        }
-        else
-        {
-            const char *pValue = m_rValue.GetValue();
-            vwrValue = pValue != nullptr ? pValue : m_pUnkwn;
-            return MIstatus::success;
-        }
+        vwrValue = GetValueSummary(!m_bHandleCharType && IsCharType(), m_pUnkwn);
+        return MIstatus::success;
     }
     else if (IsPointerType())
     {
-        if (m_bHandleCharType && IsPointeeCharType())
-        {
-            vwrValue = GetSimpleValueCStringPointer();
-            return MIstatus::success;
-        }
-        else
-        {
-            const char *pValue = m_rValue.GetValue();
-            vwrValue = pValue != nullptr ? pValue : m_pUnkwn;
-            return MIstatus::success;
-        }
+        vwrValue = GetValueSummary(!m_bHandleCharType && IsPointeeCharType(), m_pUnkwn);
+        return MIstatus::success;
     }
     else if (IsArrayType())
     {
@@ -157,7 +139,7 @@
                                                                         bPrintCharArrayAsString) && bPrintCharArrayAsString;
         if (bPrintCharArrayAsString && m_bHandleCharType && IsFirstChildCharType())
         {
-            vwrValue = GetSimpleValueCStringArray();
+            vwrValue = GetValueSummary(false);
             return MIstatus::success;
         }
         else if (vbHandleArrayType)
@@ -170,152 +152,15 @@
     {
         // Treat composite value which has registered summary
         // (for example with AddCXXSummary) as simple value
-        vwrValue = GetValueSummary();
+        vwrValue = GetValueSummary(false);
         if (!vwrValue.empty())
             return MIstatus::success;
     }
 
     // Composite variable type i.e. struct
     return MIstatus::failure;
 }
 
-//++ ------------------------------------------------------------------------------------
-// Details: Retrieve from the LLDB SB Value object the char value of the variable.
-// Type:    Method.
-// Args:    None.
-// Return:  CMIUtilString   - The char value of the variable.
-// Throws:  None.
-//--
-CMIUtilString
-CMICmnLLDBUtilSBValue::GetSimpleValueChar() const
-{
-    const CMIUtilString& summary = GetValueSummary();
-    if (!summary.empty())
-        return summary;
-
-    const uint64_t value = m_rValue.GetValueAsUnsigned();
-    if (value == 0)
-    {
-        const uint64_t nFailValue = 1;
-        if (nFailValue == m_rValue.GetValueAsUnsigned(nFailValue))
-            return m_pUnkwn;
-    }
-
-    const lldb::BasicType eType = m_rValue.GetType().GetBasicType();
-    switch (eType)
-    {
-        default:
-            assert(0 && "value must be a char type");
-        case lldb::eBasicTypeChar:
-        case lldb::eBasicTypeSignedChar:
-        case lldb::eBasicTypeUnsignedChar:
-        {
-            const CMIUtilString prefix(CMIUtilString::ConvertToPrintableASCII((char)value));
-            return CMIUtilString::Format("%" PRIu8 " '%s'", (uint8_t)value, prefix.c_str());
-        }
-        case lldb::eBasicTypeChar16:
-        {
-            const CMIUtilString prefix(CMIUtilString::ConvertToPrintableASCII((char16_t)value));
-            return CMIUtilString::Format("U+%04" PRIx16 " u'%s'", (uint16_t)value, prefix.c_str());
-        }
-        case lldb::eBasicTypeChar32:
-        {
-            const CMIUtilString prefix(CMIUtilString::ConvertToPrintableASCII((char32_t)value));
-            return CMIUtilString::Format("U+%08" PRIx32 " U'%s'", (uint32_t)value, prefix.c_str());
-        }
-    }
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Retrieve from the LLDB SB Value object of type char* the c-string value.
-// Type:    Method.
-// Args:    None.
-// Return:  CMIUtilString   - The c-string value of the variable.
-// Throws:  None.
-//--
-CMIUtilString
-CMICmnLLDBUtilSBValue::GetSimpleValueCStringPointer() const
-{
-    const CMIUtilString& summary = GetValueSummary();
-    if (!summary.empty())
-        return summary;
-
-    const char *value = m_rValue.GetValue();
-    if (value == nullptr)
-        return m_pUnkwn;
-
-    lldb::SBValue child = m_rValue.GetChildAtIndex(0);
-    const lldb::BasicType eType = child.GetType().GetBasicType();
-    switch (eType)
-    {
-        default:
-            assert(0 && "child must be a char type");
-        case lldb::eBasicTypeChar:
-        case lldb::eBasicTypeSignedChar:
-        case lldb::eBasicTypeUnsignedChar:
-        {
-            const CMIUtilString prefix(ReadCStringFromHostMemory<char>(child));
-            // Note code that has const in will not show the text suffix to the string pointer
-            // i.e. const char * pMyStr = "blah"; ==> "0x00007000"" <-- Eclipse shows this
-            // but        char * pMyStr = "blah"; ==> "0x00007000" "blah"" <-- Eclipse shows this
-            return CMIUtilString::Format("%s \"%s\"", value, prefix.c_str());
-        }
-        case lldb::eBasicTypeChar16:
-        {
-            const CMIUtilString prefix(ReadCStringFromHostMemory<char16_t>(child));
-            return CMIUtilString::Format("%s u\"%s\"", value, prefix.c_str());
-        }
-        case lldb::eBasicTypeChar32:
-        {
-            const CMIUtilString prefix(ReadCStringFromHostMemory<char32_t>(child));
-            return CMIUtilString::Format("%s U\"%s\"", value, prefix.c_str());
-        }
-    }
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Retrieve from the LLDB SB Value object of type char[] the c-string value.
-// Type:    Method.
-// Args:    None.
-// Return:  CMIUtilString   - The c-string value of the variable.
-// Throws:  None.
-//--
-CMIUtilString
-CMICmnLLDBUtilSBValue::GetSimpleValueCStringArray() const
-{
-    const CMIUtilString& summary = GetValueSummary();
-    if (!summary.empty())
-        return summary;
-
-    const MIuint nChildren = m_rValue.GetNumChildren();
-    lldb::SBValue child = m_rValue.GetChildAtIndex(0);
-    const lldb::BasicType eType = child.GetType().GetBasicType();
-    switch (eType)
-    {
-        default:
-            assert(0 && "value must be a char[] type");
-        case lldb::eBasicTypeChar:
-        case lldb::eBasicTypeSignedChar:
-        case lldb::eBasicTypeUnsignedChar:
-        {
-            const CMIUtilString prefix(ReadCStringFromHostMemory<char>(m_rValue, nChildren));
-            // TODO: to match char* it should be the following
-            //       return CMIUtilString::Format("[%u] \"%s\"", nChildren, prefix.c_str());
-            return CMIUtilString::Format("\"%s\"", prefix.c_str());
-        }
-        case lldb::eBasicTypeChar16:
-        {
-            const CMIUtilString prefix(ReadCStringFromHostMemory<char16_t>(m_rValue, nChildren));
-            return CMIUtilString::Format("u\"%s\"", prefix.c_str());
-        }
-        case lldb::eBasicTypeChar32:
-        {
-            const CMIUtilString prefix(ReadCStringFromHostMemory<char32_t>(m_rValue, nChildren));
-            return CMIUtilString::Format("U\"%s\"", prefix.c_str());
-        }
-    }
-}
-
 bool
 CMICmnLLDBUtilSBValue::GetCompositeValue(const bool vbPrintFieldNames, CMICmnMIValueTuple &vwrMiValueTuple,
                                          const MIuint vnDepth /* = 1 */) const
@@ -368,30 +213,37 @@
     return MIstatus::success;
 }
 
+// Returns value or value + summary, depending on valueOnly parameter value.
+// If result is an empty string returns failVal.
 CMIUtilString
-CMICmnLLDBUtilSBValue::GetValueSummary() const
-{
-    CMIUtilString valSummary;
-    if (m_rValue.IsValid())
-    {
-#ifndef LLDB_DISABLE_PYTHON
-        const char *c_str = m_rValue.GetSummary();
-        if (c_str && c_str[0])
+CMICmnLLDBUtilSBValue::GetValueSummary(bool valueOnly, const CMIUtilString& failVal) const
+{    
+    if (!m_rValue.IsValid())
+        return failVal;
+ 
+    CMIUtilString value, valSummary;
+    const char* c_value = m_rValue.GetValue();
+    if (valueOnly)
+        return c_value == nullptr ? failVal : c_value;
+    
+    const char* c_summary = m_rValue.GetSummary();   
+    if (c_value)
+        value = c_value;
+    else if (c_summary == nullptr)
+        return failVal;
+    
+    if (c_summary && c_summary[0])
+    {
+        valSummary = c_summary;
+        lldb::SBTypeSummary summary = m_rValue.GetTypeSummary();
+        if (summary.IsValid() && summary.DoesPrintValue(m_rValue) && !value.empty())
         {
-            valSummary = c_str;
-            lldb::SBTypeSummary summary = m_rValue.GetTypeSummary();
-            if (summary.IsValid() && summary.DoesPrintValue(m_rValue))
-            {
-                c_str = m_rValue.GetValue();
-                if (c_str && c_str[0])
-                {
-                    valSummary.insert(0, std::string(c_str) + " ");
-                }
-            }
+            valSummary.insert(0, value + " ");
         }
-#endif
+        return valSummary;
     }
-    return valSummary;
+    // no summary - return just value
+    return value;
 }
 
 //++ ------------------------------------------------------------------------------------
Index: tools/lldb-mi/MICmnLLDBDebugger.h
===================================================================
--- tools/lldb-mi/MICmnLLDBDebugger.h
+++ tools/lldb-mi/MICmnLLDBDebugger.h
@@ -93,7 +93,7 @@
     bool ClientSaveMask(const CMIUtilString &vClientName, const CMIUtilString &vBroadcasterClass, const MIuint vEventMask);
     bool ClientRemoveTheirMask(const CMIUtilString &vClientName, const CMIUtilString &vBroadcasterClass);
     bool ClientGetTheirMask(const CMIUtilString &vClientName, const CMIUtilString &vBroadcasterClass, MIuint &vwEventMask);
-
+    bool RegisterMISummaryProviders();
     // Overridden:
   private:
     // From CMICmnBase
Index: tools/lldb-mi/MICmnLLDBDebugger.cpp
===================================================================
--- tools/lldb-mi/MICmnLLDBDebugger.cpp
+++ tools/lldb-mi/MICmnLLDBDebugger.cpp
@@ -12,6 +12,10 @@
 #include "lldb/API/SBThread.h"
 #include "lldb/API/SBProcess.h"
 #include "lldb/API/SBCommandInterpreter.h"
+#include "lldb/API/SBTypeSummary.h"
+#include "lldb/API/SBTypeCategory.h"
+#include "lldb/API/SBTypeNameSpecifier.h"
+#include "lldb/API/SBStream.h"
 
 // In-house headers:
 #include "MICmnLLDBDebugger.h"
@@ -24,6 +28,33 @@
 #include "MIUtilSingletonHelper.h"
 
 //++ ------------------------------------------------------------------------------------
+// MI private summary providers
+static inline bool
+MI_char_summary_provider(lldb::SBValue value, lldb::SBTypeSummaryOptions options, lldb::SBStream &stream)
+{
+    bool is_signed;
+    if (!value.IsValid() || !value.IsIntegerType(is_signed))
+        return false;
+
+    if (is_signed)
+        stream.Printf("%d '%c'", (int)value.GetValueAsSigned(), (char)value.GetValueAsSigned());
+    else
+        stream.Printf("%u '%c'", (unsigned)value.GetValueAsUnsigned(), (char)value.GetValueAsUnsigned());
+    
+    return true;
+}
+
+//++ ------------------------------------------------------------------------------------
+// MI summary helper routines
+static inline bool
+MI_add_summary(lldb::SBTypeCategory category, const char *typeName, lldb::SBTypeSummary::FormatCallback cb,
+               uint32_t options, bool regex = false)
+{
+    lldb::SBTypeSummary summary = lldb::SBTypeSummary::CreateWithCallback(cb, options);
+    return summary.IsValid() ? category.AddTypeSummary(lldb::SBTypeNameSpecifier(typeName, regex), summary) : false;
+} 
+
+//++ ------------------------------------------------------------------------------------
 // Details: CMICmnLLDBDebugger constructor.
 // Type:    Method.
 // Args:    None.
@@ -98,7 +129,7 @@
         errMsg += GetErrorDescription().c_str();
     }
     bOk = bOk && InitStdStreams();
-
+    bOk = bOk && RegisterMISummaryProviders();
     m_bInitialized = bOk;
 
     if (!bOk && !HaveErrorDescription())
@@ -791,3 +822,38 @@
 {
     return m_constStrThisThreadId;
 }
+
+//++ ------------------------------------------------------------------------------------
+// Details: Registers lldb-mi custom summary providers
+// Type:    Method.
+// Args:    None.
+// Return:  MIstatus::success - Functionality succeeded.
+//          MIstatus::failure - Functionality failed.
+// Throws:  None.
+//--
+bool
+CMICmnLLDBDebugger::RegisterMISummaryProviders()
+{
+    static const char* miCategoryName = "lldb-mi";
+    lldb::SBTypeCategory miCategory = m_lldbDebugger.CreateCategory(miCategoryName);
+    if (!miCategory.IsValid())
+        return false;
+
+    if (MI_add_summary(miCategory, "char", MI_char_summary_provider,
+                        lldb::eTypeOptionHideValue | lldb::eTypeOptionSkipPointers))
+    {    
+        if (MI_add_summary(miCategory, "unsigned char", MI_char_summary_provider,
+                        lldb::eTypeOptionHideValue | lldb::eTypeOptionSkipPointers))
+        {
+            if (MI_add_summary(miCategory, "signed char", MI_char_summary_provider,
+                        lldb::eTypeOptionHideValue | lldb::eTypeOptionSkipPointers))
+            {    
+                miCategory.SetEnabled(true);            
+                return true;
+            }
+        }
+    }
+
+    m_lldbDebugger.DeleteCategory(miCategoryName);
+    return false;
+}
Index: test/tools/lldb-mi/symbol/TestMiSymbol.py
===================================================================
--- test/tools/lldb-mi/symbol/TestMiSymbol.py
+++ test/tools/lldb-mi/symbol/TestMiSymbol.py
@@ -31,8 +31,8 @@
 
         # Get address of main and its line
         self.runCmd("-data-evaluate-expression main")
-        self.expect("\^done,value=\"0x[0-9a-f]+\"")
-        addr = int(self.child.after.split("\"")[1], 16)
+        self.expect("\^done,value=\"0x[0-9a-f]+ \(a.out`main at main.cpp:[0-9]+\)\"")
+        addr = int(self.child.after.split("\"")[1].split(" ")[0], 16)
         line = line_number('main.cpp', '// FUNC_main')
 
         # Test that -symbol-list-lines works on valid data
Index: test/tools/lldb-mi/data/TestMiData.py
===================================================================
--- test/tools/lldb-mi/data/TestMiData.py
+++ test/tools/lldb-mi/data/TestMiData.py
@@ -31,8 +31,8 @@
 
         # Get an address for disassembling: use main
         self.runCmd("-data-evaluate-expression main")
-        self.expect("\^done,value=\"0x[0-9a-f]+\"")
-        addr = int(self.child.after.split("\"")[1], 16)
+        self.expect("\^done,value=\"0x[0-9a-f]+ \(a.out`main at main.cpp:[0-9]+\)\"")
+        addr = int(self.child.after.split("\"")[1].split(" ")[0], 16)
 
         # Test -data-disassemble: try to disassemble some address
         self.runCmd("-data-disassemble -s %#x -e %#x -- 0" % (addr, addr + 0x10))
@@ -47,8 +47,8 @@
 
         # Get an address for disassembling: use hello_world
         self.runCmd("-data-evaluate-expression hello_world")
-        self.expect("\^done,value=\"0x[0-9a-f]+\"")
-        addr = int(self.child.after.split("\"")[1], 16)
+        self.expect("\^done,value=\"0x[0-9a-f]+ \(a.out`hello_world\(\) at main.cpp:[0-9]+\)\"")
+        addr = int(self.child.after.split("\"")[1].split(" ")[0], 16)
 
         # Test -data-disassemble: try to disassemble some address
         self.runCmd("-data-disassemble -s %#x -e %#x -- 0" % (addr, addr + 0x10))
@@ -286,8 +286,8 @@
 
         # Get the address of main and its line
         self.runCmd("-data-evaluate-expression main")
-        self.expect("\^done,value=\"0x[0-9a-f]+\"")
-        addr = int(self.child.after.split("\"")[1], 16)
+        self.expect("\^done,value=\"0x[0-9a-f]+ \(a.out`main at main.cpp:[0-9]+\)\"")
+        addr = int(self.child.after.split("\"")[1].split(" ")[0], 16)
         line = line_number('main.cpp', '// FUNC_main')
 
         # Test that -data-info-line works for address
Index: source/API/SBValue.cpp
===================================================================
--- source/API/SBValue.cpp
+++ source/API/SBValue.cpp
@@ -1531,6 +1531,14 @@
 }
 
 bool
+SBValue::IsIntegerType(bool& is_signed)
+{    
+    ValueLocker locker;
+    lldb::ValueObjectSP value_sp(GetSP(locker));
+    return value_sp && value_sp->IsIntegerType(is_signed);
+}
+
+bool
 SBValue::GetDescription (SBStream &description)
 {
     Stream &strm = description.ref();
Index: include/lldb/API/SBValue.h
===================================================================
--- include/lldb/API/SBValue.h
+++ include/lldb/API/SBValue.h
@@ -368,6 +368,9 @@
     GetExpressionPath (lldb::SBStream &description, 
                        bool qualify_cxx_base_classes);
 
+    bool
+    IsIntegerType(bool& is_signed);
+
     SBValue (const lldb::ValueObjectSP &value_sp);
 
     //------------------------------------------------------------------
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to