Index: lldb/trunk/include/lldb/DataFormatters/FormattersHelpers.h =================================================================== --- lldb/trunk/include/lldb/DataFormatters/FormattersHelpers.h +++ lldb/trunk/include/lldb/DataFormatters/FormattersHelpers.h @@ -106,6 +106,9 @@ size_t ExtractIndexFromString (const char* item_name); + lldb::addr_t + GetArrayAddressOrPointerValue (ValueObject& valobj); + time_t GetOSXEpoch (); } // namespace formatters Index: lldb/trunk/source/DataFormatters/FormattersHelpers.cpp =================================================================== --- lldb/trunk/source/DataFormatters/FormattersHelpers.cpp +++ lldb/trunk/source/DataFormatters/FormattersHelpers.cpp @@ -306,3 +306,16 @@ return UINT32_MAX; return idx; } + +lldb::addr_t +lldb_private::formatters::GetArrayAddressOrPointerValue (ValueObject& valobj) +{ + lldb::addr_t data_addr = LLDB_INVALID_ADDRESS; + + if (valobj.IsPointerType()) + data_addr = valobj.GetValueAsUnsigned(0); + else if (valobj.IsArrayType()) + data_addr = valobj.GetAddressOf(); + + return data_addr; +} Index: lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp =================================================================== --- lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -628,8 +628,20 @@ #ifndef LLDB_DISABLE_PYTHON // FIXME because of a bug in the FormattersContainer we need to add a summary for both X* and const X* () AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider, "char16_t * summary provider", ConstString("char16_t *"), string_flags); + AddCXXSummary(cpp_category_sp, + lldb_private::formatters::Char16StringSummaryProvider, + "char16_t [] summary provider", + ConstString("char16_t \\[[0-9]+\\]"), + string_array_flags, + true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char32StringSummaryProvider, "char32_t * summary provider", ConstString("char32_t *"), string_flags); + AddCXXSummary(cpp_category_sp, + lldb_private::formatters::Char32StringSummaryProvider, + "char32_t [] summary provider", + ConstString("char32_t \\[[0-9]+\\]"), + string_array_flags, + true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::WCharStringSummaryProvider, "wchar_t * summary provider", ConstString("wchar_t *"), string_flags); AddCXXSummary(cpp_category_sp, lldb_private::formatters::WCharStringSummaryProvider, "wchar_t * summary provider", ConstString("wchar_t \\[[0-9]+\\]"), string_array_flags, true); Index: lldb/trunk/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp =================================================================== --- lldb/trunk/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp +++ lldb/trunk/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp @@ -24,6 +24,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/ProcessStructReader.h" +#include "lldb/DataFormatters/FormattersHelpers.h" #include @@ -44,9 +45,8 @@ if (!process_sp) return false; - lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0); - - if (!valobj_addr) + lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj); + if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS) return false; StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); @@ -71,9 +71,8 @@ if (!process_sp) return false; - lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0); - - if (!valobj_addr) + lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj); + if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS) return false; StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); @@ -98,14 +97,8 @@ if (!process_sp) return false; - lldb::addr_t data_addr = 0; - - if (valobj.IsPointerType()) - data_addr = valobj.GetValueAsUnsigned(0); - else if (valobj.IsArrayType()) - data_addr = valobj.GetAddressOf(); - - if (data_addr == 0 || data_addr == LLDB_INVALID_ADDRESS) + lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj); + if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS) return false; // Get a wchar_t basic type from the current type system @@ -117,7 +110,7 @@ const uint32_t wchar_size = wchar_compiler_type.GetBitSize(nullptr); // Safe to pass NULL for exe_scope here StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); - options.SetLocation(data_addr); + options.SetLocation(valobj_addr); options.SetProcessSP(process_sp); options.SetStream(&stream); options.SetPrefixToken('L'); Index: lldb/trunk/test/lang/cpp/char1632_t/TestChar1632T.py =================================================================== --- lldb/trunk/test/lang/cpp/char1632_t/TestChar1632T.py +++ lldb/trunk/test/lang/cpp/char1632_t/TestChar1632T.py @@ -64,6 +64,11 @@ self.expect("frame variable s16 s32", substrs = ['(char16_t *) s16 = ','(char32_t *) s32 = ','u"ﺸﺵۻ"','U"ЕЙРГЖО"']) + # Check that we correctly report the array types + self.expect("frame variable as16 as32", + patterns = ['\(char16_t \[[0-9]+\]\) as16 = ', '\(char32_t \[[0-9]+\]\) as32 = '], + substrs = ['u"ﺸﺵۻ"','U"ЕЙРГЖО"']) + self.runCmd("next") # step to after the string is nullified # check that we don't crash on NULL @@ -77,6 +82,11 @@ self.expect("frame variable s16 s32", substrs = ['(char16_t *) s16 = 0x','(char32_t *) s32 = ','"色ハ匂ヘト散リヌルヲ"','"෴"']) + # check the same as above for arrays + self.expect("frame variable as16 as32", + patterns = ['\(char16_t \[[0-9]+\]\) as16 = ', '\(char32_t \[[0-9]+\]\) as32 = '], + substrs = ['"色ハ匂ヘト散リヌルヲ"','"෴"']) + # check that zero values are properly handles self.expect('frame variable cs16_zero', substrs=["U+0000 u'\\0'"]) self.expect('frame variable cs32_zero', substrs=["U+0x00000000 U'\\0'"]) Index: lldb/trunk/test/lang/cpp/char1632_t/main.cpp =================================================================== --- lldb/trunk/test/lang/cpp/char1632_t/main.cpp +++ lldb/trunk/test/lang/cpp/char1632_t/main.cpp @@ -7,18 +7,38 @@ // //===----------------------------------------------------------------------===// +#include +#include + +#define UASZ 64 + +template +void copy_char_seq (T (&arr)[N], const T* src) +{ + size_t src_len = std::char_traits::length(src); + assert(src_len < N); + + std::char_traits::copy(arr, src, src_len); + arr[src_len] = 0; +} int main (int argc, char const *argv[]) { - auto cs16_zero = (char16_t)0; - auto cs32_zero = (char32_t)0; + char16_t as16[UASZ]; + char32_t as32[UASZ]; + auto cs16_zero = (char16_t)0; + auto cs32_zero = (char32_t)0; auto cs16 = u"hello world ྒྙྐ"; - auto cs32 = U"hello world ྒྙྐ"; + auto cs32 = U"hello world ྒྙྐ"; char16_t *s16 = (char16_t *)u"ﺸﺵۻ"; char32_t *s32 = (char32_t *)U"ЕЙРГЖО"; + copy_char_seq(as16, s16); + copy_char_seq(as32, s32); s32 = nullptr; // breakpoint1 s32 = (char32_t *)U"෴"; s16 = (char16_t *)u"色ハ匂ヘト散リヌルヲ"; + copy_char_seq(as16, s16); + copy_char_seq(as32, s32); s32 = nullptr; // breakpoint2 return 0; }