<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Hi Daniel.<div>Thanks for catching this issue.</div><div><br></div><div>The idea of writing this as a template argument was in fact that I knew at compile time which function to pick for the data conversion process, and so I was hoping to let the compiler optimize as an effect of this advance knowledge. However, if this causes issues I am happy to reconsider the original design.</div><div><br></div><div>I'd rather not go the route of two functions for now, since most of the code will be common anyway. I guess a function pointer is the most sensible approach here, especially since I do not have a GCC 4.6 or later available for testing other ideas.</div><div><br></div><div>With that said, I am currently making more changes to that very same region of code, so I will commit the new implementation by the end of today along with other modifications. Hope that works for you.</div><div><br><div>
<div><div style="border-collapse: separate; border-spacing: 0px; "><i>Enrico Granata</i></div><div style="border-collapse: separate; border-spacing: 0px; ">✉ egranata@<font class="Apple-style-span" color="#ff230e"></font>.com</div><div>✆ (408) 972-7683</div></div>
</div>
<br><div><div>On Jan 14, 2013, at 1:53 PM, "Malea, Daniel" <<a href="mailto:daniel.malea@intel.com">daniel.malea@intel.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">Hi Enrico,<br><br>This commit introduces a build problem with GCC 4.6 and a few warnings with clang. I believe the error is related to passing ConvertFunction as a template parameter as its arguments are dependent on the first template parameter to ReadUTFBufferAndDumpToStream. I'm no c++11 expert, but the usage seems very similar to template aliases, which are available only on later versions of GCC -- so that might be the reason for the failure.<br><br>In any case, I'm not really sure I understand the motivation of making ConvertFunction a template parameter though -- if the intention was to "bake in" the ConvertFunction pointer and have the compiler eliminate the unreachable portions of ReadUTFBufferAndDumpToStream, I don't think that is happening even with clang 3.2, as I'm seeing the following warning for the code in question:<br><br>CXXFormatterFunctions.cpp:159:34: warning: address of function 'ConvertUTF16toUTF8' will always evaluate to 'true' [-Wbool-conversion]<br><br>The patch attached fixes the build (and the warnings) by changing ConvertFunction to be a plain old function parameter, but I wanted to post it here for review in case there's a better approach! If the intention was in fact to bake in the function pointer and thereby optimize out the 'dead' branches of the function, I think writing two functions would be a better approach.<br><br><br>For reference, the GCC (4.6) error/warning messages are:<br><br>CXXFormatterFunctions.cpp:322:68: error: no matching function for call to ‘ReadUTFBufferAndDumpToStream(lldb::addr_t&, lldb::ProcessSP&, lldb_private::Stream&, char, bool)’<br>CXXFormatterFunctions.cpp:322:68: note: candidate is:<br>CXXFormatterFunctions.cpp:144:1: note: template<class SourceDataType, ConversionResult (* ConvertFunction)(const SourceDataType**, const SourceDataType*, UTF8**, UTF8*, ConversionFlags)> bool ReadUTFBufferAndDumpToStream(uint64_t, const ProcessSP&, lldb_private::Stream&, char, bool)<br>CXXFormatterFunctions.cpp: In function ‘bool lldb_private::formatters::NSNumberSummaryProvider(lldb_private::ValueObject&, lldb_private::Stream&)’:<br>CXXFormatterFunctions.cpp:656:59: warning: ISO C++ does not support the ‘hh’ gnu_printf length modifier [-Wformat]<br>CXXFormatterFunctions.cpp:687:59: warning: ISO C++ does not support the ‘hh’ gnu_printf length modifier [-Wformat]<br>llvm[4]: Compiling Disassembler.cpp for Debug+Asserts build<br>CXXFormatterFunctions.cpp: In function ‘bool ReadUTFBufferAndDumpToStream(uint64_t, const ProcessSP&, lldb_private::Stream&, char, bool) [with SourceDataType = short unsigned int, ConversionResult (* ConvertFunction)(const SourceDataType**, const SourceDataType*, UTF8**, UTF8*, ConversionFlags) = ConvertUTF16toUTF8, uint64_t = long unsigned int, lldb::ProcessSP = std::tr1::shared_ptr<lldb_private::Process>]’:<br>CXXFormatterFunctions.cpp:256:70:   instantiated from here<br>CXXFormatterFunctions.cpp:159:5: warning: the address of ‘ConversionResult ConvertUTF16toUTF8(const UTF16**, const UTF16*, UTF8**, UTF8*, ConversionFlags)’ will always evaluate as ‘true’ [-Waddress]<br>CXXFormatterFunctions.cpp:256:70:   instantiated from here<br>CXXFormatterFunctions.cpp:206:9: warning: the address of ‘ConversionResult ConvertUTF16toUTF8(const UTF16**, const UTF16*, UTF8**, UTF8*, ConversionFlags)’ will always evaluate as ‘true’ [-Waddress]<br>CXXFormatterFunctions.cpp:256:70:   instantiated from here<br>CXXFormatterFunctions.cpp:211:13: warning: cast from type ‘short unsigned int**’ to type ‘const short unsigned int**’ casts away qualifiers [-Wcast-qual]<br>CXXFormatterFunctions.cpp: In function ‘bool ReadUTFBufferAndDumpToStream(uint64_t, const ProcessSP&, lldb_private::Stream&, char, bool) [with SourceDataType = unsigned int, ConversionResult (* ConvertFunction)(const SourceDataType**, const SourceDataType*, UTF8**, UTF8*, ConversionFlags) = ConvertUTF32toUTF8, uint64_t = long unsigned int, lldb::ProcessSP = std::tr1::shared_ptr<lldb_private::Process>]’:<br>CXXFormatterFunctions.cpp:281:70:   instantiated from here<br>CXXFormatterFunctions.cpp:159:5: warning: the address of ‘ConversionResult ConvertUTF32toUTF8(const UTF32**, const UTF32*, UTF8**, UTF8*, ConversionFlags)’ will always evaluate as ‘true’ [-Waddress]<br>CXXFormatterFunctions.cpp:206:9: warning: the address of ‘ConversionResult ConvertUTF32toUTF8(const UTF32**, const UTF32*, UTF8**, UTF8*, ConversionFlags)’ will always evaluate as ‘true’ [-Waddress]<br>CXXFormatterFunctions.cpp:211:13: warning: cast from type ‘unsigned int**’ to type ‘const unsigned int**’ casts away qualifiers [-Wcast-qual]<br><br><br><br><br>On 2013-01-11, at 8:00 PM, Enrico Granata wrote:<br><br>Author: enrico<br>Date: Fri Jan 11 19:00:22 2013<br>New Revision: 172282<br><br>URL: <a href="http://llvm.org/viewvc/llvm-project?rev=172282&view=rev">http://llvm.org/viewvc/llvm-project?rev=172282&view=rev</a><br>Log:<br><<a href="rdar://problem/12239827">rdar://problem/12239827</a>><br><br>Providing a data formatter for libc++ std::wstring<br>In the process, refactoring the std::string data formatter to be written in C++ so that commonalities between the two can be exploited<br>Also, providing a new API on the ValueObject to navigate a hierarchy by index-path<br>Lastly, an appropriate test case is included<br><br><br>Added:<br>   lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/<br>   lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/Makefile<br>   lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py<br>   lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/main.cpp<br>Modified:<br>   lldb/trunk/include/lldb/Core/CXXFormatterFunctions.h<br>   lldb/trunk/include/lldb/Core/ValueObject.h<br>   lldb/trunk/source/Core/CXXFormatterFunctions.cpp<br>   lldb/trunk/source/Core/FormatManager.cpp<br>   lldb/trunk/source/Core/ValueObject.cpp<br><br>Modified: lldb/trunk/include/lldb/Core/CXXFormatterFunctions.h<br>URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/CXXFormatterFunctions.h?rev=172282&r1=172281&r2=172282&view=diff">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/CXXFormatterFunctions.h?rev=172282&r1=172281&r2=172282&view=diff</a><br>==============================================================================<br>--- lldb/trunk/include/lldb/Core/CXXFormatterFunctions.h (original)<br>+++ lldb/trunk/include/lldb/Core/CXXFormatterFunctions.h Fri Jan 11 19:00:22 2013<br>@@ -49,6 +49,12 @@<br>        bool<br>        WCharStringSummaryProvider (ValueObject& valobj, Stream& stream); // wchar_t*<br><br>+        bool<br>+        LibcxxStringSummaryProvider (ValueObject& valobj, Stream& stream); // libc++ std::string<br>+<br>+        bool<br>+        LibcxxWStringSummaryProvider (ValueObject& valobj, Stream& stream); // libc++ std::wstring<br>+<br>        template<bool name_entries><br>        bool<br>        NSDictionarySummaryProvider (ValueObject& valobj, Stream& stream);<br><br>Modified: lldb/trunk/include/lldb/Core/ValueObject.h<br>URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=172282&r1=172281&r2=172282&view=diff">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=172282&r1=172281&r2=172282&view=diff</a><br>==============================================================================<br>--- lldb/trunk/include/lldb/Core/ValueObject.h (original)<br>+++ lldb/trunk/include/lldb/Core/ValueObject.h Fri Jan 11 19:00:22 2013<br>@@ -734,6 +734,23 @@<br>    virtual lldb::ValueObjectSP<br>    GetChildAtIndex (uint32_t idx, bool can_create);<br><br>+    // this will always create the children if necessary<br>+    lldb::ValueObjectSP<br>+    GetChildAtIndexPath (const std::initializer_list<uint32_t> &idxs,<br>+                         uint32_t* index_of_error = NULL);<br>+<br>+    lldb::ValueObjectSP<br>+    GetChildAtIndexPath (const std::vector<uint32_t> &idxs,<br>+                         uint32_t* index_of_error = NULL);<br>+<br>+    lldb::ValueObjectSP<br>+    GetChildAtIndexPath (const std::initializer_list< std::pair<uint32_t, bool> > &idxs,<br>+                         uint32_t* index_of_error = NULL);<br>+<br>+    lldb::ValueObjectSP<br>+    GetChildAtIndexPath (const std::vector< std::pair<uint32_t, bool> > &idxs,<br>+                         uint32_t* index_of_error = NULL);<br>+<br>    virtual lldb::ValueObjectSP<br>    GetChildMemberWithName (const ConstString &name, bool can_create);<br><br><br>Modified: lldb/trunk/source/Core/CXXFormatterFunctions.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/CXXFormatterFunctions.cpp?rev=172282&r1=172281&r2=172282&view=diff">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/CXXFormatterFunctions.cpp?rev=172282&r1=172281&r2=172282&view=diff</a><br>==============================================================================<br>--- lldb/trunk/source/Core/CXXFormatterFunctions.cpp (original)<br>+++ lldb/trunk/source/Core/CXXFormatterFunctions.cpp Fri Jan 11 19:00:22 2013<br>@@ -158,8 +158,9 @@<br>    // if not UTF8, I need a conversion function to return proper UTF8<br>    if (origin_encoding != 8 && !ConvertFunction)<br>        return false;<br>-    const int bufferSPSize = 1024;<br>-    const int sourceSize = (bufferSPSize / (origin_encoding >> 2));<br>+<br>+    const int sourceSize = process_sp->GetTarget().GetMaximumSizeOfStringSummary();<br>+    const int bufferSPSize = sourceSize * (origin_encoding >> 2);<br><br>    Error error;<br>    lldb::DataBufferSP buffer_sp(new DataBufferHeap(bufferSPSize,0));<br>@@ -218,6 +219,9 @@<br>            utf8_data_end_ptr = (UTF8*)data_end_ptr;<br>        }<br><br>+        // since we tend to accept partial data (and even partially malformed data)<br>+        // we might end up with no NULL terminator before the end_ptr<br>+        // hence we need to take a slower route and ensure we stay within boundaries<br>        for (;utf8_data_ptr != utf8_data_end_ptr; utf8_data_ptr++)<br>        {<br>            if (!*utf8_data_ptr)<br>@@ -290,9 +294,14 @@<br>    if (!process_sp)<br>        return false;<br><br>-    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);<br>+    lldb::addr_t data_addr = 0;<br>+<br>+    if (valobj.IsPointerType())<br>+        data_addr = valobj.GetValueAsUnsigned(0);<br>+    else if (valobj.IsArrayType())<br>+        data_addr = valobj.GetAddressOf();<br><br>-    if (!valobj_addr)<br>+    if (data_addr == 0 || data_addr == LLDB_INVALID_ADDRESS)<br>        return false;<br><br>    clang::ASTContext* ast = valobj.GetClangAST();<br>@@ -306,21 +315,21 @@<br>    {<br>        case 8:<br>            // utf 8<br>-            return ReadUTFBufferAndDumpToStream<UTF8, nullptr>(valobj_addr,<br>+            return ReadUTFBufferAndDumpToStream<UTF8, nullptr>(data_addr,<br>                                                               process_sp,<br>                                                               stream,<br>                                                               'L',<br>                                                               true); // but use quotes<br>        case 16:<br>            // utf 16<br>-            return ReadUTFBufferAndDumpToStream<UTF16, ConvertUTF16toUTF8>(valobj_addr,<br>+            return ReadUTFBufferAndDumpToStream<UTF16, ConvertUTF16toUTF8>(data_addr,<br>                                                                           process_sp,<br>                                                                           stream,<br>                                                                           'L',<br>                                                                           true); // but use quotes<br>        case 32:<br>            // utf 32<br>-            return ReadUTFBufferAndDumpToStream<UTF32, ConvertUTF32toUTF8>(valobj_addr,<br>+            return ReadUTFBufferAndDumpToStream<UTF32, ConvertUTF32toUTF8>(data_addr,<br>                                                                           process_sp,<br>                                                                           stream,<br>                                                                           'L',<br>@@ -332,6 +341,86 @@<br>    return true;<br>}<br><br>+// this function extracts information from a libcxx std::basic_string<><br>+// irregardless of template arguments. it reports the size (in item count not bytes)<br>+// and the location in memory where the string data can be found<br>+static bool<br>+ExtractLibcxxStringInfo (ValueObject& valobj,<br>+                         ValueObjectSP &location_sp,<br>+                         uint64_t& size)<br>+{<br>+    ValueObjectSP D(valobj.GetChildAtIndexPath({0,0,0,0}));<br>+    if (!D)<br>+        return false;<br>+<br>+    ValueObjectSP size_mode(D->GetChildAtIndexPath({1,0,0}));<br>+    if (!size_mode)<br>+        return false;<br>+<br>+    uint64_t size_mode_value(size_mode->GetValueAsUnsigned(0));<br>+<br>+    if ((size_mode_value & 1) == 0) // this means the string is in short-mode and the data is stored inline<br>+    {<br>+        ValueObjectSP s(D->GetChildAtIndex(1, true));<br>+        if (!s)<br>+            return false;<br>+        size = ((size_mode_value >> 1) % 256);<br>+        location_sp = s->GetChildAtIndex(1, true);<br>+        return (location_sp.get() != nullptr);<br>+    }<br>+    else<br>+    {<br>+        ValueObjectSP l(D->GetChildAtIndex(0, true));<br>+        if (!l)<br>+            return false;<br>+        location_sp = l->GetChildAtIndex(2, true);<br>+        ValueObjectSP size_vo(l->GetChildAtIndex(1, true));<br>+        if (!size_vo || !location_sp)<br>+            return false;<br>+        size = size_vo->GetValueAsUnsigned(0);<br>+        return true;<br>+    }<br>+}<br>+<br>+bool<br>+lldb_private::formatters::LibcxxWStringSummaryProvider (ValueObject& valobj, Stream& stream)<br>+{<br>+    uint64_t size = 0;<br>+    ValueObjectSP location_sp((ValueObject*)nullptr);<br>+    if (!ExtractLibcxxStringInfo(valobj, location_sp, size))<br>+        return false;<br>+    if (size == 0)<br>+    {<br>+        stream.Printf("L\"\"");<br>+        return true;<br>+    }<br>+    if (!location_sp)<br>+        return false;<br>+    return WCharStringSummaryProvider(*location_sp.get(), stream);<br>+}<br>+<br>+bool<br>+lldb_private::formatters::LibcxxStringSummaryProvider (ValueObject& valobj, Stream& stream)<br>+{<br>+    uint64_t size = 0;<br>+    ValueObjectSP location_sp((ValueObject*)nullptr);<br>+    if (!ExtractLibcxxStringInfo(valobj, location_sp, size))<br>+        return false;<br>+    if (size == 0)<br>+    {<br>+        stream.Printf("\"\"");<br>+        return true;<br>+    }<br>+    if (!location_sp)<br>+        return false;<br>+    Error error;<br>+    location_sp->ReadPointedString(stream,<br>+                                   error,<br>+                                   0, // max length is decided by the settings<br>+                                   false); // do not honor array (terminates on first 0 byte even for a char[])<br>+    return error.Success();<br>+}<br>+<br>template<bool name_entries><br>bool<br>lldb_private::formatters::NSDictionarySummaryProvider (ValueObject& valobj, Stream& stream)<br><br>Modified: lldb/trunk/source/Core/FormatManager.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FormatManager.cpp?rev=172282&r1=172281&r2=172282&view=diff">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FormatManager.cpp?rev=172282&r1=172281&r2=172282&view=diff</a><br>==============================================================================<br>--- lldb/trunk/source/Core/FormatManager.cpp (original)<br>+++ lldb/trunk/source/Core/FormatManager.cpp Fri Jan 11 19:00:22 2013<br>@@ -844,9 +844,12 @@<br>    .SetHideItemNames(false);<br><br>#ifndef LLDB_DISABLE_PYTHON<br>-    std::string code("     lldb.formatters.cpp.libcxx.stdstring_SummaryProvider(valobj,internal_dict)");<br>-    lldb::TypeSummaryImplSP std_string_summary_sp(new ScriptSummaryFormat(stl_summary_flags, "lldb.formatters.cpp.libcxx.stdstring_SummaryProvider",code.c_str()));<br>+    //std::string code("     lldb.formatters.cpp.libcxx.stdstring_SummaryProvider(valobj,internal_dict)");<br>+    //lldb::TypeSummaryImplSP std_string_summary_sp(new ScriptSummaryFormat(stl_summary_flags, "lldb.formatters.cpp.libcxx.stdstring_SummaryProvider",code.c_str()));<br><br>+    lldb::TypeSummaryImplSP std_string_summary_sp(new CXXFunctionSummaryFormat(stl_summary_flags, lldb_private::formatters::LibcxxStringSummaryProvider, "std::string summary provider"));<br>+    lldb::TypeSummaryImplSP std_wstring_summary_sp(new CXXFunctionSummaryFormat(stl_summary_flags, lldb_private::formatters::LibcxxWStringSummaryProvider, "std::wstring summary provider"));<br>+<br>    TypeCategoryImpl::SharedPointer libcxx_category_sp = GetCategory(m_libcxx_category_name);<br><br>    libcxx_category_sp->GetSummaryNavigator()->Add(ConstString("std::__1::string"),<br>@@ -854,6 +857,11 @@<br>    libcxx_category_sp->GetSummaryNavigator()->Add(ConstString("std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >"),<br>                                                   std_string_summary_sp);<br><br>+    libcxx_category_sp->GetSummaryNavigator()->Add(ConstString("std::__1::wstring"),<br>+                                                   std_wstring_summary_sp);<br>+    libcxx_category_sp->GetSummaryNavigator()->Add(ConstString("std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >"),<br>+                                                   std_wstring_summary_sp);<br>+<br>    SyntheticChildren::Flags stl_synth_flags;<br>    stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(false);<br><br><br>Modified: lldb/trunk/source/Core/ValueObject.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=172282&r1=172281&r2=172282&view=diff">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=172282&r1=172281&r2=172282&view=diff</a><br>==============================================================================<br>--- lldb/trunk/source/Core/ValueObject.cpp (original)<br>+++ lldb/trunk/source/Core/ValueObject.cpp Fri Jan 11 19:00:22 2013<br>@@ -533,6 +533,86 @@<br>    return child_sp;<br>}<br><br>+ValueObjectSP<br>+ValueObject::GetChildAtIndexPath (const std::initializer_list<uint32_t>& idxs,<br>+                                  uint32_t* index_of_error)<br>+{<br>+    if (idxs.size() == 0)<br>+        return GetSP();<br>+    ValueObjectSP root(GetSP());<br>+    for (uint32_t idx : idxs)<br>+    {<br>+        root = root->GetChildAtIndex(idx, true);<br>+        if (!root)<br>+        {<br>+            if (index_of_error)<br>+                *index_of_error = idx;<br>+            return root;<br>+        }<br>+    }<br>+    return root;<br>+}<br>+<br>+ValueObjectSP<br>+ValueObject::GetChildAtIndexPath (const std::initializer_list< std::pair<uint32_t, bool> >& idxs,<br>+                                  uint32_t* index_of_error)<br>+{<br>+    if (idxs.size() == 0)<br>+        return GetSP();<br>+    ValueObjectSP root(GetSP());<br>+    for (std::pair<uint32_t, bool> idx : idxs)<br>+    {<br>+        root = root->GetChildAtIndex(idx.first, idx.second);<br>+        if (!root)<br>+        {<br>+            if (index_of_error)<br>+                *index_of_error = idx.first;<br>+            return root;<br>+        }<br>+    }<br>+    return root;<br>+}<br>+<br>+lldb::ValueObjectSP<br>+ValueObject::GetChildAtIndexPath (const std::vector<uint32_t> &idxs,<br>+                                  uint32_t* index_of_error)<br>+{<br>+    if (idxs.size() == 0)<br>+        return GetSP();<br>+    ValueObjectSP root(GetSP());<br>+    for (uint32_t idx : idxs)<br>+    {<br>+        root = root->GetChildAtIndex(idx, true);<br>+        if (!root)<br>+        {<br>+            if (index_of_error)<br>+                *index_of_error = idx;<br>+            return root;<br>+        }<br>+    }<br>+    return root;<br>+}<br>+<br>+lldb::ValueObjectSP<br>+ValueObject::GetChildAtIndexPath (const std::vector< std::pair<uint32_t, bool> > &idxs,<br>+                                  uint32_t* index_of_error)<br>+{<br>+    if (idxs.size() == 0)<br>+        return GetSP();<br>+    ValueObjectSP root(GetSP());<br>+    for (std::pair<uint32_t, bool> idx : idxs)<br>+    {<br>+        root = root->GetChildAtIndex(idx.first, idx.second);<br>+        if (!root)<br>+        {<br>+            if (index_of_error)<br>+                *index_of_error = idx.first;<br>+            return root;<br>+        }<br>+    }<br>+    return root;<br>+}<br>+<br>uint32_t<br>ValueObject::GetIndexOfChildWithName (const ConstString &name)<br>{<br><br>Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/Makefile<br>URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/Makefile?rev=172282&view=auto">http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/Makefile?rev=172282&view=auto</a><br>==============================================================================<br>--- lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/Makefile (added)<br>+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/Makefile Fri Jan 11 19:00:22 2013<br>@@ -0,0 +1,8 @@<br>+LEVEL = ../../../../../make<br>+<br>+CXX_SOURCES := main.cpp<br>+<br>+include $(LEVEL)/Makefile.rules<br>+<br>+CXXFLAGS += -stdlib=libc++ -O0<br>+LDFLAGS += -stdlib=libc++<br>\ No newline at end of file<br><br>Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py<br>URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py?rev=172282&view=auto">http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py?rev=172282&view=auto</a><br>==============================================================================<br>--- lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py (added)<br>+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py Fri Jan 11 19:00:22 2013<br>@@ -0,0 +1,81 @@<br>+#coding=utf8<br>+"""<br>+Test lldb data formatter subsystem.<br>+"""<br>+<br>+import os, time<br>+import unittest2<br>+import lldb<br>+from lldbtest import *<br>+import lldbutil<br>+<br>+class LibcxxStringDataFormatterTestCase(TestBase):<br>+<br>+    mydir = os.path.join("functionalities", "data-formatter", "data-formatter-stl", "libcxx", "string")<br>+<br>+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")<br>+    @dsym_test<br>+    def test_with_dsym_and_run_command(self):<br>+        """Test data formatter commands."""<br>+        self.buildDsym()<br>+        self.data_formatter_commands()<br>+<br>+    @skipOnLinux # No standard locations for libc++ on Linux, so skip for now<br>+    @dwarf_test<br>+    def test_with_dwarf_and_run_command(self):<br>+        """Test data formatter commands."""<br>+        self.buildDwarf()<br>+        self.data_formatter_commands()<br>+<br>+    def setUp(self):<br>+        # Call super's setUp().<br>+        TestBase.setUp(self)<br>+        # Find the line number to break at.<br>+        self.line = line_number('main.cpp', '// Set break point at this line.')<br>+<br>+    def data_formatter_commands(self):<br>+        """Test that that file and class static variables display correctly."""<br>+        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)<br>+<br>+        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=-1)<br>+<br>+        self.runCmd("run", RUN_SUCCEEDED)<br>+<br>+        # The stop reason of the thread should be breakpoint.<br>+        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,<br>+            substrs = ['stopped',<br>+                       'stop reason = breakpoint'])<br>+<br>+        # This is the function to remove the custom formats in order to have a<br>+        # clean slate for the next test case.<br>+        def cleanup():<br>+            self.runCmd('type format clear', check=False)<br>+            self.runCmd('type summary clear', check=False)<br>+            self.runCmd('type filter clear', check=False)<br>+            self.runCmd('type synth clear', check=False)<br>+            self.runCmd("settings set target.max-children-count 256", check=False)<br>+<br>+        # Execute the cleanup function during test case tear down.<br>+        self.addTearDownHook(cleanup)<br>+<br>+        self.expect("frame variable",<br>+                    substrs = ['(std::__1::wstring) s = L"hello world! ×ž×–ל ×˜×•×‘!"',<br>+                    '(std::__1::wstring) S = L"!!!!"',<br>+                    '(const wchar_t *) mazeltov = 0x','L"מזל ×˜×•×‘"',<br>+                    '(std::__1::string) q = "hello world"',<br>+                    '(std::__1::string) Q = "quite a long std::strin with lots of info inside it"'])<br>+<br>+        self.runCmd("n")<br>+<br>+        self.expect("frame variable",<br>+                    substrs = ['(std::__1::wstring) s = L"hello world! ×ž×–ל ×˜×•×‘!"',<br>+                    '(std::__1::wstring) S = L"!!!!!"',<br>+                    '(const wchar_t *) mazeltov = 0x','L"מזל ×˜×•×‘"',<br>+                    '(std::__1::string) q = "hello world"',<br>+                    '(std::__1::string) Q = "quite a long std::strin with lots of info inside it"'])<br>+<br>+if __name__ == '__main__':<br>+    import atexit<br>+    lldb.SBDebugger.Initialize()<br>+    atexit.register(lambda: lldb.SBDebugger.Terminate())<br>+    unittest2.main()<br><br>Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/main.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/main.cpp?rev=172282&view=auto">http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/main.cpp?rev=172282&view=auto</a><br>==============================================================================<br>--- lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/main.cpp (added)<br>+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/main.cpp Fri Jan 11 19:00:22 2013<br>@@ -0,0 +1,12 @@<br>+#include <string><br>+<br>+int main()<br>+{<br>+    std::wstring s(L"hello world! ×ž×–ל ×˜×•×‘!");<br>+    std::wstring S(L"!!!!");<br>+    const wchar_t *mazeltov = L"מזל ×˜×•×‘";<br>+    std::string q("hello world");<br>+    std::string Q("quite a long std::strin with lots of info inside it");<br>+    S.assign(L"!!!!!"); // Set break point at this line.<br>+    return 0;<br>+}<br>\ No newline at end of file<br><br><br>_______________________________________________<br>lldb-commits mailing list<br><a href="mailto:lldb-commits@cs.uiuc.edu">lldb-commits@cs.uiuc.edu</a><<a href="mailto:lldb-commits@cs.uiuc.edu">mailto:lldb-commits@cs.uiuc.edu</a>><br><a href="http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits">http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits</a><br><br><span><convert_utf_buildfix.patch></span></blockquote></div><br></div></body></html>