<div dir="ltr">+list in case anyone else is curious<br><br><div class="gmail_quote"><div dir="ltr">On Wed, Nov 18, 2015 at 11:34 AM Zachary Turner <<a href="mailto:zturner@google.com">zturner@google.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Can you roll your head back to r253448, apply this patch on top and see if it works?  If so feel free to resubmit your patch and then these changes on top.<div><br></div><div>Sadly this is in fact a bug in the compiler's support for Expression SFINAE.  The most reasonable workaround we could come up with is to not use the name Set() for both the Regex and the Exact match case.  So I've renamed them to SetExact() and SetWithRegex().  This allows the enable-if's to work correctly.</div></div><div dir="ltr"><div><br><div><div><br></div><div><br></div><br><div class="gmail_quote"><div dir="ltr">On Wed, Nov 18, 2015 at 11:07 AM Enrico Granata <<a href="mailto:egranata@apple.com" target="_blank">egranata@apple.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div>Much appreciated, thanks :-)</div></div><div style="word-wrap:break-word"><br><div><blockquote type="cite"><div>On Nov 18, 2015, at 10:40 AM, Zachary Turner <<a href="mailto:zturner@google.com" target="_blank">zturner@google.com</a>> wrote:</div><br><div><div dir="ltr">I'll take a look</div><br><div class="gmail_quote"><div dir="ltr">On Wed, Nov 18, 2015 at 10:21 AM Enrico Granata <<a href="mailto:egranata@apple.com" target="_blank">egranata@apple.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div>This smells like compiler bug:</div><div><pre style="font-family:'Courier New',courier,monotype,monospace"><span>trying to match the argument list '(bool (__cdecl *)(lldb_private::ConstString,const lldb_private::TypeFormatImpl::SharedPointer &))'</span></pre><div>it fails saying this could be a candidate:</div></div><div><pre style="font-family:'Courier New',courier,monotype,monospace"><span>        c:\lldbSlave\lldb-win7-android\llvm\tools\lldb\include\lldb/DataFormatters/TypeCategory.h(122): or       'lldb_private::TypeCategoryImpl::ForEachCallbacks<FormatterType> &lldb_private::TypeCategoryImpl::ForEachCallbacks<FormatterType>::Set<lldb_private::TypeFormatImpl>(std::function<bool (KeyType,const std::shared_ptr<lldb_private::TypeFormatImpl> &)>)'
        with
        [
            FormatterType=lldb_private::TypeFormatImpl
,            KeyType=lldb_private::ConstString
        ]
</span></pre></div><div><span>(hint: it is)</span></div><div><span><br></span></div><div><span>or else this one is also a candidate:</span></div><div><span><pre style="font-family:'Courier New',courier,monotype,monospace"><span>        c:\lldbSlave\lldb-win7-android\llvm\tools\lldb\include\lldb/DataFormatters/TypeCategory.h(129): could be 'lldb_private::TypeCategoryImpl::ForEachCallbacks<FormatterType> &lldb_private::TypeCategoryImpl::ForEachCallbacks<FormatterType>::Set<lldb_private::TypeFormatImpl>(std::function<bool (KeyType,const std::shared_ptr<lldb_private::TypeFormatImpl> &)>)'
        with
        [
            FormatterType=lldb_private::TypeFormatImpl
,            KeyType=lldb::RegularExpressionSP
        ]
</span></pre><div>which seems highly unlikely given that there is nothing in common between ConstString and RegularExpressionSP</div><div><br></div><div>With that said, since I do want to get this code in, is it possible to get someone on the Windows side to help me clean up in such a way that it works on MSVC?</div><div>I would do the dance myself, but I don’t have a Windows install handy</div></span></div></div><div style="word-wrap:break-word"><br><div><blockquote type="cite"><div>On Nov 18, 2015, at 4:14 AM, Tamas Berghammer <<a href="mailto:tberghammer@google.com" target="_blank">tberghammer@google.com</a>> wrote:</div><br><div><div dir="ltr">Hi Enrico,<div><br></div><div>I reverted this CL and the follow-up one (r<span style="font-size:13px;line-height:19.5px">253424) as they are breaking the Windows build. For the error message please see </span><span style="line-height:19.5px"><a href="http://lab.llvm.org:8011/builders/lldb-windows7-android/builds/2781" target="_blank">http://lab.llvm.org:8011/builders/lldb-windows7-android/builds/2781</a></span></div><div><br></div><div>Tamas</div><br><div class="gmail_quote"><div dir="ltr">On Wed, Nov 18, 2015 at 1:40 AM Enrico Granata via lldb-commits <<a href="mailto:lldb-commits@lists.llvm.org" target="_blank">lldb-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: enrico<br>
Date: Tue Nov 17 19:37:49 2015<br>
New Revision: 253423<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=253423&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=253423&view=rev</a><br>
Log:<br>
Cleanup the type X list commands to use the new ForEach goodness<br>
<br>
<br>
Modified:<br>
    lldb/trunk/include/lldb/DataFormatters/DataVisualization.h<br>
    lldb/trunk/include/lldb/DataFormatters/FormatManager.h<br>
    lldb/trunk/include/lldb/DataFormatters/FormattersContainer.h<br>
    lldb/trunk/include/lldb/DataFormatters/TypeCategory.h<br>
    lldb/trunk/include/lldb/DataFormatters/TypeCategoryMap.h<br>
    lldb/trunk/include/lldb/DataFormatters/TypeSynthetic.h<br>
    lldb/trunk/source/API/SBTypeCategory.cpp<br>
    lldb/trunk/source/Commands/CommandObjectType.cpp<br>
    lldb/trunk/source/DataFormatters/DataVisualization.cpp<br>
    lldb/trunk/source/DataFormatters/FormatManager.cpp<br>
    lldb/trunk/source/DataFormatters/TypeCategoryMap.cpp<br>
<br>
Modified: lldb/trunk/include/lldb/DataFormatters/DataVisualization.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/DataVisualization.h?rev=253423&r1=253422&r2=253423&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/DataVisualization.h?rev=253423&r1=253422&r2=253423&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/include/lldb/DataFormatters/DataVisualization.h (original)<br>
+++ lldb/trunk/include/lldb/DataFormatters/DataVisualization.h Tue Nov 17 19:37:49 2015<br>
@@ -101,7 +101,7 @@ public:<br>
         Clear ();<br>
<br>
         static void<br>
-        LoopThrough (TypeSummaryImpl::SummaryCallback callback, void* callback_baton);<br>
+        ForEach (std::function<bool(ConstString, const lldb::TypeSummaryImplSP&)> callback);<br>
<br>
         static uint32_t<br>
         GetCount ();<br>
@@ -158,9 +158,6 @@ public:<br>
         DisableStar ();<br>
<br>
         static void<br>
-        LoopThrough (FormatManager::CategoryCallback callback, void* callback_baton);<br>
-<br>
-        static void<br>
         ForEach (TypeCategoryMap::ForEachCallback callback);<br>
<br>
         static uint32_t<br>
<br>
Modified: lldb/trunk/include/lldb/DataFormatters/FormatManager.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/FormatManager.h?rev=253423&r1=253422&r2=253423&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/FormatManager.h?rev=253423&r1=253422&r2=253423&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/include/lldb/DataFormatters/FormatManager.h (original)<br>
+++ lldb/trunk/include/lldb/DataFormatters/FormatManager.h Tue Nov 17 19:37:49 2015<br>
@@ -140,9 +140,6 @@ public:<br>
     }<br>
