[Lldb-commits] [lldb] r236827 - Add support for Unicode strings in CMICmnLLDBUtilSBValue::GetValue (MI)

Ilia K ki.stfu at gmail.com
Fri May 8 04:21:13 PDT 2015


Author: ki.stfu
Date: Fri May  8 06:21:13 2015
New Revision: 236827

URL: http://llvm.org/viewvc/llvm-project?rev=236827&view=rev
Log:
Add support for Unicode strings in CMICmnLLDBUtilSBValue::GetValue (MI)

This patch includes the following changes:
# Add CMIUtilString::ConvertToASCII to convert unicode to ASCII (MI)
# Rework CMICmnLLDBUtilSBValue::GetSimpleValue to print wide/unicode char (MI)
## Add CMICmnLLDBUtilSBValue::GetSimpleValueChar
## Extend CMICmnLLDBUtilSBValue::IsCharType to accept char16_t/char32_t
## Don't ignore the fail_value in SBValue::GetValueAsUnsigned
# Rework CMIUtilString::ConvertToASCII (MI)
## Don't use templates
## Change the function signature to convert signle characters (was std::basic_string)
## Rename CMIUtilString::ConvertToASCII to CMIUtilString::ConvertToPrintableASCII
# Add CMIUtilString::ConvertToPrintableASCII for char (MI)
## Refactor CMIUtilString::Escape
## Simplify CMICmnLLDBUtilSBValue::GetSimpleValueChar for char
# Add char16_t* and char32_t* support in CMICmnLLDBUtilSBValue::GetSimpleValue (MI)
## Add CMICmnLLDBUtilSBValue::GetSimpleValueCStringPointer
## Add CMICmnLLDBUtilSBValue::ReadCStringFromHostMemory2
   (it's extended version of CMICmnLLDBUtilSBValue::ReadCStringFromHostMemory)
# Improve error checking in CMICmnLLDBUtilSBValue::GetSimpleValueChar (MI)
# Refactor CMICmnLLDBUtilSBValue (MI)
## Remove CMICmnLLDBUtilSBValue::ReadCStringFromHostMemory
   (use CMICmnLLDBUtilSBValue::ReadCStringFromHostMemory2 instead)
## Rename CMICmnLLDBUtilSBValue::ReadCStringFromHostMemory2 to
   CMICmnLLDBUtilSBValue::ReadCStringFromHostMemory
## Move CMICmnLLDBUtilSBValue::GetValueCString to private methods
## Rename CMICmnLLDBUtilSBValue::GetValueCString to
   CMICmnLLDBUtilSBValue::GetSimpleValueCStringArray
## Remove CMICmnLLDBUtilSBValue::GetChildValueCString
# Improve MiGdbSetShowTestCase.test_lldbmi_gdb_set_show_print_char_array_as_string test to check char16_t/char32_t (MI)
# Fix CMICmnLLDBUtilSBValue::GetSimpleValueCStringArray for Unicode (MI)
## Fix handling of char16_t and char32_t
## Improve CMICmnLLDBUtilSBValue::ReadCStringFromHostMemory to read
   variables of type char[]: add vnMaxLen argument
## Turn on few cases to check char16_t[] and char32_t[] output in
   MiGdbSetShowTestCase.test_lldbmi_gdb_set_show_print_char_array_as_string
# Remove unnecessary checks in CMICmnLLDBUtilSBValue (MI)


Modified:
    lldb/trunk/test/tools/lldb-mi/variable/TestMiGdbSetShowPrint.py
    lldb/trunk/test/tools/lldb-mi/variable/main.cpp
    lldb/trunk/tools/lldb-mi/MICmnLLDBUtilSBValue.cpp
    lldb/trunk/tools/lldb-mi/MICmnLLDBUtilSBValue.h
    lldb/trunk/tools/lldb-mi/MIUtilString.cpp
    lldb/trunk/tools/lldb-mi/MIUtilString.h

Modified: lldb/trunk/test/tools/lldb-mi/variable/TestMiGdbSetShowPrint.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/variable/TestMiGdbSetShowPrint.py?rev=236827&r1=236826&r2=236827&view=diff
==============================================================================
--- lldb/trunk/test/tools/lldb-mi/variable/TestMiGdbSetShowPrint.py (original)
+++ lldb/trunk/test/tools/lldb-mi/variable/TestMiGdbSetShowPrint.py Fri May  8 06:21:13 2015
@@ -36,12 +36,28 @@ class MiGdbSetShowTestCase(lldbmi_testca
         self.expect("\^done,value=\"off\"")
 
         # Test that an char* is expanded to string when print char-array-as-string is "off"
-        self.runCmd("-var-create var1 * string_ptr")
-        self.expect("\^done,name=\"var1\",numchild=\"1\",value=\"0x[0-9a-f]+ \\\\\\\"string - const char \*\\\\\\\"\",type=\"const char \*\",thread-id=\"1\",has_more=\"0\"")
+        self.runCmd("-var-create - * cp")
+        self.expect("\^done,name=\"var\d+\",numchild=\"1\",value=\"0x[0-9a-f]+ \\\\\\\"hello\\\\\\\"\",type=\"const char \*\",thread-id=\"1\",has_more=\"0\"")
 
         # Test that an char[] isn't expanded to string when print char-array-as-string is "off"
-        self.runCmd("-var-create var2 * string_arr")
-        self.expect("\^done,name=\"var2\",numchild=\"17\",value=\"\[17\]\",type=\"const char \[17\]\",thread-id=\"1\",has_more=\"0\"")
+        self.runCmd("-var-create - * ca")
+        self.expect("\^done,name=\"var\d+\",numchild=\"6\",value=\"\[6\]\",type=\"const char \[6\]\",thread-id=\"1\",has_more=\"0\"")
+
+        # Test that an char16_t* is expanded to string when print char-array-as-string is "off"
+        self.runCmd("-var-create - * u16p")
+        self.expect("\^done,name=\"var\d+\",numchild=\"1\",value=\"0x[0-9a-f]+ u\\\\\\\"hello\\\\\\\"\",type=\"const char16_t \*\",thread-id=\"1\",has_more=\"0\"")
+
+        # Test that an char16_t[] isn't expanded to string when print char-array-as-string is "off"
+        self.runCmd("-var-create - * u16a")
+        self.expect("\^done,name=\"var\d+\",numchild=\"6\",value=\"\[6\]\",type=\"const char16_t \[6\]\",thread-id=\"1\",has_more=\"0\"")
+
+        # Test that an char32_t* is expanded to string when print char-array-as-string is "off"
+        self.runCmd("-var-create - * u32p")
+        self.expect("\^done,name=\"var\d+\",numchild=\"1\",value=\"0x[0-9a-f]+ U\\\\\\\"hello\\\\\\\"\",type=\"const char32_t \*\",thread-id=\"1\",has_more=\"0\"")
+
+        # Test that an char32_t[] isn't expanded to string when print char-array-as-string is "off"
+        self.runCmd("-var-create - * u32a")
+        self.expect("\^done,name=\"var\d+\",numchild=\"6\",value=\"\[6\]\",type=\"const char32_t \[6\]\",thread-id=\"1\",has_more=\"0\"")
 
         # Test that -gdb-set can set print char-array-as-string flag
         self.runCmd("-gdb-set print char-array-as-string on")
@@ -52,12 +68,28 @@ class MiGdbSetShowTestCase(lldbmi_testca
         self.expect("\^done,value=\"on\"")
 
         # Test that an char* is expanded to string when print char-array-as-string is "on"
-        self.runCmd("-var-create var1 * string_ptr")
-        self.expect("\^done,name=\"var1\",numchild=\"1\",value=\"0x[0-9a-f]+ \\\\\\\"string - const char \*\\\\\\\"\",type=\"const char \*\",thread-id=\"1\",has_more=\"0\"")
+        self.runCmd("-var-create - * cp")
+        self.expect("\^done,name=\"var\d+\",numchild=\"1\",value=\"0x[0-9a-f]+ \\\\\\\"hello\\\\\\\"\",type=\"const char \*\",thread-id=\"1\",has_more=\"0\"")
 
         # Test that an char[] isn't expanded to string when print char-array-as-string is "on"
-        self.runCmd("-var-create var2 * string_arr")
-        self.expect("\^done,name=\"var2\",numchild=\"17\",value=\"\\\\\\\"string - char \[\]\\\\\\\"\",type=\"const char \[17\]\",thread-id=\"1\",has_more=\"0\"")
+        self.runCmd("-var-create - * ca")
+        self.expect("\^done,name=\"var\d+\",numchild=\"6\",value=\"\\\\\\\"hello\\\\\\\"\",type=\"const char \[6\]\",thread-id=\"1\",has_more=\"0\"")
+
+        # Test that an char16_t* is expanded to string when print char-array-as-string is "on"
+        self.runCmd("-var-create - * u16p")
+        self.expect("\^done,name=\"var\d+\",numchild=\"1\",value=\"0x[0-9a-f]+ u\\\\\\\"hello\\\\\\\"\",type=\"const char16_t \*\",thread-id=\"1\",has_more=\"0\"")
+
+        # Test that an char16_t[] isn't expanded to string when print char-array-as-string is "on"
+        self.runCmd("-var-create - * u16a")
+        self.expect("\^done,name=\"var\d+\",numchild=\"6\",value=\"u\\\\\\\"hello\\\\\\\"\",type=\"const char16_t \[6\]\",thread-id=\"1\",has_more=\"0\"")
+
+        # Test that an char32_t* is expanded to string when print char-array-as-string is "on"
+        self.runCmd("-var-create - * u32p")
+        self.expect("\^done,name=\"var\d+\",numchild=\"1\",value=\"0x[0-9a-f]+ U\\\\\\\"hello\\\\\\\"\",type=\"const char32_t \*\",thread-id=\"1\",has_more=\"0\"")
+
+        # Test that an char32_t[] isn't expanded to string when print char-array-as-string is "on"
+        self.runCmd("-var-create - * u32a")
+        self.expect("\^done,name=\"var\d+\",numchild=\"6\",value=\"U\\\\\\\"hello\\\\\\\"\",type=\"const char32_t \[6\]\",thread-id=\"1\",has_more=\"0\"")
 
         # Test that -gdb-set print char-array-as-string fails if "on"/"off" isn't specified
         self.runCmd("-gdb-set print char-array-as-string")

Modified: lldb/trunk/test/tools/lldb-mi/variable/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/variable/main.cpp?rev=236827&r1=236826&r2=236827&view=diff
==============================================================================
--- lldb/trunk/test/tools/lldb-mi/variable/main.cpp (original)
+++ lldb/trunk/test/tools/lldb-mi/variable/main.cpp Fri May  8 06:21:13 2015
@@ -47,8 +47,12 @@ var_list_children(void)
 void
 gdb_set_show_print_char_array_as_string_test(void)
 {
-    const char *string_ptr = "string - const char *";
-    const char string_arr[] = "string - char []";
+    const char *cp = "hello";
+    const char ca[] = "hello";
+    const char16_t *u16p = u"hello";
+    const char16_t u16a[] = u"hello";
+    const char32_t *u32p = U"hello";
+    const char32_t u32a[] = U"hello";
 
     // BP_gdb_set_show_print_char_array_as_string_test
 }

Modified: lldb/trunk/tools/lldb-mi/MICmnLLDBUtilSBValue.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MICmnLLDBUtilSBValue.cpp?rev=236827&r1=236826&r2=236827&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MICmnLLDBUtilSBValue.cpp (original)
+++ lldb/trunk/tools/lldb-mi/MICmnLLDBUtilSBValue.cpp Fri May  8 06:21:13 2015
@@ -7,6 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+// Third party headers:
+#include <cinttypes>
+
 // In-house headers:
 #include "MICmnLLDBUtilSBValue.h"
 #include "MICmnLLDBDebugSessionInfo.h"
@@ -121,14 +124,12 @@ CMICmnLLDBUtilSBValue::GetSimpleValue(co
     {
         if (m_bHandleCharType && IsCharType())
         {
-            const uint8_t value = m_rValue.GetValueAsUnsigned();
-            const CMIUtilString prefix(CMIUtilString::Format("%c", value).Escape().AddSlashes());
-            vwrValue = CMIUtilString::Format("%hhu '%s'", value, prefix.c_str());
+            vwrValue = GetSimpleValueChar();
             return MIstatus::success;
         }
         else
         {
-            const MIchar *pValue = m_bValidSBValue ? m_rValue.GetValue() : nullptr;
+            const MIchar *pValue = m_rValue.GetValue();
             vwrValue = pValue != nullptr ? pValue : m_pUnkwn;
             return MIstatus::success;
         }
@@ -137,18 +138,12 @@ CMICmnLLDBUtilSBValue::GetSimpleValue(co
     {
         if (m_bHandleCharType && IsFirstChildCharType())
         {
-            const MIchar *pValue = m_bValidSBValue ? m_rValue.GetValue() : nullptr;
-            const CMIUtilString value = pValue != nullptr ? pValue : m_pUnkwn;
-            const CMIUtilString prefix(GetChildValueCString().Escape().AddSlashes());
-            // 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
-            vwrValue = CMIUtilString::Format("%s \"%s\"", value.c_str(), prefix.c_str());
+            vwrValue = GetSimpleValueCStringPointer();
             return MIstatus::success;
         }
         else
         {
-            const MIchar *pValue = m_bValidSBValue ? m_rValue.GetValue() : nullptr;
+            const MIchar *pValue = m_rValue.GetValue();
             vwrValue = pValue != nullptr ? pValue : m_pUnkwn;
             return MIstatus::success;
         }
@@ -161,10 +156,7 @@ CMICmnLLDBUtilSBValue::GetSimpleValue(co
                                                                         bPrintCharArrayAsString) && bPrintCharArrayAsString;
         if (bPrintCharArrayAsString && m_bHandleCharType && IsFirstChildCharType())
         {
-            // TODO: to match char* it should be the following
-            //       vwrValue = CMIUtilString::Format("[%u] \"%s\"", nChildren, prefix.c_str());
-            const CMIUtilString prefix(GetValueCString().Escape().AddSlashes());
-            vwrValue = CMIUtilString::Format("\"%s\"", prefix.c_str());
+            vwrValue = GetSimpleValueCStringArray();
             return MIstatus::success;
         }
         else if (vbHandleArrayType)
@@ -178,6 +170,137 @@ CMICmnLLDBUtilSBValue::GetSimpleValue(co
     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(void) const
+{
+    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(void) const
+{
+    const MIchar *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:
+        {
+            // FIXME Add slashes before double quotes
+            const CMIUtilString prefix(ReadCStringFromHostMemory<char>(child).AddSlashes());
+            // 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:
+        {
+            // FIXME Add slashes before double quotes
+            const CMIUtilString prefix(ReadCStringFromHostMemory<char16_t>(child).AddSlashes());
+            return CMIUtilString::Format("%s u\"%s\"", value, prefix.c_str());
+        }
+        case lldb::eBasicTypeChar32:
+        {
+            // FIXME Add slashes before double quotes
+            const CMIUtilString prefix(ReadCStringFromHostMemory<char32_t>(child).AddSlashes());
+            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(void) const
+{
+    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:
+        {
+            // FIXME Add slashes before double quotes
+            const CMIUtilString prefix(ReadCStringFromHostMemory<char>(m_rValue, nChildren).AddSlashes());
+            // 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:
+        {
+            // FIXME Add slashes before double quotes
+            const CMIUtilString prefix(ReadCStringFromHostMemory<char16_t>(m_rValue, nChildren).AddSlashes());
+            return CMIUtilString::Format("u\"%s\"", prefix.c_str());
+        }
+        case lldb::eBasicTypeChar32:
+        {
+            // FIXME Add slashes before double quotes
+            const CMIUtilString prefix(ReadCStringFromHostMemory<char32_t>(m_rValue, nChildren).AddSlashes());
+            return CMIUtilString::Format("U\"%s\"", prefix.c_str());
+        }
+    }
+}
+
 bool
 CMICmnLLDBUtilSBValue::GetCompositeValue(const bool vbPrintFieldNames, CMICmnMIValueTuple &vwrMiValueTuple,
                                          const MIuint vnDepth /* = 1 */) const
@@ -235,28 +358,6 @@ CMICmnLLDBUtilSBValue::GetCompositeValue
 }
 
 //++ ------------------------------------------------------------------------------------
-// Details: If the LLDB SB Value object is a char or char[] type then form the text data
-//          string otherwise return nothing. m_bHandleCharType must be true to return
-//          text data if any.
-// Type:    Method.
-// Args:    None.
-// Return:  CMIUtilString   - Text description of the variable's value.
-// Throws:  None.
-//--
-CMIUtilString
-CMICmnLLDBUtilSBValue::GetValueCString(void) const
-{
-    CMIUtilString text;
-
-    if (m_bHandleCharType && (IsCharType() || (IsArrayType() && IsFirstChildCharType())))
-    {
-        text = ReadCStringFromHostMemory(m_rValue);
-    }
-
-    return text;
-}
-
-//++ ------------------------------------------------------------------------------------
 // Details: Retrieve the flag stating whether this value object is a char type or some
 //          other type. Char type can be signed or unsigned.
 // Type:    Method.
@@ -268,7 +369,17 @@ bool
 CMICmnLLDBUtilSBValue::IsCharType(void) const
 {
     const lldb::BasicType eType = m_rValue.GetType().GetBasicType();
-    return ((eType == lldb::eBasicTypeChar) || (eType == lldb::eBasicTypeSignedChar) || (eType == lldb::eBasicTypeUnsignedChar));
+    switch (eType)
+    {
+        case lldb::eBasicTypeChar:
+        case lldb::eBasicTypeSignedChar:
+        case lldb::eBasicTypeUnsignedChar:
+        case lldb::eBasicTypeChar16:
+        case lldb::eBasicTypeChar32:
+            return true;
+        default:
+            return false;
+    }
 }
 
 //++ ------------------------------------------------------------------------------------
@@ -342,61 +453,34 @@ CMICmnLLDBUtilSBValue::IsArrayType(void)
 }
 
 //++ ------------------------------------------------------------------------------------
-// Details: Retrieve the C string data for a child of char type (one and only child) for
-//          the parent value object. If the child is not a char type or the parent has
-//          more than one child then an empty string is returned. Char type can be
-//          signed or unsigned.
-// Type:    Method.
-// Args:    None.
-// Return:  CMIUtilString   - Text description of the variable's value.
-// Throws:  None.
-//--
-CMIUtilString
-CMICmnLLDBUtilSBValue::GetChildValueCString(void) const
-{
-    CMIUtilString text;
-    const MIuint nChildren = m_rValue.GetNumChildren();
-
-    // Is it a basic type
-    if (nChildren == 0)
-        return text;
-
-    // Is it a composite type
-    if (nChildren > 1)
-        return text;
-
-    lldb::SBValue member = m_rValue.GetChildAtIndex(0);
-    const CMICmnLLDBUtilSBValue utilValue(member);
-    if (m_bHandleCharType && utilValue.IsCharType())
-    {
-        text = ReadCStringFromHostMemory(member);
-    }
-
-    return text;
-}
-
-//++ ------------------------------------------------------------------------------------
 // Details: Retrieve the C string data of value object by read the memory where the
 //          variable is held.
 // Type:    Method.
-// Args:    vrValueObj  - (R) LLDB SBValue variable object.
+// Args:    vrValue         - (R) LLDB SBValue variable object.
 // Return:  CMIUtilString   - Text description of the variable's value.
 // Throws:  None.
 //--
+template <typename charT>
 CMIUtilString
-CMICmnLLDBUtilSBValue::ReadCStringFromHostMemory(const lldb::SBValue &vrValueObj) const
+CMICmnLLDBUtilSBValue::ReadCStringFromHostMemory(lldb::SBValue &vrValue, const MIuint vnMaxLen) const
 {
-    CMIUtilString text;
-
-    lldb::SBValue &rValue = const_cast<lldb::SBValue &>(vrValueObj);
-    const lldb::addr_t addr = rValue.GetLoadAddress();
-    CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
-    const MIuint nBytes(128);
-    std::unique_ptr<char[]> apBufferMemory(new char[nBytes]);
+    std::string result;
+    lldb::addr_t addr = vrValue.GetLoadAddress(), end_addr = addr + vnMaxLen * sizeof(charT);
+    lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance().GetProcess();
     lldb::SBError error;
-    const MIuint64 nReadBytes = rSessionInfo.GetProcess().ReadMemory(addr, apBufferMemory.get(), nBytes, error);
-    MIunused(nReadBytes);
-    return CMIUtilString(apBufferMemory.get());
+    while (addr < end_addr)
+    {
+        charT ch;
+        const MIuint64 nReadBytes = process.ReadMemory(addr, &ch, sizeof(ch), error);
+        if (error.Fail() || nReadBytes != sizeof(ch))
+            return m_pUnkwn;
+        else if (ch == 0)
+            break;
+        result.append(CMIUtilString::ConvertToPrintableASCII(ch));
+        addr += sizeof(ch);
+    }
+
+    return result.c_str();
 }
 
 //++ ------------------------------------------------------------------------------------

Modified: lldb/trunk/tools/lldb-mi/MICmnLLDBUtilSBValue.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MICmnLLDBUtilSBValue.h?rev=236827&r1=236826&r2=236827&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MICmnLLDBUtilSBValue.h (original)
+++ lldb/trunk/tools/lldb-mi/MICmnLLDBUtilSBValue.h Fri May  8 06:21:13 2015
@@ -36,8 +36,6 @@ class CMICmnLLDBUtilSBValue
     //
     CMIUtilString GetName(void) const;
     CMIUtilString GetValue(const bool vbExpandAggregates = false) const;
-    CMIUtilString GetValueCString(void) const;
-    CMIUtilString GetChildValueCString(void) const;
     CMIUtilString GetTypeName(void) const;
     CMIUtilString GetTypeNameDisplay(void) const;
     bool IsCharType(void) const;
@@ -53,8 +51,11 @@ class CMICmnLLDBUtilSBValue
 
     // Methods:
   private:
-    CMIUtilString ReadCStringFromHostMemory(const lldb::SBValue &vrValueObj) const;
+    template <typename charT> CMIUtilString ReadCStringFromHostMemory(lldb::SBValue &vrValue, const MIuint vnMaxLen = UINT32_MAX) const;
     bool GetSimpleValue(const bool vbHandleArrayType, CMIUtilString &vrValue) const;
+    CMIUtilString GetSimpleValueChar(void) const;
+    CMIUtilString GetSimpleValueCStringPointer(void) const;
+    CMIUtilString GetSimpleValueCStringArray(void) const;
     bool GetCompositeValue(const bool vbPrintFieldNames, CMICmnMIValueTuple &vwrMiValueTuple, const MIuint vnDepth = 1) const;
 
     // Attributes:

Modified: lldb/trunk/tools/lldb-mi/MIUtilString.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MIUtilString.cpp?rev=236827&r1=236826&r2=236827&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MIUtilString.cpp (original)
+++ lldb/trunk/tools/lldb-mi/MIUtilString.cpp Fri May  8 06:21:13 2015
@@ -17,7 +17,6 @@
 
 // In-house headers:
 #include "MIUtilString.h"
-#include "Platform.h"
 
 //++ ------------------------------------------------------------------------------------
 // Details: CMIUtilString constructor.
@@ -804,54 +803,10 @@ CMIUtilString::Escape(const bool vbEscap
     for (MIuint nIndex(0); nIndex < nLen; ++nIndex)
     {
         const MIchar cUnescapedChar((*this)[nIndex]);
-        switch (cUnescapedChar)
-        {
-            case '\a':
-                strNew.append("\\a");
-                break;
-            case '\b':
-                strNew.append("\\b");
-                break;
-            case '\t':
-                strNew.append("\\t");
-                break;
-            case '\n':
-                strNew.append("\\n");
-                break;
-            case '\v':
-                strNew.append("\\v");
-                break;
-            case '\f':
-                strNew.append("\\f");
-                break;
-            case '\r':
-                strNew.append("\\r");
-                break;
-            case '\033':
-                strNew.append("\\e");
-                break;
-            case '\\':
-                strNew.append("\\\\");
-                break;
-            case '\"':
-                if (vbEscapeQuotes)
-                {
-                    strNew.append("\\\"");
-                    break;
-                }
-                // FALLTHROUGH
-            default:
-                if (::isprint(cUnescapedChar))
-                    strNew.push_back(cUnescapedChar);
-                else
-                {
-                    const size_t size = sizeof("\\xXX");
-                    char strEscapedChar[size];
-                    ::snprintf(strEscapedChar, size, "\\x%02" PRIx8, cUnescapedChar);
-                    strNew.append(strEscapedChar);
-                }
-                break;
-        }
+        if (cUnescapedChar == '"' && vbEscapeQuotes)
+            strNew.append("\\\"");
+        else
+            strNew.append(ConvertToPrintableASCII((char)cUnescapedChar));
     }
     return strNew;
 }
@@ -939,3 +894,57 @@ CMIUtilString::StripSlashes(void) const
 
     return strNew;
 }
+
+CMIUtilString
+CMIUtilString::ConvertToPrintableASCII(const char vChar)
+{
+    switch (vChar)
+    {
+        case '\a':
+            return "\\a";
+        case '\b':
+            return "\\b";
+        case '\t':
+            return "\\t";
+        case '\n':
+            return "\\n";
+        case '\v':
+            return "\\v";
+        case '\f':
+            return "\\f";
+        case '\r':
+            return "\\r";
+        case '\033':
+            return "\\e";
+        case '\\':
+            return "\\\\";
+        default:
+            if (::isprint(vChar))
+                return Format("%c", vChar);
+            else
+                return Format("\\x%02" PRIx8, vChar);
+    }
+}
+
+CMIUtilString
+CMIUtilString::ConvertToPrintableASCII(const char16_t vChar16)
+{
+    if (vChar16 == (char16_t)(char)vChar16 && ::isprint(vChar16))
+        // Convert char16_t to char (if possible)
+        return Format("%c", vChar16);
+    else
+        return Format("\\u%02" PRIx8 "%02" PRIx8,
+                      (vChar16 >> 8) & 0xff, vChar16 & 0xff);
+}
+
+CMIUtilString
+CMIUtilString::ConvertToPrintableASCII(const char32_t vChar32)
+{
+    if (vChar32 == (char32_t)(char)vChar32 && ::isprint(vChar32))
+        // Convert char32_t to char (if possible)
+        return Format("%c", vChar32);
+    else
+        return Format("\\U%02" PRIx8 "%02" PRIx8 "%02" PRIx8 "%02" PRIx8,
+                      (vChar32 >> 24) & 0xff, (vChar32 >> 16) & 0xff,
+                      (vChar32 >> 8) & 0xff, vChar32 & 0xff);
+}

Modified: lldb/trunk/tools/lldb-mi/MIUtilString.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MIUtilString.h?rev=236827&r1=236826&r2=236827&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MIUtilString.h (original)
+++ lldb/trunk/tools/lldb-mi/MIUtilString.h Fri May  8 06:21:13 2015
@@ -12,6 +12,7 @@
 // Third party headers:
 #include <string>
 #include <vector>
+#include <cinttypes>
 
 // In-house headers:
 #include "MIDataTypes.h"
@@ -36,6 +37,9 @@ class CMIUtilString : public std::string
     static CMIUtilString FormatValist(const CMIUtilString &vrFormating, va_list vArgs);
     static bool IsAllValidAlphaAndNumeric(const MIchar &vrText);
     static bool Compare(const CMIUtilString &vrLhs, const CMIUtilString &vrRhs);
+    static CMIUtilString ConvertToPrintableASCII(const char vChar);
+    static CMIUtilString ConvertToPrintableASCII(const char16_t vChar16);
+    static CMIUtilString ConvertToPrintableASCII(const char32_t vChar32);
 
     // Methods:
   public:





More information about the lldb-commits mailing list