diff --git a/lldb/examples/synthetic/gnu_libstdcpp.py b/lldb/examples/synthetic/gnu_libstdcpp.py --- a/lldb/examples/synthetic/gnu_libstdcpp.py +++ b/lldb/examples/synthetic/gnu_libstdcpp.py @@ -7,6 +7,94 @@ # as it ships with Mac OS X 10.6.8 thru 10.8.0 # You are encouraged to look at the STL implementation for your platform # before relying on these formatters to do the right thing for your setup +class StdUnorderedMapSynthProvider: + def __init__(self, valobj, dict): + self.valobj = valobj + self.count = None + + def extract_type(self): + logger = lldb.formatters.Logger.Logger() + list_type = self.valobj.GetType().GetUnqualifiedType() + if list_type.IsReferenceType(): + list_type = list_type.GetDereferencedType() + if list_type.GetNumberOfTemplateArguments() > 0: + data_type = list_type.GetTemplateArgumentType(0) + else: + data_type = None + return data_type + + def update(self): + logger = lldb.formatters.Logger.Logger() + # preemptively setting this to None - we might end up changing our mind + # later + self.count = None + try: + self.head = self.valobj.GetChildMemberWithName('_M_h') + self.before_begin = self.head.GetChildMemberWithName('_M_before_begin') + self.next = self.before_begin.GetChildMemberWithName('_M_nxt') + self.data_type = self.extract_type() + self.skip_size = self.head.GetType().GetByteSize() + logger >> "Data type is this: " + str(self.data_type) + self.data_size = self.data_type.GetByteSize() + except: + pass + return False + + def get_child_index(self, name): + logger = lldb.formatters.Logger.Logger() + try: + return int(name.lstrip('[').rstrip(']')) + except: + return -1 + + def get_child_key(self, index): + try: + logger = lldb.formatters.Logger.Logger() + offset = self.count - index - 1 + current = self.next + while offset > 0: + current = current.GetChildMemberWithName('_M_nxt') + offset = offset - 1 + return current.CreateChildAtOffset('[' + str(index) + ']', self.next.GetType().GetByteSize(), self.data_type) + except: + logger >> "Error in get_child_key" + return None + + def get_child_at_index(self, index): + logger = lldb.formatters.Logger.Logger() + logger >> "Being asked to fetch child[" + str(index) + "]" + if index < 0: + return None + if index >= self.num_children(): + return None + try: + offset = self.count - index - 1 + current = self.next + while offset > 0: + current = current.GetChildMemberWithName('_M_nxt') + offset = offset - 1 + key = self.get_child_key(index) + return current.CreateChildAtOffset('[' + str(key.GetValue()) + ']', self.next.GetType().GetByteSize() + 9, self.data_type) + + except: + logger >> "Error in get_child_at_index" + return None + + def num_children(self): + logger = lldb.formatters.Logger.Logger() + if self.count is None: + self.count = self.num_children_impl() + return self.count + + def num_children_impl(self): + logger = lldb.formatters.Logger.Logger() + try: + count = self.head.GetChildMemberWithName('_M_element_count').GetValueAsUnsigned(0) + logger >> "I have " + str(count) + " children available" + return count + except: + logger >> "Could not determine the size" + return 0 class StdListSynthProvider: diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -918,6 +918,11 @@ SyntheticChildrenSP(new ScriptedSyntheticChildren( stl_deref_flags, "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider"))); + cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add( + RegularExpression("^std::unordered_(multi)?(map|set)<.+> >$"), + SyntheticChildrenSP(new ScriptedSyntheticChildren( + stl_deref_flags, + "lldb.formatters.cpp.gnu_libstdcpp.StdUnorderedMapSynthProvider"))); cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add( RegularExpression("^std::(__cxx11::)?list<.+>(( )?&)?$"), SyntheticChildrenSP(new ScriptedSyntheticChildren( @@ -949,6 +954,10 @@ RegularExpression("^std::multiset<.+> >(( )?&)?$"), TypeSummaryImplSP( new StringSummaryFormat(stl_summary_flags, "size=${svar%#}"))); + cpp_category_sp->GetRegexTypeSummariesContainer()->Add( + RegularExpression("^std::unordered_(multi)?(map|set)<.+> >$"), + TypeSummaryImplSP( + new StringSummaryFormat(stl_summary_flags, "size=${svar%#}"))); cpp_category_sp->GetRegexTypeSummariesContainer()->Add( RegularExpression("^std::(__cxx11::)?list<.+>(( )?&)?$"), TypeSummaryImplSP(