<br>
     void<br>
-    LoopThroughCategories (CategoryCallback callback, void* param);<br>
-<br>
-    void<br>
     ForEachCategory (TypeCategoryMap::ForEachCallback callback);<br>
<br>
     lldb::TypeCategoryImplSP<br>
<br>
Modified: lldb/trunk/include/lldb/DataFormatters/FormattersContainer.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/FormattersContainer.h?rev=253423&r1=253422&r2=253423&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/FormattersContainer.h?rev=253423&r1=253422&r2=253423&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/include/lldb/DataFormatters/FormattersContainer.h (original)<br>
+++ lldb/trunk/include/lldb/DataFormatters/FormattersContainer.h Tue Nov 17 19:37:49 2015<br>
@@ -141,22 +141,6 @@ public:<br>
     }<br>
<br>
     void<br>
-    LoopThrough (CallbackType callback, void* param)<br>
-    {<br>
-        if (callback)<br>
-        {<br>
-            Mutex::Locker locker(m_map_mutex);<br>
-            MapIterator pos, end = m_map.end();<br>
-            for (pos = m_map.begin(); pos != end; pos++)<br>
-            {<br>
-                KeyType type = pos->first;<br>
-                if (!callback(param, type, pos->second))<br>
-                    break;<br>
-            }<br>
-        }<br>
-    }<br>
-<br>
-    void<br>
     ForEach (ForEachCallback callback)<br>
     {<br>
         if (callback)<br>
@@ -316,12 +300,6 @@ public:<br>
     }<br>
<br>
     void<br>
