Author: tfiala
Date: Wed Oct 21 19:23:38 2015
New Revision: 250965

URL: http://llvm.org/viewvc/llvm-project?rev=250965&view=rev
Log:
Fix libstdc++ data formatters on Ubuntu 15.10 x86_64

See http://reviews.llvm.org/D13964 for details.

Modified:
    lldb/trunk/examples/synthetic/gnu_libstdcpp.py
    lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
    lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
    lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcpp.h
    
lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/loop/main.cpp
    
lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/TestDataFormatterStdString.py
    lldb/trunk/test/make/Makefile.rules

Modified: lldb/trunk/examples/synthetic/gnu_libstdcpp.py
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/synthetic/gnu_libstdcpp.py?rev=250965&r1=250964&r2=250965&view=diff
==============================================================================
--- lldb/trunk/examples/synthetic/gnu_libstdcpp.py (original)
+++ lldb/trunk/examples/synthetic/gnu_libstdcpp.py Wed Oct 21 19:23:38 2015
@@ -13,7 +13,7 @@ class StdListSynthProvider:
                logger = lldb.formatters.Logger.Logger()
                self.valobj = valobj
                self.count = None
-               logger >> "Providing synthetic children for a map named " + 
str(valobj.GetName())
+               logger >> "Providing synthetic children for a list named " + 
str(valobj.GetName())
 
        def next_node(self,node):
                logger = lldb.formatters.Logger.Logger()
@@ -21,11 +21,20 @@ class StdListSynthProvider:
 
        def is_valid(self,node):
                logger = lldb.formatters.Logger.Logger()
-               return self.value(self.next_node(node)) != self.node_address
+               valid = self.value(self.next_node(node)) != self.node_address
+                if valid:
+                        logger >> "%s is valid" % str(self.valobj.GetName())
+                else:
+                        logger >> "synthetic value is not valid"
+                return valid
 
        def value(self,node):
                logger = lldb.formatters.Logger.Logger()
-               return node.GetValueAsUnsigned()
+                value = node.GetValueAsUnsigned()
+                logger >> "synthetic value for {}: {}".format(
+                        str(self.valobj.GetName()),
+                        value)
+                return value
 
        # Floyd's cycle-finding algorithm
        # try to detect if this list has a loop
@@ -49,7 +58,12 @@ class StdListSynthProvider:
 
        def num_children(self):
                logger = lldb.formatters.Logger.Logger()
-               if self.count == None:
+               if self.count is None:
+                        # libstdc++ 6.0.21 added dedicated count field.
+                        count_child = 
self.node.GetChildMemberWithName('_M_data')
+                        if count_child and count_child.IsValid():
+                                self.count = count_child.GetValueAsUnsigned(0)
+                if self.count is None:
                        self.count = self.num_children_impl()
                return self.count
 
@@ -117,10 +131,10 @@ class StdListSynthProvider:
                self.count = None
                try:
                        impl = self.valobj.GetChildMemberWithName('_M_impl')
-                       node = impl.GetChildMemberWithName('_M_node')
+                       self.node = impl.GetChildMemberWithName('_M_node')
                        self.node_address = 
self.valobj.AddressOf().GetValueAsUnsigned(0)
-                       self.next = node.GetChildMemberWithName('_M_next')
-                       self.prev = node.GetChildMemberWithName('_M_prev')
+                       self.next = self.node.GetChildMemberWithName('_M_next')
+                       self.prev = self.node.GetChildMemberWithName('_M_prev')
                        self.data_type = self.extract_type()
                        self.data_size = self.data_type.GetByteSize()
                except:

