[Lldb-commits] [lldb] r190564 - <rdar://problem/14071463>

Enrico Granata egranata at apple.com
Wed Sep 11 17:48:47 PDT 2013


Author: enrico
Date: Wed Sep 11 19:48:47 2013
New Revision: 190564

URL: http://llvm.org/viewvc/llvm-project?rev=190564&view=rev
Log:
<rdar://problem/14071463>

SVN r189964 provided a sample Python script to inspect unordered(multi){set|map} with synthetic children, contribued by Jared Grubb
This checkin converts that sample script to a C++ provider built into LLDB
A test case is also provided


Added:
    lldb/trunk/source/DataFormatters/LibCxxUnorderedMap.cpp
    lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/
    lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/Makefile
    lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/TestDataFormatterUnordered.py
    lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/main.cpp
Modified:
    lldb/trunk/include/lldb/Core/ValueObject.h
    lldb/trunk/include/lldb/DataFormatters/CXXFormatterFunctions.h
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/source/Core/ValueObject.cpp
    lldb/trunk/source/DataFormatters/FormatManager.cpp

Modified: lldb/trunk/include/lldb/Core/ValueObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=190564&r1=190563&r2=190564&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObject.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObject.h Wed Sep 11 19:48:47 2013
@@ -767,6 +767,23 @@ public:
     lldb::ValueObjectSP
     GetChildAtIndexPath (const std::vector< std::pair<size_t, bool> > &idxs,
                          size_t* index_of_error = NULL);
+
+    // this will always create the children if necessary
+    lldb::ValueObjectSP
+    GetChildAtNamePath (const std::initializer_list<ConstString> &names,
+                        ConstString* name_of_error = NULL);
+    
+    lldb::ValueObjectSP
+    GetChildAtNamePath (const std::vector<ConstString> &names,
+                        ConstString* name_of_error = NULL);
+    
+    lldb::ValueObjectSP
+    GetChildAtNamePath (const std::initializer_list< std::pair<ConstString, bool> > &names,
+                        ConstString* name_of_error = NULL);
+    
+    lldb::ValueObjectSP
+    GetChildAtNamePath (const std::vector< std::pair<ConstString, bool> > &names,
+                        ConstString* name_of_error = NULL);
     
     virtual lldb::ValueObjectSP
     GetChildMemberWithName (const ConstString &name, bool can_create);

Modified: lldb/trunk/include/lldb/DataFormatters/CXXFormatterFunctions.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/CXXFormatterFunctions.h?rev=190564&r1=190563&r2=190564&view=diff
==============================================================================
--- lldb/trunk/include/lldb/DataFormatters/CXXFormatterFunctions.h (original)
+++ lldb/trunk/include/lldb/DataFormatters/CXXFormatterFunctions.h Wed Sep 11 19:48:47 2013
@@ -868,6 +868,39 @@ namespace lldb_private {
         
         SyntheticChildrenFrontEnd* LibcxxStdMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
         
+        class LibcxxStdUnorderedMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+        {
+        public:
+            LibcxxStdUnorderedMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+            
+            virtual size_t
+            CalculateNumChildren ();
+            
+            virtual lldb::ValueObjectSP
+            GetChildAtIndex (size_t idx);
+            
+            virtual bool
+            Update();
+            
+            virtual bool
+            MightHaveChildren ();
+            
+            virtual size_t
+            GetIndexOfChildWithName (const ConstString &name);
+            
+            virtual
+            ~LibcxxStdUnorderedMapSyntheticFrontEnd ();
+        private:
+            
+            ValueObject* m_tree;
+            size_t m_num_elements;
+            ValueObject* m_next_element;
+            std::map<size_t,lldb::ValueObjectSP> m_children;
+            std::vector<std::pair<ValueObject*, uint64_t> > m_elements_cache;
+        };
+        
+        SyntheticChildrenFrontEnd* LibcxxStdUnorderedMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+        
     } // namespace formatters
 } // namespace lldb_private
 

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=190564&r1=190563&r2=190564&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Wed Sep 11 19:48:47 2013
@@ -531,11 +531,11 @@
 		944372DD171F6B4300E57C32 /* RegisterContextDummy.h in Headers */ = {isa = PBXBuildFile; fileRef = 944372DB171F6B4300E57C32 /* RegisterContextDummy.h */; };
 		9443B122140C18C40013457C /* SBData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9443B121140C18C10013457C /* SBData.cpp */; };
 		9443B123140C26AB0013457C /* SBData.h in Headers */ = {isa = PBXBuildFile; fileRef = 9443B120140C18A90013457C /* SBData.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		9452573A16262D0200325455 /* SBDeclaration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9452573916262D0200325455 /* SBDeclaration.cpp */; };