-    LoopThrough (CallbackType callback, void* param)<br>
-    {<br>
-        m_format_map.LoopThrough(callback,param);<br>
-    }<br>
-<br>
-    void<br>
     ForEach (ForEachCallback callback)<br>
     {<br>
         m_format_map.ForEach(callback);<br>
<br>
Modified: lldb/trunk/include/lldb/DataFormatters/TypeCategory.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/TypeCategory.h?rev=253423&r1=253422&r2=253423&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/TypeCategory.h?rev=253423&r1=253422&r2=253423&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/include/lldb/DataFormatters/TypeCategory.h (original)<br>
+++ lldb/trunk/include/lldb/DataFormatters/TypeCategory.h Tue Nov 17 19:37:49 2015<br>
@@ -67,14 +67,6 @@ namespace lldb_private {<br>
             return m_regex_sp;<br>
         }<br>
<br>
-        void<br>
-        LoopThrough (typename ExactMatchContainer::CallbackType exact_callback,<br>
-                     typename RegexMatchContainer::CallbackType regex_callback)<br>
-        {<br>
-            GetExactMatch()->LoopThrough(exact_callback);<br>
-            GetRegexMatch()->LoopThrough(regex_callback);<br>
-        }<br>
-<br>
         uint32_t<br>
         GetCount ()<br>
         {<br>
@@ -95,7 +87,7 @@ namespace lldb_private {<br>
         typedef FormatterContainerPair<TypeValidatorImpl> ValidatorContainer;<br>
<br>
 #ifndef LLDB_DISABLE_PYTHON<br>
-        typedef FormatterContainerPair<ScriptedSyntheticChildren> SynthContainer;<br>
+        typedef FormatterContainerPair<SyntheticChildren> SynthContainer;<br>
 #endif // LLDB_DISABLE_PYTHON<br>
<br>
     public:<br>
@@ -118,74 +110,84 @@ namespace lldb_private {<br>
         typedef ValidatorContainer::ExactMatchContainerSP ValidatorContainerSP;<br>
         typedef ValidatorContainer::RegexMatchContainerSP RegexValidatorContainerSP;<br>
<br>
-        class ForEach<br>
+        template <typename T><br>
+        class ForEachCallbacks<br>
         {<br>
         public:<br>
-            ForEach () = default;<br>
-            ~ForEach () = default;<br>
+            ForEachCallbacks () = default;<br>
+            ~ForEachCallbacks () = default;<br>
<br>
-            ForEach&<br>
-            SetFormatExactCallback (FormatContainer::ExactMatchForEachCallback callback)<br>
+            template<typename U = TypeFormatImpl><br>
+            typename std::enable_if<std::is_same<U,T>::value, ForEachCallbacks&>::type<br>
+            Set (FormatContainer::ExactMatchForEachCallback callback)<br>
             {<br>
                 m_format_exact = callback;<br>
                 return *this;<br>
             }<br>
-            ForEach&<br>
-            SetFormatRegexCallback (FormatContainer::RegexMatchForEachCallback callback)<br>
+            template<typename U = TypeFormatImpl><br>
+            typename std::enable_if<std::is_same<U,T>::value, ForEachCallbacks&>::type<br>
+            Set (FormatContainer::RegexMatchForEachCallback callback)<br>
             {<br>
                 m_format_regex = callback;<br>
                 return *this;<br>
             }<br>
<br>
-            ForEach&<br>
-            SetSummaryExactCallback (SummaryContainer::ExactMatchForEachCallback callback)<br>
+            template<typename U = TypeSummaryImpl><br>
+            typename std::enable_if<std::is_same<U,T>::value, ForEachCallbacks&>::type<br>
+            Set (SummaryContainer::ExactMatchForEachCallback callback)<br>
             {<br>
                 m_summary_exact = callback;<br>
                 return *this;<br>
             }<br>
-            ForEach&<br>
-            SetSummaryRegexCallback (SummaryContainer::RegexMatchForEachCallback callback)<br>
+            template<typename U = TypeSummaryImpl><br>
+            typename std::enable_if<std::is_same<U,T>::value, ForEachCallbacks&>::type<br>
+            Set (SummaryContainer::RegexMatchForEachCallback callback)<br>
             {<br>
                 m_summary_regex = callback;<br>
                 return *this;<br>
             }<br>
<br>
-            ForEach&<br>
-            SetFilterExactCallback (FilterContainer::ExactMatchForEachCallback callback)<br>
+            template<typename U = TypeFilterImpl><br>
+            typename std::enable_if<std::is_same<U,T>::value, ForEachCallbacks&>::type<br>
+            Set (FilterContainer::ExactMatchForEachCallback callback)<br>
             {<br>
                 m_filter_exact = callback;<br>
                 return *this;<br>
             }<br>
-            ForEach&<br>
-            SetFilterRegexCallback (FilterContainer::RegexMatchForEachCallback callback)<br>
+            template<typename U = TypeFilterImpl><br>
+            typename std::enable_if<std::is_same<U,T>::value, ForEachCallbacks&>::type<br>
+            Set (FilterContainer::RegexMatchForEachCallback callback)<br>
             {<br>
                 m_filter_regex = callback;<br>
                 return *this;<br>
             }<br>
<br>
 #ifndef LLDB_DISABLE_PYTHON<br>
-            ForEach&<br>
-            SetSynthExactCallback (SynthContainer::ExactMatchForEachCallback callback)<br>
+            template<typename U = SyntheticChildren><br>
+            typename std::enable_if<std::is_same<U,T>::value, ForEachCallbacks&>::type<br>
+            Set (SynthContainer::ExactMatchForEachCallback callback)<br>
             {<br>
                 m_synth_exact = callback;<br>
                 return *this;<br>
             }<br>
-            ForEach&<br>
-            SetSynthRegexCallback (SynthContainer::RegexMatchForEachCallback callback)<br>
+            template<typename U = SyntheticChildren><br>
+            typename std::enable_if<std::is_same<U,T>::value, ForEachCallbacks&>::type<br>
+            Set (SynthContainer::RegexMatchForEachCallback callback)<br>
             {<br>
                 m_synth_regex = callback;<br>
                 return *this;<br>
             }<br>
 #endif // LLDB_DISABLE_PYTHON<br>
-<br>
-            ForEach&<br>
-            SetValidatorExactCallback (ValidatorContainer::ExactMatchForEachCallback callback)<br>
+            template<typename U = TypeValidatorImpl><br>
+            typename std::enable_if<std::is_same<U,T>::value, ForEachCallbacks&>::type<br>
+            Set (ValidatorContainer::ExactMatchForEachCallback callback)<br>
             {<br>
                 m_validator_exact = callback;<br>
                 return *this;<br>
             }<br>
-            ForEach&<br>
-            SetValidatorRegexCallback (ValidatorContainer::RegexMatchForEachCallback callback)<br>
+            template<typename U = TypeValidatorImpl><br>
+            typename std::enable_if<std::is_same<U,T>::value, ForEachCallbacks&>::type<br>
+            Set (ValidatorContainer::RegexMatchForEachCallback callback)<br>
             {<br>
                 m_validator_regex = callback;<br>
                 return *this;<br>
@@ -271,8 +273,9 @@ namespace lldb_private {<br>
                           ConstString name,<br>
                           std::initializer_list<lldb::LanguageType> langs = {});<br>
<br>
+        template <typename T><br>
         void<br>
-        ForEach (const ForEach &foreach)<br>
+        ForEach (const ForEachCallbacks<T> &foreach)<br>
         {<br>
             GetTypeFormatsContainer()->ForEach(foreach.GetFormatExactCallback());<br>
             GetRegexTypeFormatsContainer()->ForEach(foreach.GetFormatRegexCallback());<br>
<br>
Modified: lldb/trunk/include/lldb/DataFormatters/TypeCategoryMap.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/TypeCategoryMap.h?rev=253423&r1=253422&r2=253423&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/TypeCategoryMap.h?rev=253423&r1=253422&r2=253423&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/include/lldb/DataFormatters/TypeCategoryMap.h (original)<br>
+++ lldb/trunk/include/lldb/DataFormatters/TypeCategoryMap.h Tue Nov 17 19:37:49 2015<br>
@@ -88,9 +88,6 @@ namespace lldb_private {<br>
              ValueSP& entry);<br>
<br>
         void<br>
-        LoopThrough (CallbackType callback, void* param);<br>
-<br>
-        void<br>
         ForEach (ForEachCallback callback);<br>
<br>
         lldb::TypeCategoryImplSP<br>
<br>
Modified: lldb/trunk/include/lldb/DataFormatters/TypeSynthetic.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/TypeSynthetic.h?rev=253423&r1=253422&r2=253423&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/TypeSynthetic.h?rev=253423&r1=253422&r2=253423&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/include/lldb/DataFormatters/TypeSynthetic.h (original)<br>
+++ lldb/trunk/include/lldb/DataFormatters/TypeSynthetic.h Tue Nov 17 19:37:49 2015<br>
@@ -479,6 +479,8 @@ namespace lldb_private {<br>
             return SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(this, backend));<br>
         }<br>
<br>
+        typedef std::shared_ptr<TypeFilterImpl> SharedPointer;<br>
+<br>
     private:<br>
         DISALLOW_COPY_AND_ASSIGN(TypeFilterImpl);<br>
     };<br>
<br>
Modified: lldb/trunk/source/API/SBTypeCategory.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBTypeCategory.cpp?rev=253423&r1=253422&r2=253423&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBTypeCategory.cpp?rev=253423&r1=253422&r2=253423&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/source/API/SBTypeCategory.cpp (original)<br>
+++ lldb/trunk/source/API/SBTypeCategory.cpp Tue Nov 17 19:37:49 2015<br>
@@ -180,7 +180,7 @@ SBTypeCategory::GetFilterForType (SBType<br>
     if (!spec.IsValid())<br>
         return SBTypeFilter();<br>
<br>
-    lldb::SyntheticChildrenSP children_sp;<br>
+    lldb::TypeFilterImplSP children_sp;<br>
<br>
     if (spec.IsRegex())<br>
         m_opaque_sp->GetRegexTypeFiltersContainer()->GetExact(ConstString(spec.GetName()), children_sp);<br>
<br>
Modified: lldb/trunk/source/Commands/CommandObjectType.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectType.cpp?rev=253423&r1=253422&r2=253423&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectType.cpp?rev=253423&r1=253422&r2=253423&view=diff</a><br>
==============================================================================<br>
--- lldb/trunk/source/Commands/CommandObjectType.cpp (original)<br>
+++ lldb/trunk/source/Commands/CommandObjectType.cpp Tue Nov 17 19:37:49 2015<br>
@@ -1089,13 +1089,6 @@ CommandObjectTypeFormatterDelete::Comman<br>
     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }<br>
 };<br>
<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
-<br>
 class CommandObjectTypeFormatterClear : public CommandObjectParsed<br>
 {<br>
 private:<br>
@@ -1224,10 +1217,6 @@ CommandObjectTypeFormatterClear::Command<br>
     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }<br>
 };<br>
<br>
-<br>
-<br>
-<br>
-<br>
 //-------------------------------------------------------------------------<br>
 // CommandObjectTypeFormatDelete<br>
 //-------------------------------------------------------------------------<br>
@@ -1264,25 +1253,8 @@ public:<br>
     }<br>
 };<br>
<br>
-//-------------------------------------------------------------------------<br>
-// CommandObjectTypeFormatList<br>
-//-------------------------------------------------------------------------<br>
-<br>
-bool CommandObjectTypeFormatList_LoopCallback(void* pt2self, ConstString type, const lldb::TypeFormatImplSP& entry);<br>
-bool CommandObjectTypeRXFormatList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const lldb::TypeFormatImplSP& entry);<br>
-<br>
-class CommandObjectTypeFormatList;<br>
-<br>
-struct CommandObjectTypeFormatList_LoopCallbackParam {<br>
-    CommandObjectTypeFormatList* self;<br>
-    CommandReturnObject* result;<br>
-    RegularExpression* regex;<br>
-    RegularExpression* cate_regex;<br>
-    CommandObjectTypeFormatList_LoopCallbackParam(CommandObjectTypeFormatList* S, CommandReturnObject* R,<br>
-                                            RegularExpression* X = NULL, RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {}<br>
-};<br>
-<br>
-class CommandObjectTypeFormatList : public CommandObjectParsed<br>
+template <typename FormatterType><br>
+class CommandObjectTypeFormatterList : public CommandObjectParsed<br>
 {<br>
     class CommandOptions : public Options<br>
     {<br>
@@ -1323,6 +1295,12 @@ class CommandObjectTypeFormatList : publ<br>
         const OptionDefinition*<br>
         GetDefinitions () override<br>
         {<br>
+            static OptionDefinition g_option_table[] =<br>
+            {<br>
+                { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,  "Only show categories matching this filter."},<br>
+                { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }<br>
+            };<br>
+<br>
             return g_option_table;<br>
         }<br>
<br>
@@ -1345,10 +1323,12 @@ class CommandObjectTypeFormatList : publ<br>
     }<br>
<br>
 public:<br>
-    CommandObjectTypeFormatList (CommandInterpreter &interpreter) :<br>
+    CommandObjectTypeFormatterList (CommandInterpreter &interpreter,<br>
+                                    const char* name,<br>
+                                    const char* help) :<br>
         CommandObjectParsed (interpreter,<br>
-                             "type format list",<br>
-                             "Show a list of current formatting styles.",<br>
+                             name,<br>
+                             help,<br>
                              NULL),<br>
     m_options(interpreter)<br>
     {<br>
@@ -1363,115 +1343,137 @@ public:<br>
         m_arguments.push_back (type_arg);<br>
     }<br>
<br>
-    ~CommandObjectTypeFormatList () override<br>
+    ~CommandObjectTypeFormatterList () override<br>
     {<br>
     }<br>
<br>
 protected:<br>
+    virtual void<br>
+    FormatterSpecificList (CommandReturnObject &result)<br>
+    {<br>
+    }<br>
+<br>
     bool<br>
     DoExecute (Args& command, CommandReturnObject &result) override<br>
     {<br>
         const size_t argc = command.GetArgumentCount();<br>
<br>
-        CommandObjectTypeFormatList_LoopCallbackParam *param;<br>
-        RegularExpression* cate_regex =<br>
-        m_options.m_category_regex.empty() ? NULL :<br>
-        new RegularExpression(m_options.m_category_regex.c_str());<br>
+        std::unique_ptr<RegularExpression> category_regex;<br>
+        std::unique_ptr<RegularExpression> formatter_regex;<br>
+<br>
+        if (m_options.m_category_regex.size() > 0)<br>
+        {<br>
+            category_regex.reset(new RegularExpression());<br>
+            if (!category_regex->Compile(m_options.m_category_regex.c_str()))<br>
+            {<br>
+                result.AppendErrorWithFormat("syntax error in category regular expression '%s'", m_options.m_category_regex.c_str());<br>
+                result.SetStatus(eReturnStatusFailed);<br>
+                return false;<br>
+            }<br>
+        }<br>
<br>
         if (argc == 1)<br>
         {<br>
-            RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));<br>
-            regex->Compile(command.GetArgumentAtIndex(0));<br>
-            param = new CommandObjectTypeFormatList_LoopCallbackParam(this,&result,regex,cate_regex);<br>
+            const char* arg = command.GetArgumentAtIndex(1);<br>
+            formatter_regex.reset(new RegularExpression());<br>
+            if (!formatter_regex->Compile(arg))<br>
+            {<br>
+                result.AppendErrorWithFormat("syntax error in regular expression '%s'", arg);<br>
+                result.SetStatus(eReturnStatusFailed);<br>
+                return false;<br>
+            }<br>
         }<br>
-        else<br>
-            param = new CommandObjectTypeFormatList_LoopCallbackParam(this,&result,NULL,cate_regex);<br>
<br>
-        DataVisualization::Categories::LoopThrough(PerCategoryCallback,param);<br>
-        delete param;<br>
+        DataVisualization::Categories::ForEach( [this, &command, &result, &category_regex, &formatter_regex] (const lldb::TypeCategoryImplSP& category) -> bool {<br>
+            if (category_regex)<br>
+            {<br>
+                bool escape = true;<br>
+                if (0 == strcmp(category->GetName(), category_regex->GetText()))<br>
+                {<br>
+                    escape = false;<br>
+                }<br>
+                else if (category_regex->Execute(category->GetName()))<br>
+                {<br>
+                    escape = false;<br>
+                }<br>
+<br>
+                if (escape)<br>
+                    return true;<br>
+            }<br>
+<br>
+            result.GetOutputStream().Printf("-----------------------\nCategory: %s\n-----------------------\n", category->GetName());<br>
+<br>
+            TypeCategoryImpl::ForEachCallbacks<FormatterType> foreach;<br>
+            foreach.Set( [&result, &formatter_regex] (ConstString name, const typename FormatterType::SharedPointer& format_sp) -> bool {<br>
+                if (formatter_regex)<br>
+                {<br>
+                    bool escape = true;<br>
+                    if (0 == strcmp(name.AsCString(), formatter_regex->GetText()))<br>
+                    {<br>
+                        escape = false;<br>
+                    }<br>
+                    else if (formatter_regex->Execute(name.AsCString()))<br>
+                    {<br>
+                        escape = false;<br>
+                    }<br>
+<br>
+                    if (escape)<br>
+                        return true;<br>
+                }<br>
+<br>
+                result.GetOutputStream().Printf ("%s: %s\n", name.AsCString(), format_sp->GetDescription().c_str());<br>
+<br>
+                return true;<br>
+            });<br>
+<br>
+            foreach.Set( [&result, &formatter_regex] (RegularExpressionSP regex_sp, const typename FormatterType::SharedPointer& format_sp) -> bool {<br>
+                if (formatter_regex)<br>
+                {<br>
+                    bool escape = true;<br>
+                    if (0 == strcmp(regex_sp->GetText(), formatter_regex->GetText()))<br>
+                    {<br>
+                        escape = false;<br>
+                    }<br>
+                    else if (formatter_regex->Execute(regex_sp->GetText()))<br>
+                    {<br>
+                        escape = false;<br>
+                    }<br>
+<br>
+                    if (escape)<br>
+                        return true;<br>
+                }<br>
+<br>
+                result.GetOutputStream().Printf ("%s: %s\n", regex_sp->GetText(), format_sp->GetDescription().c_str());<br>
+<br>
+                return true;<br>
+            });<br>
<br>
-        if (cate_regex)<br>
-            delete cate_regex;<br>
+            category->ForEach(foreach);<br>
+<br>
+            return true;<br>
+        });<br>
<br>
+        FormatterSpecificList(result);<br>
+<br>
         result.SetStatus(eReturnStatusSuccessFinishResult);<br>
         return result.Succeeded();<br>
     }<br>