Modified: lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp?rev=250965&r1=250964&r2=250965&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp 
(original)
+++ lldb/trunk/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp Wed Oct 
21 19:23:38 2015
@@ -545,7 +545,14 @@ LoadLibStdcppFormatters(lldb::TypeCatego
     
     lldb::TypeSummaryImplSP std_string_summary_sp(new 
StringSummaryFormat(stl_summary_flags,
                                                                           
"${var._M_dataplus._M_p}"));
-    
+
+    lldb::TypeSummaryImplSP cxx11_string_summary_sp(new 
CXXFunctionSummaryFormat(stl_summary_flags,
+                                                                               
  LibStdcppStringSummaryProvider,
+                                                                               
  "libstdc++ c++11 std::string summary provider"));
+    lldb::TypeSummaryImplSP cxx11_wstring_summary_sp(new 
CXXFunctionSummaryFormat(stl_summary_flags,
+                                                                               
  LibStdcppWStringSummaryProvider,
+                                                                               
  "libstdc++ c++11 std::wstring summary provider"));
+
     
cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::string"),
                                                       std_string_summary_sp);
     
cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::basic_string<char>"),
@@ -554,7 +561,12 @@ LoadLibStdcppFormatters(lldb::TypeCatego
                                                       std_string_summary_sp);
     
cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::basic_string<char,
 std::char_traits<char>, std::allocator<char> >"),
                                                       std_string_summary_sp);
-    
+
+    
cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__cxx11::string"),
+                                                      cxx11_string_summary_sp);
+    
cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__cxx11::basic_string<char,
 std::char_traits<char>, std::allocator<char> >"),
+                                                      cxx11_string_summary_sp);
+
     // making sure we force-pick the summary for printing wstring (_M_p is a 
wchar_t*)
     lldb::TypeSummaryImplSP std_wstring_summary_sp(new 
StringSummaryFormat(stl_summary_flags,
                                                                            
"${var._M_dataplus._M_p%S}"));
@@ -567,8 +579,12 @@ LoadLibStdcppFormatters(lldb::TypeCatego
                                                       std_wstring_summary_sp);
     
cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::basic_string<wchar_t,
 std::char_traits<wchar_t>, std::allocator<wchar_t> >"),
                                                       std_wstring_summary_sp);
-    
-    
+
+    
cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__cxx11::wstring"),
+                                                      
cxx11_wstring_summary_sp);
+    
cpp_category_sp->GetTypeSummariesContainer()->Add(ConstString("std::__cxx11::basic_string<wchar_t,
 std::char_traits<wchar_t>, std::allocator<wchar_t> >"),
+                                                      
cxx11_wstring_summary_sp);
+
 #ifndef LLDB_DISABLE_PYTHON
     
     SyntheticChildren::Flags stl_synth_flags;
@@ -580,9 +596,16 @@ LoadLibStdcppFormatters(lldb::TypeCatego
     
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(RegularExpressionSP(new 
RegularExpression("^std::map<.+> >(( )?&)?$")),
                                                             
SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
                                                                                
                               
"lldb.formatters.cpp.gnu_libstdcpp.StdMapSynthProvider")));
-    
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(RegularExpressionSP(new 
RegularExpression("^std::list<.+>(( )?&)?$")),
+    
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(RegularExpressionSP(new 
RegularExpression("^std::(__cxx11::)?list<.+>(( )?&)?$")),
                                                             
SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
                                                                                
                               
"lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider")));
+#if 0
+    // With only this, I get std::list showing the content, all children on 
the same line.
+    // With this and the section below, I see one child element per line.
+    
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(RegularExpressionSP(new 
RegularExpression("^std::__cxx11::_List_base<.+>(( )?&)?$")),
+                                                            
SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
+                                                                               
                               
"lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider")));
+#endif
     
     
stl_summary_flags.SetDontShowChildren(false);stl_summary_flags.SetSkipPointers(true);
     
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(RegularExpressionSP(new 
RegularExpression("^std::vector<.+>(( )?&)?$")),
@@ -591,10 +614,16 @@ LoadLibStdcppFormatters(lldb::TypeCatego
     
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(RegularExpressionSP(new 
RegularExpression("^std::map<.+> >(( )?&)?$")),
                                                            
TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags,
                                                                                
                      "size=${svar%#}")));