+		9456F2241616671900656F91 /* DynamicLibrary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9456F2211616644B00656F91 /* DynamicLibrary.cpp */; };
 		945759671534941F005A9070 /* PlatformPOSIX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 945759651534941F005A9070 /* PlatformPOSIX.cpp */; };
 		945759681534941F005A9070 /* PlatformPOSIX.h in Headers */ = {isa = PBXBuildFile; fileRef = 945759661534941F005A9070 /* PlatformPOSIX.h */; };
 		945E8D80152F6AB40019BCCD /* StreamGDBRemote.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 945E8D7F152F6AB40019BCCD /* StreamGDBRemote.cpp */; };
-		9452573A16262D0200325455 /* SBDeclaration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9452573916262D0200325455 /* SBDeclaration.cpp */; };
-		9456F2241616671900656F91 /* DynamicLibrary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9456F2211616644B00656F91 /* DynamicLibrary.cpp */; };
 		9461569A14E358A6003A195C /* SBTypeFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9461568A14E35621003A195C /* SBTypeFilter.cpp */; };
 		9461569B14E358A6003A195C /* SBTypeFormat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9461568B14E35621003A195C /* SBTypeFormat.cpp */; };
 		9461569C14E358A6003A195C /* SBTypeSummary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9461568C14E35621003A195C /* SBTypeSummary.cpp */; };
@@ -549,7 +549,6 @@
 		947A1D651616476B0017C8D1 /* CommandObjectPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 947A1D631616476A0017C8D1 /* CommandObjectPlugin.h */; };
 		949ADF031406F648004833E1 /* ValueObjectConstResultImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 949ADF021406F648004833E1 /* ValueObjectConstResultImpl.cpp */; };
 		94B6E76213D88365005F417F /* ValueObjectSyntheticFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94B6E76113D88362005F417F /* ValueObjectSyntheticFilter.cpp */; };
-		94E829CA152D33C1006F96A3 /* lldb-platform in Resources */ = {isa = PBXBuildFile; fileRef = 26DC6A101337FE6900FF7998 /* lldb-platform */; };
 		94BA8B6D176F8C9B005A91B5 /* Range.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94BA8B6C176F8C9B005A91B5 /* Range.cpp */; };
 		94BA8B70176F97CE005A91B5 /* CommandHistory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94BA8B6F176F97CE005A91B5 /* CommandHistory.cpp */; };
 		94CB255B16B069770059775D /* CXXFormatterFunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CB255716B069770059775D /* CXXFormatterFunctions.cpp */; };
@@ -571,7 +570,9 @@
 		94D6A0AA16CEB55F00833B6E /* NSArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94D6A0A716CEB55F00833B6E /* NSArray.cpp */; };
 		94D6A0AB16CEB55F00833B6E /* NSDictionary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94D6A0A816CEB55F00833B6E /* NSDictionary.cpp */; };
 		94D6A0AC16CEB55F00833B6E /* NSSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94D6A0A916CEB55F00833B6E /* NSSet.cpp */; };
+		94E829CA152D33C1006F96A3 /* lldb-platform in Resources */ = {isa = PBXBuildFile; fileRef = 26DC6A101337FE6900FF7998 /* lldb-platform */; };
 		94EA1D5C15E6C9B400D4171A /* PythonDataObjects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94EA1D5B15E6C9B400D4171A /* PythonDataObjects.cpp */; };