-<br>
-private:<br>
-<br>
-    static bool<br>
-    PerCategoryCallback(void* param_vp,<br>
-                        const lldb::TypeCategoryImplSP& cate)<br>
-    {<br>
-<br>
-        CommandObjectTypeFormatList_LoopCallbackParam* param =<br>
-        (CommandObjectTypeFormatList_LoopCallbackParam*)param_vp;<br>
-        CommandReturnObject* result = param->result;<br>
-<br>
-        const char* cate_name = cate->GetName();<br>
-<br>
-        // if the category is disabled or empty and there is no regex, just skip it<br>
-        if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemValue | eFormatCategoryItemRegexValue) == 0) && param->cate_regex == NULL)<br>
-            return true;<br>
-<br>
-        // if we have a regex and this category does not match it, just skip it<br>
-        if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false)<br>
-            return true;<br>
-<br>
-        result->GetOutputStream().Printf("-----------------------\nCategory: %s\n-----------------------\n", cate->GetDescription().c_str());<br>
-<br>
-        cate->GetTypeFormatsContainer()->LoopThrough(CommandObjectTypeFormatList_LoopCallback, param_vp);<br>
-<br>
-        if (cate->GetRegexTypeFormatsContainer()->GetCount() > 0)<br>
-        {<br>
-            result->GetOutputStream().Printf("Regex-based formats (slower):\n");<br>
-            cate->GetRegexTypeFormatsContainer()->LoopThrough(CommandObjectTypeRXFormatList_LoopCallback, param_vp);<br>
-        }<br>
-        return true;<br>
-    }<br>
-<br>
-<br>
-    bool<br>
-    LoopCallback (const char* type,<br>
-                  const lldb::TypeFormatImplSP& entry,<br>
-                  RegularExpression* regex,<br>
-                  CommandReturnObject *result)<br>
-    {<br>
-        if (regex == NULL || strcmp(type,regex->GetText()) == 0 || regex->Execute(type))<br>
-            result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str());<br>
-        return true;<br>
-    }<br>
-<br>
-    friend bool CommandObjectTypeFormatList_LoopCallback(void* pt2self, ConstString type, const lldb::TypeFormatImplSP& entry);<br>
-    friend bool CommandObjectTypeRXFormatList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const lldb::TypeFormatImplSP& entry);<br>
-<br>
 };<br>