-    
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(RegularExpressionSP(new 
RegularExpression("^std::list<.+>(( )?&)?$")),
+    
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(RegularExpressionSP(new 
RegularExpression("^std::(__cxx11::)?list<.+>(( )?&)?$")),
                                                            
TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags,
                                                                                
                      "size=${svar%#}")));
-    
+#if 0
+    // With this, I get std::list showing one child per line.  Requires the 
change above to get anything, though.
+    
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(RegularExpressionSP(new 
RegularExpression("^std::__cxx11::_List_base<.+>(( )?&)?$")),
+                                                           
TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags,
+                                                                               
                      "size=${svar%#}")));
+#endif
+
     AddCXXSynthetic(cpp_category_sp, 
lldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator, 
"std::vector iterator synthetic children", 
ConstString("^__gnu_cxx::__normal_iterator<.+>$"), stl_synth_flags, true);
     
     AddCXXSynthetic(cpp_category_sp, 
lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator, 
"std::map iterator synthetic children", 
ConstString("^std::_Rb_tree_iterator<.+>$"), stl_synth_flags, true);

Modified: lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp?rev=250965&r1=250964&r2=250965&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp (original)
+++ lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp Wed Oct 21 
19:23:38 2015
@@ -14,6 +14,7 @@
 #include "lldb/Core/Stream.h"
 #include "lldb/Core/ValueObject.h"
 #include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/DataFormatters/StringPrinter.h"
 #include "lldb/DataFormatters/VectorIterator.h"
 #include "lldb/Host/Endian.h"
 #include "lldb/Symbol/ClangASTContext.h"
@@ -256,3 +257,117 @@ lldb_private::formatters::VectorIterator
 
lldb_private::formatters::VectorIteratorSyntheticFrontEnd::~VectorIteratorSyntheticFrontEnd
 ()
 {
 }