+		94EA27CE17DE91750070F505 /* LibCxxUnorderedMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94EA27CD17DE91750070F505 /* LibCxxUnorderedMap.cpp */; };
 		94FA3DE01405D50400833217 /* ValueObjectConstResultChild.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94FA3DDF1405D50300833217 /* ValueObjectConstResultChild.cpp */; };
 		9A19A6AF1163BBB200E0D453 /* SBValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A19A6A51163BB7E00E0D453 /* SBValue.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		9A19A6B01163BBB300E0D453 /* SBValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A19A6AD1163BB9800E0D453 /* SBValue.cpp */; };
@@ -1573,16 +1574,16 @@
 		944372DB171F6B4300E57C32 /* RegisterContextDummy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextDummy.h; path = Utility/RegisterContextDummy.h; sourceTree = "<group>"; };
 		9443B120140C18A90013457C /* SBData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SBData.h; path = include/lldb/API/SBData.h; sourceTree = "<group>"; };
 		9443B121140C18C10013457C /* SBData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBData.cpp; path = source/API/SBData.cpp; sourceTree = "<group>"; };
-		945759651534941F005A9070 /* PlatformPOSIX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PlatformPOSIX.cpp; path = POSIX/PlatformPOSIX.cpp; sourceTree = "<group>"; };
-		945759661534941F005A9070 /* PlatformPOSIX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlatformPOSIX.h; path = POSIX/PlatformPOSIX.h; sourceTree = "<group>"; };
-		945E8D7D152F6AA80019BCCD /* StreamGDBRemote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StreamGDBRemote.h; path = include/lldb/Core/StreamGDBRemote.h; sourceTree = "<group>"; };
-		945E8D7F152F6AB40019BCCD /* StreamGDBRemote.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StreamGDBRemote.cpp; path = source/Core/StreamGDBRemote.cpp; sourceTree = "<group>"; };
 		944DC3481774C99000D7D884 /* python-swigsafecast.swig */ = {isa = PBXFileReference; lastKnownFileType = text; path = "python-swigsafecast.swig"; sourceTree = "<group>"; };
 		9452573616262CD000325455 /* SBDeclaration.i */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBDeclaration.i; sourceTree = "<group>"; };
 		9452573816262CEF00325455 /* SBDeclaration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SBDeclaration.h; path = include/lldb/API/SBDeclaration.h; sourceTree = "<group>"; };
 		9452573916262D0200325455 /* SBDeclaration.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBDeclaration.cpp; path = source/API/SBDeclaration.cpp; sourceTree = "<group>"; };
 		9456F2211616644B00656F91 /* DynamicLibrary.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DynamicLibrary.cpp; sourceTree = "<group>"; };
 		9456F2231616645A00656F91 /* DynamicLibrary.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = DynamicLibrary.h; path = include/lldb/Host/DynamicLibrary.h; sourceTree = "<group>"; };
+		945759651534941F005A9070 /* PlatformPOSIX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PlatformPOSIX.cpp; path = POSIX/PlatformPOSIX.cpp; sourceTree = "<group>"; };
+		945759661534941F005A9070 /* PlatformPOSIX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlatformPOSIX.h; path = POSIX/PlatformPOSIX.h; sourceTree = "<group>"; };
+		945E8D7D152F6AA80019BCCD /* StreamGDBRemote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StreamGDBRemote.h; path = include/lldb/Core/StreamGDBRemote.h; sourceTree = "<group>"; };
+		945E8D7F152F6AB40019BCCD /* StreamGDBRemote.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StreamGDBRemote.cpp; path = source/Core/StreamGDBRemote.cpp; sourceTree = "<group>"; };
 		9461568614E355F2003A195C /* SBTypeFilter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SBTypeFilter.h; path = include/lldb/API/SBTypeFilter.h; sourceTree = "<group>"; };
 		9461568714E355F2003A195C /* SBTypeFormat.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SBTypeFormat.h; path = include/lldb/API/SBTypeFormat.h; sourceTree = "<group>"; };
 		9461568814E355F2003A195C /* SBTypeSummary.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SBTypeSummary.h; path = include/lldb/API/SBTypeSummary.h; sourceTree = "<group>"; };
@@ -1647,6 +1648,7 @@
 		94E367CE140C4EEA001C7A5A /* python-typemaps.swig */ = {isa = PBXFileReference; lastKnownFileType = text; path = "python-typemaps.swig"; sourceTree = "<group>"; };
 		94EA1D5A15E6C99B00D4171A /* PythonDataObjects.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PythonDataObjects.h; path = include/lldb/Interpreter/PythonDataObjects.h; sourceTree = "<group>"; };
 		94EA1D5B15E6C9B400D4171A /* PythonDataObjects.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PythonDataObjects.cpp; path = source/Interpreter/PythonDataObjects.cpp; sourceTree = "<group>"; };
+		94EA27CD17DE91750070F505 /* LibCxxUnorderedMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxxUnorderedMap.cpp; path = source/DataFormatters/LibCxxUnorderedMap.cpp; sourceTree = "<group>"; };
 		94EBAC8313D9EE26009BA64E /* PythonPointer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PythonPointer.h; path = include/lldb/Utility/PythonPointer.h; sourceTree = "<group>"; };
 		94FA3DDD1405D4E500833217 /* ValueObjectConstResultChild.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ValueObjectConstResultChild.h; path = include/lldb/Core/ValueObjectConstResultChild.h; sourceTree = "<group>"; };
 		94FA3DDF1405D50300833217 /* ValueObjectConstResultChild.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectConstResultChild.cpp; path = source/Core/ValueObjectConstResultChild.cpp; sourceTree = "<group>"; };
@@ -3429,60 +3431,6 @@
 			name = POSIX;
 			sourceTree = "<group>";
 		};
-		940DB8C416EA64D400D3C2F1 /* lldb-perf */ = {
-			isa = PBXGroup;
-			children = (
-				940DB8C616EA654E00D3C2F1 /* darwin */,
-				940DB8C516EA654900D3C2F1 /* lib */,
-			);
-			name = "lldb-perf";
-			path = "tools/lldb-perf";
-			sourceTree = "<group>";
-		};
-		940DB8C516EA654900D3C2F1 /* lib */ = {
-			isa = PBXGroup;
-			children = (
-				940DB8CA16EA66FB00D3C2F1 /* Gauge.h */,
-				940DB8CE16EA670C00D3C2F1 /* Measurement.h */,
-				940DB8D116EA671800D3C2F1 /* MemoryGauge.cpp */,
-				940DB8D216EA671800D3C2F1 /* MemoryGauge.h */,
-				940DB8D516EA672200D3C2F1 /* Metric.cpp */,
-				940DB8D616EA672200D3C2F1 /* Metric.h */,
-				940DB8D916EA672D00D3C2F1 /* TestCase.cpp */,
-				940DB8DA16EA672D00D3C2F1 /* TestCase.h */,
-				940DB8DD16EA673800D3C2F1 /* Timer.cpp */,
-				940DB8DE16EA673800D3C2F1 /* Timer.h */,
-				940DB8E116EA674000D3C2F1 /* Xcode.cpp */,
-				940DB8E216EA674000D3C2F1 /* Xcode.h */,
-			);
-			path = lib;
-			sourceTree = "<group>";
-		};
-		940DB8C616EA654E00D3C2F1 /* darwin */ = {
-			isa = PBXGroup;
-			children = (
-				940DB8FB16EA84BF00D3C2F1 /* formatters */,
-				940DB8C716EA655400D3C2F1 /* sketch */,
-			);
-			path = darwin;
-			sourceTree = "<group>";
-		};
-		940DB8C716EA655400D3C2F1 /* sketch */ = {
-			isa = PBXGroup;
-			children = (
-				940DB8E616EA709400D3C2F1 /* main.cpp */,
-			);
-			path = sketch;
-			sourceTree = "<group>";
-		};
-		940DB8FB16EA84BF00D3C2F1 /* formatters */ = {
-			isa = PBXGroup;
-			children = (
-				94DB60F016EA888A00459D9E /* main.cpp */,
-			);
-			path = formatters;
-			sourceTree = "<group>";
-		};
 		94CB255616B0683B0059775D /* DataFormatters */ = {
 			isa = PBXGroup;
 			children = (
@@ -3502,6 +3450,7 @@
 				94D0B10A16D5535900EA9C70 /* LibCxx.cpp */,
 				94CD704F16F8DF1C00CF1E42 /* LibCxxList.cpp */,
 				94CD705116F8F5BC00CF1E42 /* LibCxxMap.cpp */,
+				94EA27CD17DE91750070F505 /* LibCxxUnorderedMap.cpp */,
 				94D0B10B16D5535900EA9C70 /* LibStdcpp.cpp */,
 				94D6A0A716CEB55F00833B6E /* NSArray.cpp */,
 				94D6A0A816CEB55F00833B6E /* NSDictionary.cpp */,
@@ -4327,6 +4276,7 @@
 				94B6E76213D88365005F417F /* ValueObjectSyntheticFilter.cpp in Sources */,
 				262D24E613FB8710002D1960 /* RegisterContextMemory.cpp in Sources */,
 				26F4A21C13FBA31A0064B613 /* ThreadMemory.cpp in Sources */,
+				94EA27CE17DE91750070F505 /* LibCxxUnorderedMap.cpp in Sources */,
 				266DFE9713FD656E00D0C574 /* OperatingSystem.cpp in Sources */,
 				26954EBE1401EE8B00294D09 /* DynamicRegisterInfo.cpp in Sources */,
 				26274FA714030F79006BA130 /* DynamicLoaderDarwinKernel.cpp in Sources */,

Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=190564&r1=190563&r2=190564&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Wed Sep 11 19:48:47 2013
@@ -595,6 +595,86 @@ ValueObject::GetChildAtIndexPath (const
     return root;
 }
 
+lldb::ValueObjectSP
+ValueObject::GetChildAtNamePath (const std::initializer_list<ConstString> &names,
+                                 ConstString* name_of_error)
+{
+    if (names.size() == 0)
+        return GetSP();
+    ValueObjectSP root(GetSP());
+    for (ConstString name : names)
+    {
+        root = root->GetChildMemberWithName(name, true);
+        if (!root)
+        {
+            if (name_of_error)
+                *name_of_error = name;
+            return root;
+        }
+    }
+    return root;
+}
+
+lldb::ValueObjectSP
+ValueObject::GetChildAtNamePath (const std::vector<ConstString> &names,
+                                 ConstString* name_of_error)
+{
+    if (names.size() == 0)
+        return GetSP();
+    ValueObjectSP root(GetSP());
+    for (ConstString name : names)
+    {
+        root = root->GetChildMemberWithName(name, true);
+        if (!root)
+        {
+            if (name_of_error)
+                *name_of_error = name;
+            return root;
+        }
+    }
+    return root;
+}
+
+lldb::ValueObjectSP
+ValueObject::GetChildAtNamePath (const std::initializer_list< std::pair<ConstString, bool> > &names,
+                                 ConstString* name_of_error)
+{
+    if (names.size() == 0)
+        return GetSP();
+    ValueObjectSP root(GetSP());
+    for (std::pair<ConstString, bool> name : names)
+    {
+        root = root->GetChildMemberWithName(name.first, name.second);
+        if (!root)
+        {
+            if (name_of_error)
+                *name_of_error = name.first;
+            return root;
+        }
+    }
+    return root;
+}
+
+lldb::ValueObjectSP
+ValueObject::GetChildAtNamePath (const std::vector< std::pair<ConstString, bool> > &names,
+                                 ConstString* name_of_error)
+{
+    if (names.size() == 0)
+        return GetSP();
+        ValueObjectSP root(GetSP());
+        for (std::pair<ConstString, bool> name : names)
+        {
+            root = root->GetChildMemberWithName(name.first, name.second);
+            if (!root)
+            {
+                if (name_of_error)
+                    *name_of_error = name.first;
+                    return root;
+            }
+        }
+    return root;
+}
+
 size_t
 ValueObject::GetIndexOfChildWithName (const ConstString &name)
 {

Modified: lldb/trunk/source/DataFormatters/FormatManager.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/DataFormatters/FormatManager.cpp?rev=190564&r1=190563&r2=190564&view=diff
==============================================================================
--- lldb/trunk/source/DataFormatters/FormatManager.cpp (original)
+++ lldb/trunk/source/DataFormatters/FormatManager.cpp Wed Sep 11 19:48:47 2013
@@ -632,7 +632,8 @@ FormatManager::LoadLibcxxFormatters()
     AddCXXSynthetic(libcxx_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::set synthetic children", ConstString("^std::__1::set<.+> >(( )?&)?$"), stl_synth_flags, true);
     AddCXXSynthetic(libcxx_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::multiset synthetic children", ConstString("^std::__1::multiset<.+> >(( )?&)?$"), stl_synth_flags, true);
     AddCXXSynthetic(libcxx_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::multimap synthetic children", ConstString("^std::__1::multimap<.+> >(( )?&)?$"), stl_synth_flags, true);
-
+    AddCXXSynthetic(libcxx_category_sp, lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEndCreator, "libc++ std::unordered containers synthetic children", ConstString("^(std::__1::)unordered_(multi)?(map|set)<.+> >$"), stl_synth_flags, true);
+    
     libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)deque<.+>(( )?&)?$")),
                                                           SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
                                                                                                     "lldb.formatters.cpp.libcxx.stddeque_SynthProvider")));
@@ -650,6 +651,7 @@ FormatManager::LoadLibcxxFormatters()
     AddCXXSummary(libcxx_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::set summary provider", ConstString("^std::__1::set<.+>(( )?&)?$"), stl_summary_flags, true);
     AddCXXSummary(libcxx_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::multiset summary provider", ConstString("^std::__1::multiset<.+>(( )?&)?$"), stl_summary_flags, true);
     AddCXXSummary(libcxx_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::multimap summary provider", ConstString("^std::__1::multimap<.+>(( )?&)?$"), stl_summary_flags, true);
+    AddCXXSummary(libcxx_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::unordered containers summary provider", ConstString("^(std::__1::)unordered_(multi)?(map|set)<.+> >$"), stl_summary_flags, true);
 
     stl_summary_flags.SetSkipPointers(true);
     AddStringSummary(libcxx_category_sp, "{${var.__ptr_%S}} (strong=${var.count} weak=${var.weak_count})}", ConstString("^std::__1::shared_ptr<.+>(( )?&)?$"), stl_summary_flags, true);

Added: lldb/trunk/source/DataFormatters/LibCxxUnorderedMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/DataFormatters/LibCxxUnorderedMap.cpp?rev=190564&view=auto
==============================================================================
--- lldb/trunk/source/DataFormatters/LibCxxUnorderedMap.cpp (added)
+++ lldb/trunk/source/DataFormatters/LibCxxUnorderedMap.cpp Wed Sep 11 19:48:47 2013
@@ -0,0 +1,135 @@
+//===-- LibCxxUnorderedMap.cpp -----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-python.h"
+
+#include "lldb/DataFormatters/CXXFormatterFunctions.h"
+
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Host/Endian.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::LibcxxStdUnorderedMapSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+SyntheticChildrenFrontEnd(*valobj_sp.get()),
+m_tree(NULL),
+m_num_elements(0),
+m_next_element(nullptr),
+m_children(),
+m_elements_cache()
+{
+    if (valobj_sp)
+        Update();
+}
+
+size_t
+lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::CalculateNumChildren ()
+{
+    if (m_num_elements != UINT32_MAX)
+        return m_num_elements;
+    return 0;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::GetChildAtIndex (size_t idx)
+{
+    if (idx >= CalculateNumChildren())
+        return lldb::ValueObjectSP();
+    if (m_tree == NULL)
+        return lldb::ValueObjectSP();
+    
+    auto cached = m_children.find(idx);
+    if (cached != m_children.end())
+        return cached->second;
+    
+    while (idx >= m_elements_cache.size())
+    {
+        if (m_next_element == nullptr)
+            return lldb::ValueObjectSP();
+        
+        Error error;
+        ValueObjectSP node_sp = m_next_element->Dereference(error);
+        if (!node_sp || error.Fail())
+            return lldb::ValueObjectSP();
+        
+        ValueObjectSP value_sp = node_sp->GetChildMemberWithName(ConstString("__value_"), true);
+        ValueObjectSP hash_sp = node_sp->GetChildMemberWithName(ConstString("__hash_"), true);
+        if (!hash_sp || !value_sp)
+            return lldb::ValueObjectSP();
+        m_elements_cache.push_back({value_sp.get(),hash_sp->GetValueAsUnsigned(0)});
+        m_next_element = node_sp->GetChildMemberWithName(ConstString("__next_"),true).get();
+        if (!m_next_element || m_next_element->GetValueAsUnsigned(0) == 0)
+            m_next_element = nullptr;
+    }
+    
+    std::pair<ValueObject*, uint64_t> val_hash = m_elements_cache[idx];
+    if (!val_hash.first)
+        return lldb::ValueObjectSP();
+    StreamString stream;
+    stream.Printf("[%zu]",idx);
+    DataExtractor data;
+    val_hash.first->GetData(data);
+    ExecutionContext exe_ctx = val_hash.first->GetExecutionContextRef().Lock();
+    return val_hash.first->CreateValueObjectFromData(stream.GetData(),
+                                                     data,
+                                                     exe_ctx,
+                                                     val_hash.first->GetClangType());
+}
+
+bool
+lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::Update()
+{
+    m_num_elements = UINT32_MAX;
+    m_next_element = nullptr;
+    m_elements_cache.clear();
+    m_children.clear();
+    ValueObjectSP table_sp = m_backend.GetChildMemberWithName(ConstString("__table_"), true);
+    if (!table_sp)
+        return false;
+    ValueObjectSP num_elements_sp = table_sp->GetChildAtNamePath({ConstString("__p2_"),ConstString("__first_")});
+    if (!num_elements_sp)
+        return false;
+    m_num_elements = num_elements_sp->GetValueAsUnsigned(0);
+    m_tree = table_sp->GetChildAtNamePath({ConstString("__p1_"),ConstString("__first_"),ConstString("__next_")}).get();
+    if (m_num_elements > 0)
+        m_next_element = table_sp->GetChildAtNamePath({ConstString("__p1_"),ConstString("__first_"),ConstString("__next_")}).get();
+    return false;
+}
+
+bool
+lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::MightHaveChildren ()
+{
+    return true;
+}
+
+size_t
+lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+    return ExtractIndexFromString(name.GetCString());
+}
+
+lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::~LibcxxStdUnorderedMapSyntheticFrontEnd ()
+{}
+
+SyntheticChildrenFrontEnd*
+lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
+{
+    if (!valobj_sp)
+        return NULL;
+    return (new LibcxxStdUnorderedMapSyntheticFrontEnd(valobj_sp));
+}

Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/Makefile?rev=190564&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/Makefile (added)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/Makefile Wed Sep 11 19:48:47 2013
@@ -0,0 +1,8 @@
+LEVEL = ../../../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
+
+CXXFLAGS += -stdlib=libc++ -O0 -std=c++11
+LDFLAGS += -stdlib=libc++
\ No newline at end of file

Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/TestDataFormatterUnordered.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/TestDataFormatterUnordered.py?rev=190564&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/TestDataFormatterUnordered.py (added)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/TestDataFormatterUnordered.py Wed Sep 11 19:48:47 2013
@@ -0,0 +1,75 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+import lldbutil
+
+class LibcxxMultiMapDataFormatterTestCase(TestBase):
+
+    mydir = os.path.join("functionalities", "data-formatter", "data-formatter-stl", "libcxx", "unordered")
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @dsym_test
+    def test_with_dsym_and_run_command(self):
+        """Test data formatter commands."""
+        self.buildDsym()
+        self.data_formatter_commands()
+
+    @skipIfLinux # No standard locations for libc++ on Linux, so skip for now 
+    @dwarf_test
+    def test_with_dwarf_and_run_command(self):
+        """Test data formatter commands."""
+        self.buildDwarf()
+        self.data_formatter_commands()
+
+    def setUp(self):
+        # Call super's setUp().
+        TestBase.setUp(self)
+
+    def look_for_content_and_continue(self,var_name,substrs):
+        self.expect( ("frame variable %s" % var_name), substrs )
+        self.runCmd("continue")
+
+    def data_formatter_commands(self):
+        """Test that that file and class static variables display correctly."""
+        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+        lldbutil.run_break_set_by_source_regexp (self, "Set break point at this line.")
+
+        self.runCmd("run", RUN_SUCCEEDED)
+
+        # The stop reason of the thread should be breakpoint.
+        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+            substrs = ['stopped',
+                       'stop reason = breakpoint'])
+
+        # This is the function to remove the custom formats in order to have a
+        # clean slate for the next test case.
+        def cleanup():
+            self.runCmd('type format clear', check=False)
+            self.runCmd('type summary clear', check=False)
+            self.runCmd('type filter clear', check=False)
+            self.runCmd('type synth clear', check=False)
+            self.runCmd("settings set target.max-children-count 256", check=False)
+
+        # Execute the cleanup function during test case tear down.
+        self.addTearDownHook(cleanup)
+
+        self.expect('image list', substrs = self.getLibcPlusPlusLibs())
+
+        self.look_for_content_and_continue("map",['size=5 {,''hello','world','this','is','me'])
+        self.look_for_content_and_continue("mmap",['size=6 {','first = 3','second = "this"','first = 2','second = "hello"'])
+        self.look_for_content_and_continue("iset",['size=5 {','[0] = 5','[2] = 3','[3] = 2'])
+        self.look_for_content_and_continue("sset",['size=5 {','[0] = "is"','[1] = "world"','[4] = "hello"'])
+        self.look_for_content_and_continue("imset",['size=6 {','[0] = 3','[1] = 3','[2] = 3','[4] = 2','[5] = 1'])
+        self.look_for_content_and_continue("smset",['size=5 {','[0] = "is"','[1] = "is"','[2] = "world"','[3] = "world"'])
+
+if __name__ == '__main__':
+    import atexit
+    lldb.SBDebugger.Initialize()
+    atexit.register(lambda: lldb.SBDebugger.Terminate())
+    unittest2.main()

Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/main.cpp?rev=190564&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/main.cpp (added)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-stl/libcxx/unordered/main.cpp Wed Sep 11 19:48:47 2013
@@ -0,0 +1,84 @@
+#include <string>
+#ifdef _LIBCPP_INLINE_VISIBILITY
+#undef _LIBCPP_INLINE_VISIBILITY
+#endif
+#define _LIBCPP_INLINE_VISIBILITY
+#include <unordered_map>
+#include <unordered_set>
+
+using std::string;
+
+#define intstr_map std::unordered_map<int, string> 
+#define intstr_mmap std::unordered_multimap<int, string> 
+
+#define int_set std::unordered_set<int> 
+#define str_set std::unordered_set<string> 
+#define int_mset std::unordered_multiset<int> 
+#define str_mset std::unordered_multiset<string> 
+
+int g_the_foo = 0;
+
+int thefoo_rw(int arg = 1)
+{
+	if (arg < 0)
+		arg = 0;
+	if (!arg)
+		arg = 1;
+	g_the_foo += arg;
+	return g_the_foo;
+}
+
+int main()
+{
+	intstr_map map;
+	map.emplace(1,"hello");
+	map.emplace(2,"world");
+	map.emplace(3,"this");
+	map.emplace(4,"is");
+	map.emplace(5,"me");
+	thefoo_rw();  // Set break point at this line.
+	
+	intstr_mmap mmap;
+	mmap.emplace(1,"hello");
+	mmap.emplace(2,"hello");
+	mmap.emplace(2,"world");
+	mmap.emplace(3,"this");
+	mmap.emplace(3,"this");
+	mmap.emplace(3,"this");
+	thefoo_rw();  // Set break point at this line.
+	
+	int_set iset;
+	iset.emplace(1);
+	iset.emplace(2);
+	iset.emplace(3);
+	iset.emplace(4);
+	iset.emplace(5);
+	thefoo_rw();  // Set break point at this line.
+	
+	str_set sset;
+	sset.emplace("hello");
+	sset.emplace("world");
+	sset.emplace("this");
+	sset.emplace("is");
+	sset.emplace("me");
+	thefoo_rw();  // Set break point at this line.
+	
+	int_mset imset;
+	imset.emplace(1);
+	imset.emplace(2);
+	imset.emplace(2);
+	imset.emplace(3);
+	imset.emplace(3);
+	imset.emplace(3);
+	thefoo_rw();  // Set break point at this line.
+	
+	str_mset smset;
+	smset.emplace("hello");
+	smset.emplace("world");
+	smset.emplace("world");
+	smset.emplace("is");
+	smset.emplace("is");
+	thefoo_rw();  // Set break point at this line.
+	
+    return 0;
+}
\ No newline at end of file





More information about the lldb-commits mailing list