<br>
-bool<br>
-CommandObjectTypeFormatList_LoopCallback (<br>
-                                    void* pt2self,<br>
-                                    ConstString type,<br>
-                                    const lldb::TypeFormatImplSP& entry)<br>
-{<br>
-    CommandObjectTypeFormatList_LoopCallbackParam* param = (CommandObjectTypeFormatList_LoopCallbackParam*)pt2self;<br>
-    return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result);<br>
-}<br>
-<br>
-bool<br>
-CommandObjectTypeRXFormatList_LoopCallback (<br>
-                                             void* pt2self,<br>
-                                             lldb::RegularExpressionSP regex,<br>
-                                             const lldb::TypeFormatImplSP& entry)<br>
-{<br>
-    CommandObjectTypeFormatList_LoopCallbackParam* param = (CommandObjectTypeFormatList_LoopCallbackParam*)pt2self;<br>
-    return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result);<br>
-}<br>
+//-------------------------------------------------------------------------<br>
+// CommandObjectTypeFormatList<br>
+//-------------------------------------------------------------------------<br>
<br>
-OptionDefinition<br>
-CommandObjectTypeFormatList::CommandOptions::g_option_table[] =<br>
+class CommandObjectTypeFormatList : public CommandObjectTypeFormatterList<TypeFormatImpl><br>
 {<br>
-    { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,  "Only show categories matching this filter."},<br>
-    { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }<br>
+public:<br>
+<br>
+    CommandObjectTypeFormatList (CommandInterpreter &interpreter) :<br>
+        CommandObjectTypeFormatterList(interpreter,<br>
+                                       "type format list",<br>
+                                       "Show a list of current formats.")<br>
+    {<br>
+    }<br>
 };<br>
<br>
 #ifndef LLDB_DISABLE_PYTHON<br>
@@ -2046,226 +2048,30 @@ protected:<br>
 // CommandObjectTypeSummaryList<br>
 //-------------------------------------------------------------------------<br>
<br>
-bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, ConstString type, const StringSummaryFormat::SharedPointer& entry);<br>
-bool CommandObjectTypeRXSummaryList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const StringSummaryFormat::SharedPointer& entry);<br>
-<br>
-class CommandObjectTypeSummaryList;<br>
-<br>
-struct CommandObjectTypeSummaryList_LoopCallbackParam {<br>
-    CommandObjectTypeSummaryList* self;<br>
-    CommandReturnObject* result;<br>
-    RegularExpression* regex;<br>
-    RegularExpression* cate_regex;<br>
-    CommandObjectTypeSummaryList_LoopCallbackParam(CommandObjectTypeSummaryList* S, CommandReturnObject* R,<br>
-                                                  RegularExpression* X = NULL,<br>
-                                                  RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {}<br>
-};<br>
-<br>
-class CommandObjectTypeSummaryList : public CommandObjectParsed<br>
+class CommandObjectTypeSummaryList : public CommandObjectTypeFormatterList<TypeSummaryImpl><br>
 {<br>
-<br>
-    class CommandOptions : public Options<br>
-    {<br>
-    public:<br>
-<br>
-        CommandOptions (CommandInterpreter &interpreter) :<br>
-        Options (interpreter)<br>
-        {<br>
-        }<br>
-<br>
-        ~CommandOptions () override {}<br>
-<br>
-        Error<br>
-        SetOptionValue (uint32_t option_idx, const char *option_arg) override<br>
-        {<br>
-            Error error;<br>
-            const int short_option = m_getopt_table[option_idx].val;<br>
-<br>
-            switch (short_option)<br>
-            {<br>
-                case 'w':<br>
-                    m_category_regex = std::string(option_arg);<br>
-                    break;<br>
-                default:<br>
-                    error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);<br>
-                    break;<br>
-            }<br>
-<br>
-            return error;<br>
-        }<br>
-<br>
-        void<br>
-        OptionParsingStarting () override<br>
-        {<br>
-            m_category_regex = "";<br>
-        }<br>
-<br>
-        const OptionDefinition*<br>
-        GetDefinitions () override<br>
-        {<br>
-            return g_option_table;<br>
-        }<br>
-<br>
-        // Options table: Required for subclasses of Options.<br>
-<br>
-        static OptionDefinition g_option_table[];<br>
-<br>
-        // Instance variables to hold the values for command options.<br>
-<br>
-        std::string m_category_regex;<br>
-<br>
-    };<br>
-<br>
-    CommandOptions m_options;<br>
-<br>
-    Options *<br>
-    GetOptions () override<br>
-    {<br>
-        return &m_options;<br>
-    }<br>
-<br>
 public:<br>
-    CommandObjectTypeSummaryList (CommandInterpreter &interpreter) :<br>
-        CommandObjectParsed (interpreter,<br>
-                             "type summary list",<br>
-                             "Show a list of current summary styles.",<br>
-                             NULL),<br>
-        m_options(interpreter)<br>
-    {<br>
-        CommandArgumentEntry type_arg;<br>
-        CommandArgumentData type_style_arg;<br>
-<br>
-        type_style_arg.arg_type = eArgTypeName;<br>
-        type_style_arg.arg_repetition = eArgRepeatOptional;<br>
-<br>
-        type_arg.push_back (type_style_arg);<br>
-<br>
-        m_arguments.push_back (type_arg);<br>
-    }<br>
<br>
-    ~CommandObjectTypeSummaryList () override<br>
+    CommandObjectTypeSummaryList (CommandInterpreter &interpreter) :<br>
+    CommandObjectTypeFormatterList(interpreter,<br>
+                                   "type summary list",<br>
+                                   "Show a list of current summaries.")<br>
     {<br>
     }<br>
<br>
 protected:<br>
-    bool<br>
-    DoExecute (Args& command, CommandReturnObject &result) override<br>
+    void<br>
+    FormatterSpecificList (CommandReturnObject &result) override<br>
     {<br>
-        const size_t argc = command.GetArgumentCount();<br>
-<br>
-        CommandObjectTypeSummaryList_LoopCallbackParam *param;<br>
-        RegularExpression* cate_regex =<br>
-        m_options.m_category_regex.empty() ? NULL :<br>
-        new RegularExpression(m_options.m_category_regex.c_str());<br>
-<br>
-        if (argc == 1)<br>
-        {<br>
-            RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));<br>
-            regex->Compile(command.GetArgumentAtIndex(0));<br>
-            param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,regex,cate_regex);<br>
-        }<br>
-        else<br>
-            param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,NULL,cate_regex);<br>
-<br>
-        DataVisualization::Categories::LoopThrough(PerCategoryCallback,param);<br>
-        delete param;<br>
-<br>
         if (DataVisualization::NamedSummaryFormats::GetCount() > 0)<br>
         {<br>
             result.GetOutputStream().Printf("Named summaries:\n");<br>
-            if (argc == 1)<br>
-            {<br>
-                RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));<br>
-                regex->Compile(command.GetArgumentAtIndex(0));<br>
-                param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,regex);<br>
-            }<br>
-            else<br>
-                param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result);<br>
-            DataVisualization::NamedSummaryFormats::LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param);<br>
-            delete param;<br>
-        }<br>
-<br>
-        if (cate_regex)<br>
-            delete cate_regex;<br>
-<br>
-        result.SetStatus(eReturnStatusSuccessFinishResult);<br>
-        return result.Succeeded();<br>
-    }<br>
-<br>
-private:<br>
-<br>
-    static bool<br>
-    PerCategoryCallback(void* param_vp,<br>
-                        const lldb::TypeCategoryImplSP& cate)<br>
-    {<br>
-<br>
-        CommandObjectTypeSummaryList_LoopCallbackParam* param =<br>
-            (CommandObjectTypeSummaryList_LoopCallbackParam*)param_vp;<br>
-        CommandReturnObject* result = param->result;<br>
-<br>
-        const char* cate_name = cate->GetName();<br>
-<br>
-        // if the category is disabled or empty and there is no regex, just skip it<br>
-        if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary) == 0) && param->cate_regex == NULL)<br>
-            return true;<br>
-<br>
-        // if we have a regex and this category does not match it, just skip it<br>
-        if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false)<br>
-            return true;<br>
-<br>
-        result->GetOutputStream().Printf("-----------------------\nCategory: %s\n-----------------------\n", cate->GetDescription().c_str());<br>
-<br>
-        cate->GetTypeSummariesContainer()->LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param_vp);<br>
-<br>
-        if (cate->GetRegexTypeSummariesContainer()->GetCount() > 0)<br>
-        {<br>
-            result->GetOutputStream().Printf("Regex-based summaries (slower):\n");<br>
-            cate->GetRegexTypeSummariesContainer()->LoopThrough(CommandObjectTypeRXSummaryList_LoopCallback, param_vp);<br>
+            DataVisualization::NamedSummaryFormats::ForEach( [&result] (ConstString name, const TypeSummaryImplSP& summary_sp) -> bool {<br>
+                result.GetOutputStream().Printf ("%s: %s\n", name.AsCString(), summary_sp->GetDescription().c_str());<br>
+                return true;<br>
+            });<br>
         }<br>