+
+bool
+lldb_private::formatters::LibStdcppStringSummaryProvider (ValueObject& valobj, 
Stream& stream, const TypeSummaryOptions& options)
+{
+    const bool scalar_is_load_addr = true;
+    AddressType addr_type;
+    lldb::addr_t addr_of_string = valobj.GetAddressOf(scalar_is_load_addr, 
&addr_type);
+    if (addr_of_string != LLDB_INVALID_ADDRESS)
+    {
+        switch (addr_type)
+        {
+            case eAddressTypeLoad:
+            {
+                ProcessSP process_sp(valobj.GetProcessSP());
+                if (!process_sp)
+                    return false;
+
+                StringPrinter::ReadStringAndDumpToStreamOptions 
options(valobj);
+                Error error;
+                lldb::addr_t addr_of_data = 
process_sp->ReadPointerFromMemory(addr_of_string, error);
+                if (error.Fail() || addr_of_data == 0 || addr_of_data == 
LLDB_INVALID_ADDRESS)
+                    return false;
+                options.SetLocation(addr_of_data);
+                options.SetProcessSP(process_sp);
+                options.SetStream(&stream);
+                options.SetNeedsZeroTermination(false);
+                options.SetBinaryZeroIsTerminator(true);
+                lldb::addr_t size_of_data = 
process_sp->ReadPointerFromMemory(addr_of_string + 
process_sp->GetAddressByteSize(), error);
+                if (error.Fail())
+                    return false;
+                options.SetSourceSize(size_of_data);
+
+                if 
(!StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF8>(options))
+                {
+                    stream.Printf("Summary Unavailable");
+                    return true;
+                }
+                else
+                    return true;
+            }
+                break;
+            case eAddressTypeHost:
+                break;
+            case eAddressTypeInvalid:
+            case eAddressTypeFile:
+                break;
+        }
+    }
+    return false;
+}
+
+bool
+lldb_private::formatters::LibStdcppWStringSummaryProvider (ValueObject& 
valobj, Stream& stream, const TypeSummaryOptions& options)
+{
+    const bool scalar_is_load_addr = true;
+    AddressType addr_type;
+    lldb::addr_t addr_of_string = valobj.GetAddressOf(scalar_is_load_addr, 
&addr_type);
+    if (addr_of_string != LLDB_INVALID_ADDRESS)
+    {
+        switch (addr_type)
+        {
+            case eAddressTypeLoad:
+            {
+                ProcessSP process_sp(valobj.GetProcessSP());
+                if (!process_sp)
+                    return false;
+
+                CompilerType wchar_compiler_type = 
valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar);
+
+                if (!wchar_compiler_type)
+                    return false;
+
+                const uint32_t wchar_size = 
wchar_compiler_type.GetBitSize(nullptr); // Safe to pass NULL for exe_scope here
+
+                StringPrinter::ReadStringAndDumpToStreamOptions 
options(valobj);
+                Error error;
+                lldb::addr_t addr_of_data = 
process_sp->ReadPointerFromMemory(addr_of_string, error);
+                if (error.Fail() || addr_of_data == 0 || addr_of_data == 
LLDB_INVALID_ADDRESS)
+                    return false;
+                options.SetLocation(addr_of_data);
+                options.SetProcessSP(process_sp);
+                options.SetStream(&stream);
+                options.SetNeedsZeroTermination(false);
+                options.SetBinaryZeroIsTerminator(false);
+                lldb::addr_t size_of_data = 
process_sp->ReadPointerFromMemory(addr_of_string + 
process_sp->GetAddressByteSize(), error);
+                if (error.Fail())
+                    return false;
+                options.SetSourceSize(size_of_data);
+                options.SetPrefixToken("L");
+
+                switch (wchar_size)
+                {
+                    case 8:
+                        return 
StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF8>(options);
+                    case 16:
+                        return 
StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16>(options);
+                    case 32:
+                        return 
StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF32>(options);
+                    default:
+                        stream.Printf("size for wchar_t is not valid");
+                        return true;
+                }
+                return true;
+            }
+                break;
+            case eAddressTypeHost:
+                break;
+            case eAddressTypeInvalid:
+            case eAddressTypeFile:
+                break;
+        }
+    }
+    return false;
+}

Modified: lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcpp.h
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcpp.h?rev=250965&r1=250964&r2=250965&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcpp.h (original)
+++ lldb/trunk/source/Plugins/Language/CPlusPlus/LibStdcpp.h Wed Oct 21 
19:23:38 2015
@@ -18,6 +18,12 @@
 namespace lldb_private {
     namespace formatters
     {
+        bool
+        LibStdcppStringSummaryProvider (ValueObject& valobj, Stream& stream, 
const TypeSummaryOptions& options); // libcstdc++ c++11 std::string
+
+        bool
+        LibStdcppWStringSummaryProvider (ValueObject& valobj, Stream& stream, 
const TypeSummaryOptions& options); // libcstdc++ c++11 std::wstring
+
         SyntheticChildrenFrontEnd* 
LibstdcppMapIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, 
lldb::ValueObjectSP);
         
         SyntheticChildrenFrontEnd* 
LibStdcppVectorIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, 
lldb::ValueObjectSP);

Modified: 
lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/loop/main.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/loop/main.cpp?rev=250965&r1=250964&r2=250965&view=diff
==============================================================================
--- 
lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/loop/main.cpp
 (original)
+++ 
lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/loop/main.cpp
 Wed Oct 21 19:23:38 2015