-        return true;<br>
-    }<br>
-<br>
-<br>
-    bool<br>
-    LoopCallback (const char* type,<br>
-                  const lldb::TypeSummaryImplSP& entry,<br>
-                  RegularExpression* regex,<br>
-                  CommandReturnObject *result)<br>
-    {<br>
-        if (regex == NULL || strcmp(type,regex->GetText()) == 0 || regex->Execute(type))<br>
-                result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str());<br>
-        return true;<br>
     }<br>
-<br>
-    friend bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, ConstString type, const lldb::TypeSummaryImplSP& entry);<br>
-    friend bool CommandObjectTypeRXSummaryList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const lldb::TypeSummaryImplSP& entry);<br>
-};<br>
-<br>
-bool<br>
-CommandObjectTypeSummaryList_LoopCallback (<br>
-                                          void* pt2self,<br>
-                                          ConstString type,<br>
-                                          const lldb::TypeSummaryImplSP& entry)<br>
-{<br>
-    CommandObjectTypeSummaryList_LoopCallbackParam* param = (CommandObjectTypeSummaryList_LoopCallbackParam*)pt2self;<br>
-    return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result);<br>
-}<br>
-<br>
-bool<br>
-CommandObjectTypeRXSummaryList_LoopCallback (<br>
-                                           void* pt2self,<br>
-                                           lldb::RegularExpressionSP regex,<br>
-                                           const lldb::TypeSummaryImplSP& entry)<br>
-{<br>
-    CommandObjectTypeSummaryList_LoopCallbackParam* param = (CommandObjectTypeSummaryList_LoopCallbackParam*)pt2self;<br>
-    return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result);<br>
-}<br>
-<br>
-OptionDefinition<br>
-CommandObjectTypeSummaryList::CommandOptions::g_option_table[] =<br>
-{<br>
-    { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,  "Only show categories matching this filter."},<br>
-    { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }<br>
 };<br>
<br>
 //-------------------------------------------------------------------------<br>
@@ -2786,37 +2592,6 @@ CommandObjectTypeCategoryDisable::Comman<br>
<br>
 class CommandObjectTypeCategoryList : public CommandObjectParsed<br>
 {<br>
-private:<br>
-<br>
-    struct CommandObjectTypeCategoryList_CallbackParam<br>
-    {<br>
-        CommandReturnObject* result;<br>
-        RegularExpression* regex;<br>
-<br>
-        CommandObjectTypeCategoryList_CallbackParam(CommandReturnObject* res,<br>
-                                                    RegularExpression* rex = NULL) :<br>
-        result(res),<br>
-        regex(rex)<br>
-        {<br>
-        }<br>
-<br>
-    };<br>
-<br>
-    static bool<br>
-    PerCategoryCallback(void* param_vp,<br>
-                        const lldb::TypeCategoryImplSP& cate)<br>
-    {<br>
-        CommandObjectTypeCategoryList_CallbackParam* param =<br>
-            (CommandObjectTypeCategoryList_CallbackParam*)param_vp;<br>
-        CommandReturnObject* result = param->result;<br>
-        RegularExpression* regex = param->regex;<br>
-<br>
-        const char* cate_name = cate->GetName();<br>
-<br>
-        if (regex == NULL || strcmp(cate_name, regex->GetText()) == 0 || regex->Execute(cate_name))<br>
-            result->GetOutputStream().Printf("Category: %s\n", cate->GetDescription().c_str());<br>
-        return true;<br>
-    }<br>
 public:<br>
     CommandObjectTypeCategoryList (CommandInterpreter &interpreter) :<br>
         CommandObjectParsed (interpreter,<br>
@@ -2844,26 +2619,48 @@ protected:<br>
     DoExecute (Args& command, CommandReturnObject &result) override<br>
     {<br>
         const size_t argc = command.GetArgumentCount();<br>
-        RegularExpression* regex = NULL;<br>
+<br>
+        std::unique_ptr<RegularExpression> regex;<br>
<br>
-        if (argc == 0)<br>
-            ;<br>
-        else if (argc == 1)<br>
-            regex = new RegularExpression(command.GetArgumentAtIndex(0));<br>
-        else<br>
+        if (argc == 1)<br>
+        {<br>
+            regex.reset(new RegularExpression());<br>
+            const char* arg = command.GetArgumentAtIndex(0);<br>
+            if (!regex->Compile(arg))<br>
+            {<br>
+                result.AppendErrorWithFormat("syntax error in category regular expression '%s'", arg);<br>
+                result.SetStatus(eReturnStatusFailed);<br>
+                return false;<br>
+            }<br>
+        }<br>
+        else if (argc != 0)<br>
         {<br>
             result.AppendErrorWithFormat ("%s takes 0 or one arg.\n", m_cmd_name.c_str());<br>
             result.SetStatus(eReturnStatusFailed);<br>
             return false;<br>
         }<br>
<br>
-        CommandObjectTypeCategoryList_CallbackParam param(&result,<br>
-                                                          regex);<br>
-<br>
-        DataVisualization::Categories::LoopThrough(PerCategoryCallback, &param);<br>
-<br>
-        if (regex)<br>
-            delete regex;<br>
+        DataVisualization::Categories::ForEach( [&regex, &result] (const lldb::TypeCategoryImplSP& category_sp) -> bool {<br>
+            if (regex)<br>
+            {<br>
+                bool escape = true;<br>
+                if (0 == strcmp(category_sp->GetName(), regex->GetText()))<br>
+                {<br>
+                    escape = false;<br>
+                }<br>
+                else if (regex->Execute(category_sp->GetName()))<br>
+                {<br>
+                    escape = false;<br>
+                }<br>
+<br>
+                if (escape)<br>
+                    return true;<br>
+            }<br>
+<br>
+            result.GetOutputStream().Printf("Category: %s\n", category_sp->GetDescription().c_str());<br>
+<br>
+            return true;<br>
+        });<br>
<br>
         result.SetStatus(eReturnStatusSuccessFinishResult);<br>
         return result.Succeeded();<br>
@@ -2875,210 +2672,16 @@ protected:<br>
 // CommandObjectTypeFilterList<br>
 //-------------------------------------------------------------------------<br>
<br>
-bool CommandObjectTypeFilterList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry);<br>
-bool CommandObjectTypeFilterRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry);<br>
-<br>
-class CommandObjectTypeFilterList;<br>
-<br>
-struct CommandObjectTypeFilterList_LoopCallbackParam {<br>
-    CommandObjectTypeFilterList* self;<br>
-    CommandReturnObject* result;<br>
-    RegularExpression* regex;<br>
-    RegularExpression* cate_regex;<br>
-    CommandObjectTypeFilterList_LoopCallbackParam(CommandObjectTypeFilterList* S, CommandReturnObject* R,<br>
-                                                  RegularExpression* X = NULL,<br>
-                                                  RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {}<br>
-};<br>
-<br>
-class CommandObjectTypeFilterList : public CommandObjectParsed<br>
+class CommandObjectTypeFilterList : public CommandObjectTypeFormatterList<TypeFilterImpl><br>
 {<br>
-<br>
-    class CommandOptions : public Options<br>
-    {<br>
-    public:<br>
-<br>
-        CommandOptions (CommandInterpreter &interpreter) :<br>
-        Options (interpreter)<br>
-        {<br>
-        }<br>
-<br>
-        ~CommandOptions () override {}<br>
-<br>
-        Error<br>
-        SetOptionValue (uint32_t option_idx, const char *option_arg) override<br>
-        {<br>
-            Error error;<br>
-            const int short_option = m_getopt_table[option_idx].val;<br>
-<br>
-            switch (short_option)<br>
-            {<br>
-                case 'w':<br>
-                    m_category_regex = std::string(option_arg);<br>
-                    break;<br>
-                default:<br>
-                    error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);<br>
-                    break;<br>
-            }<br>
-<br>
-            return error;<br>
-        }<br>
-<br>
-        void<br>
-        OptionParsingStarting () override<br>
-        {<br>
-            m_category_regex = "";<br>
-        }<br>
-<br>
-        const OptionDefinition*<br>
-        GetDefinitions () override<br>
-        {<br>
-            return g_option_table;<br>
-        }<br>
-<br>
-        // Options table: Required for subclasses of Options.<br>
-<br>
-        static OptionDefinition g_option_table[];<br>
-<br>
-        // Instance variables to hold the values for command options.<br>
-<br>
-        std::string m_category_regex;<br>
-<br>
-    };<br>
-<br>
-    CommandOptions m_options;<br>
-<br>
-    Options *<br>
-    GetOptions () override<br>
-    {<br>
-        return &m_options;<br>
-    }<br>
-<br>
 public:<br>
-    CommandObjectTypeFilterList (CommandInterpreter &interpreter) :<br>
-        CommandObjectParsed (interpreter,<br>
-                             "type filter list",<br>
-                             "Show a list of current filters.",<br>
-                             NULL),<br>
-        m_options(interpreter)<br>
-    {<br>
-        CommandArgumentEntry type_arg;<br>
-        CommandArgumentData type_style_arg;<br>
-<br>
-        type_style_arg.arg_type = eArgTypeName;<br>
-        type_style_arg.arg_repetition = eArgRepeatOptional;<br>
-<br>
-        type_arg.push_back (type_style_arg);<br>
-<br>
-        m_arguments.push_back (type_arg);<br>
-    }<br>
-<br>
-    ~CommandObjectTypeFilterList () override<br>
-    {<br>
-    }<br>
-<br>
-protected:<br>
-    bool<br>
-    DoExecute (Args& command, CommandReturnObject &result) override<br>
-    {<br>
-        const size_t argc = command.GetArgumentCount();<br>
-<br>
-        CommandObjectTypeFilterList_LoopCallbackParam *param;<br>
-        RegularExpression* cate_regex =<br>
-        m_options.m_category_regex.empty() ? NULL :<br>
-        new RegularExpression(m_options.m_category_regex.c_str());<br>
-<br>
-        if (argc == 1)<br>
-        {<br>
-            RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));<br>
-            regex->Compile(command.GetArgumentAtIndex(0));<br>
-            param = new CommandObjectTypeFilterList_LoopCallbackParam(this,&result,regex,cate_regex);<br>
-        }<br>
-        else<br>
-            param = new CommandObjectTypeFilterList_LoopCallbackParam(this,&result,NULL,cate_regex);<br>
-<br>
-        DataVisualization::Categories::LoopThrough(PerCategoryCallback,param);<br>
-        delete param;<br>
-<br>
-        if (cate_regex)<br>
-            delete cate_regex;<br>
-<br>
-        result.SetStatus(eReturnStatusSuccessFinishResult);<br>
-        return result.Succeeded();<br>
-    }<br>
<br>
-private:<br>
-<br>
-    static bool<br>
-    PerCategoryCallback(void* param_vp,<br>
-                        const lldb::TypeCategoryImplSP& cate)<br>
-    {<br>
-<br>
-        const char* cate_name = cate->GetName();<br>
-<br>
-        CommandObjectTypeFilterList_LoopCallbackParam* param =<br>
-        (CommandObjectTypeFilterList_LoopCallbackParam*)param_vp;<br>
-        CommandReturnObject* result = param->result;<br>
-<br>
-        // if the category is disabled or empty and there is no regex, just skip it<br>
-        if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter) == 0) && param->cate_regex == NULL)<br>
-            return true;<br>
-<br>
-        // if we have a regex and this category does not match it, just skip it<br>
-        if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false)<br>
-            return true;<br>
-<br>
-        result->GetOutputStream().Printf("-----------------------\nCategory: %s\n-----------------------\n", cate->GetDescription().c_str());<br>
-<br>
-        cate->GetTypeFiltersContainer()->LoopThrough(CommandObjectTypeFilterList_LoopCallback, param_vp);<br>
-<br>
-        if (cate->GetRegexTypeFiltersContainer()->GetCount() > 0)<br>
-        {<br>
-            result->GetOutputStream().Printf("Regex-based filters (slower):\n");<br>
-            cate->GetRegexTypeFiltersContainer()->LoopThrough(CommandObjectTypeFilterRXList_LoopCallback, param_vp);<br>
-        }<br>
-<br>
-        return true;<br>
-    }<br>
-<br>
-    bool<br>
-    LoopCallback (const char* type,<br>
-                  const SyntheticChildren::SharedPointer& entry,<br>
-                  RegularExpression* regex,<br>
-                  CommandReturnObject *result)<br>
+    CommandObjectTypeFilterList (CommandInterpreter &interpreter) :<br>
+    CommandObjectTypeFormatterList(interpreter,<br>
+                                   "type filter list",<br>
+                                   "Show a list of current filters.")<br>
     {<br>
-        if (regex == NULL || regex->Execute(type))<br>
-            result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str());<br>
-        return true;<br>
     }<br>