@@ -15,6 +15,7 @@ typedef std::list<int> int_list;
 
 int main()
 {
+#ifdef LLDB_USING_LIBCPP
     int_list *numbers_list = new int_list{1,2,3,4,5,6,7,8,9,10};
 
     auto *third_elem = numbers_list->__end_.__next_->__next_->__next_; // Set 
break point at this line.
@@ -22,6 +23,7 @@ int main()
     auto *fifth_elem = third_elem->__next_->__next_;
     assert(fifth_elem->__value_ == 5);
     fifth_elem->__next_ = third_elem;
+#endif
 
     // Any attempt to free the list will probably crash the program. Let's 
just leak it.
     return 0; // Set second break point at this line.

Modified: 
lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/TestDataFormatterStdString.py
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/TestDataFormatterStdString.py?rev=250965&r1=250964&r2=250965&view=diff
==============================================================================
--- 
lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/TestDataFormatterStdString.py
 (original)
+++ 
lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/TestDataFormatterStdString.py
 Wed Oct 21 19:23:38 2015
@@ -47,21 +47,21 @@ class StdStringDataFormatterTestCase(Tes
         # Execute the cleanup function during test case tear down.
         self.addTearDownHook(cleanup)
 
-        self.expect("frame variable",
-                    substrs = ['(std::wstring) s = L"hello world! מזל 
טוב!"',
-                    '(std::wstring) S = L"!!!!"',
-                    '(const wchar_t *) mazeltov = 0x','L"מזל טוב"',
-                    '(std::string) q = "hello world"',
-                    '(std::string) Q = "quite a long std::strin with lots of 
info inside it"'])
+        var_s = self.frame().FindVariable('s')
+        var_S = self.frame().FindVariable('S')
+        var_mazeltov = self.frame().FindVariable('mazeltov')
+        var_q = self.frame().FindVariable('q')
+        var_Q = self.frame().FindVariable('Q')
 
-        self.runCmd("n")
+        self.assertTrue(var_s.GetSummary() == 'L"hello world! מזל 
טוב!"', "s summary wrong")
+        self.assertTrue(var_S.GetSummary() == 'L"!!!!"', "S summary wrong")
+        self.assertTrue(var_mazeltov.GetSummary() == 'L"מזל טוב"', 
"mazeltov summary wrong")
+        self.assertTrue(var_q.GetSummary() == '"hello world"', "q summary 
wrong")
+        self.assertTrue(var_Q.GetSummary() == '"quite a long std::strin with 
lots of info inside it"', "Q summary wrong")
 
-        self.expect("frame variable",
-                    substrs = ['(std::wstring) s = L"hello world! מזל 
טוב!"',
-                    '(std::wstring) S = L"!!!!!"',
-                    '(const wchar_t *) mazeltov = 0x','L"מזל טוב"',
-                    '(std::string) q = "hello world"',
-                    '(std::string) Q = "quite a long std::strin with lots of 
info inside it"'])
+        self.runCmd("next")
+
+        self.assertTrue(var_S.GetSummary() == 'L"!!!!!"', "new S summary 
wrong")
 
 if __name__ == '__main__':
     import atexit

Modified: lldb/trunk/test/make/Makefile.rules
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/test/make/Makefile.rules?rev=250965&r1=250964&r2=250965&view=diff
==============================================================================
--- lldb/trunk/test/make/Makefile.rules (original)
+++ lldb/trunk/test/make/Makefile.rules Wed Oct 21 19:23:38 2015
@@ -296,12 +296,12 @@ ifeq (1,$(USE_LIBCPP))
                ifeq "$(OS)" "Linux"
                        # This is the default install location on Ubuntu 14.04
                        ifneq ($(wildcard /usr/include/c++/v1/.),)
-                               CXXFLAGS += -stdlib=libc++
+                               CXXFLAGS += -stdlib=libc++ -DLLDB_USING_LIBCPP
                                LDFLAGS += -stdlib=libc++
                                CXXFLAGS += -I/usr/include/c++/v1
                        endif
                else
-                       CXXFLAGS += -stdlib=libc++
+                       CXXFLAGS += -stdlib=libc++ -DLLDB_USING_LIBCPP
                        LDFLAGS += -stdlib=libc++
                endif
        endif


_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to