-<br>
-    friend bool CommandObjectTypeFilterList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry);<br>
-    friend bool CommandObjectTypeFilterRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry);<br>
-};<br>
-<br>
-bool<br>
-CommandObjectTypeFilterList_LoopCallback (void* pt2self,<br>
-                                         ConstString type,<br>
-                                         const SyntheticChildren::SharedPointer& entry)<br>
-{<br>
-    CommandObjectTypeFilterList_LoopCallbackParam* param = (CommandObjectTypeFilterList_LoopCallbackParam*)pt2self;<br>
-    return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result);<br>
-}<br>
-<br>
-bool<br>
-CommandObjectTypeFilterRXList_LoopCallback (void* pt2self,<br>
-                                           lldb::RegularExpressionSP regex,<br>
-                                           const SyntheticChildren::SharedPointer& entry)<br>
-{<br>
-    CommandObjectTypeFilterList_LoopCallbackParam* param = (CommandObjectTypeFilterList_LoopCallbackParam*)pt2self;<br>
-    return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result);<br>
-}<br>
-<br>
-<br>
-OptionDefinition<br>
-CommandObjectTypeFilterList::CommandOptions::g_option_table[] =<br>
-{<br>
-    { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,  "Only show categories matching this filter."},<br>
-    { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }<br>
 };<br>
<br>
 #ifndef LLDB_DISABLE_PYTHON<br>
@@ -3087,210 +2690,16 @@ CommandObjectTypeFilterList::CommandOpti<br>
 // CommandObjectTypeSynthList<br>
 //-------------------------------------------------------------------------<br>
<br>
-bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry);<br>
-bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry);<br>
-<br>
-class CommandObjectTypeSynthList;<br>
-<br>
-struct CommandObjectTypeSynthList_LoopCallbackParam {<br>
-    CommandObjectTypeSynthList* self;<br>
-    CommandReturnObject* result;<br>
-    RegularExpression* regex;<br>
-    RegularExpression* cate_regex;<br>
-    CommandObjectTypeSynthList_LoopCallbackParam(CommandObjectTypeSynthList* S, CommandReturnObject* R,<br>
-                                                 RegularExpression* X = NULL,<br>
-                                                 RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {}<br>
-};<br>
-<br>
-class CommandObjectTypeSynthList : public CommandObjectParsed<br>
+class CommandObjectTypeSynthList : public CommandObjectTypeFormatterList<SyntheticChildren><br>
 {<br>
-<br>
-    class CommandOptions : public Options<br>
-    {<br>
-    public:<br>
-<br>
-        CommandOptions (CommandInterpreter &interpreter) :<br>
-        Options (interpreter)<br>
-        {<br>
-        }<br>
-<br>
-        ~CommandOptions () override {}<br>
-<br>
-        Error<br>
-        SetOptionValue (uint32_t option_idx, const char *option_arg) override<br>
-        {<br>
-            Error error;<br>
-            const int short_option = m_getopt_table[option_idx].val;<br>
-<br>
-            switch (short_option)<br>
-            {<br>
-                case 'w':<br>
-                    m_category_regex = std::string(option_arg);<br>
-                    break;<br>
-                default:<br>
-                    error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);<br>
-                    break;<br>
-            }<br>
-<br>
-            return error;<br>
-        }<br>
-<br>
-        void<br>
-        OptionParsingStarting () override<br>
-        {<br>
-            m_category_regex = "";<br>
-        }<br>
-<br>
-        const OptionDefinition*<br>
-        GetDefinitions () override<br>
-        {<br>
-            return g_option_table;<br>
-        }<br>
-<br>
-        // Options table: Required for subclasses of Options.<br>
-<br>
-        static OptionDefinition g_option_table[];<br>
-<br>
-        // Instance variables to hold the values for command options.<br>
-<br>
-        std::string m_category_regex;<br>
-<br>
-    };<br>
-<br>
-    CommandOptions m_options;<br>
-<br>
-    Options *<br>
-    GetOptions () override<br>
-    {<br>
-        return &m_options;<br>
-    }<br>
-<br>
 public:<br>
-    CommandObjectTypeSynthList (CommandInterpreter &interpreter) :<br>
-        CommandObjectParsed (interpreter,<br>
-                             "type synthetic list",<br>
-                             "Show a list of current synthetic providers.",<br>
-                             NULL),<br>
-        m_options(interpreter)<br>
-    {<br>
-        CommandArgumentEntry type_arg;<br>
-        CommandArgumentData type_style_arg;<br>
-<br>
-        type_style_arg.arg_type = eArgTypeName;<br>
-        type_style_arg.arg_repetition = eArgRepeatOptional;<br>
-<br>
-        type_arg.push_back (type_style_arg);<br>
-<br>
-        m_arguments.push_back (type_arg);<br>
-    }<br>
-<br>
-    ~CommandObjectTypeSynthList () override<br>
-    {<br>
-    }<br>
-<br>
-protected:<br>
-    bool<br>
-    DoExecute (Args& command, CommandReturnObject &result) override<br>
-    {<br>
-        const size_t argc = command.GetArgumentCount();<br>
-<br>
-        CommandObjectTypeSynthList_LoopCallbackParam *param;<br>
-        RegularExpression* cate_regex =<br>
-        m_options.m_category_regex.empty() ? NULL :<br>
-        new RegularExpression(m_options.m_category_regex.c_str());<br>
-<br>
-        if (argc == 1)<br>
-        {<br>
-            RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));<br>
-            regex->Compile(command.GetArgumentAtIndex(0));<br>
-            param = new CommandObjectTypeSynthList_LoopCallbackParam(this,&result,regex,cate_regex);<br>
-        }<br>
-        else<br>
-            param = new CommandObjectTypeSynthList_LoopCallbackParam(this,&result,NULL,cate_regex);<br>
-<br>
-        DataVisualization::Categories::LoopThrough(PerCategoryCallback,param);<br>
-        delete param;<br>
-<br>
-        if (cate_regex)<br>
-            delete cate_regex;<br>
-<br>
-        result.SetStatus(eReturnStatusSuccessFinishResult);<br>
-        return result.Succeeded();<br>
-    }<br>
-<br>
-private:<br>
<br>
-    static bool<br>
-    PerCategoryCallback(void* param_vp,<br>
-                        const lldb::TypeCategoryImplSP& cate)<br>
-    {<br>
-<br>
-        CommandObjectTypeSynthList_LoopCallbackParam* param =<br>
-        (CommandObjectTypeSynthList_LoopCallbackParam*)param_vp;<br>
-        CommandReturnObject* result = param->result;<br>
-<br>
-        const char* cate_name = cate->GetName();<br>
-<br>
-        // if the category is disabled or empty and there is no regex, just skip it<br>
-        if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth) == 0) && param->cate_regex == NULL)<br>
-            return true;<br>
-<br>
-        // if we have a regex and this category does not match it, just skip it<br>
-        if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false)<br>
-            return true;<br>
-<br>
-        result->GetOutputStream().P</blockquote></div></div></div></blockquote></div></div></blockquote></div></div></blockquote></div></div></blockquote></div></div></div></div></blockquote></div></div>