[Lldb-commits] [lldb] r253493 - Reapply r253423 and r253424 (which cleanup the data formatters iteration model, as well as the type X list commands), along with a change by Zachary Turner to bypass a MSVC bug with SFINAE

Enrico Granata via lldb-commits lldb-commits at lists.llvm.org
Wed Nov 18 11:42:45 PST 2015


Author: enrico
Date: Wed Nov 18 13:42:44 2015
New Revision: 253493

URL: http://llvm.org/viewvc/llvm-project?rev=253493&view=rev
Log:
Reapply r253423 and r253424 (which cleanup the data formatters iteration model, as well as the type X list commands), along with a change by Zachary Turner to bypass a MSVC bug with SFINAE


Modified:
    lldb/trunk/include/lldb/DataFormatters/DataVisualization.h
    lldb/trunk/include/lldb/DataFormatters/FormatManager.h
    lldb/trunk/include/lldb/DataFormatters/FormattersContainer.h
    lldb/trunk/include/lldb/DataFormatters/TypeCategory.h
    lldb/trunk/include/lldb/DataFormatters/TypeCategoryMap.h
    lldb/trunk/include/lldb/DataFormatters/TypeFormat.h
    lldb/trunk/include/lldb/DataFormatters/TypeSummary.h
    lldb/trunk/include/lldb/DataFormatters/TypeSynthetic.h
    lldb/trunk/include/lldb/DataFormatters/TypeValidator.h
    lldb/trunk/source/API/SBTypeCategory.cpp
    lldb/trunk/source/Commands/CommandObjectType.cpp
    lldb/trunk/source/DataFormatters/DataVisualization.cpp
    lldb/trunk/source/DataFormatters/FormatManager.cpp
    lldb/trunk/source/DataFormatters/TypeCategoryMap.cpp

Modified: lldb/trunk/include/lldb/DataFormatters/DataVisualization.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/DataVisualization.h?rev=253493&r1=253492&r2=253493&view=diff
==============================================================================
--- lldb/trunk/include/lldb/DataFormatters/DataVisualization.h (original)
+++ lldb/trunk/include/lldb/DataFormatters/DataVisualization.h Wed Nov 18 13:42:44 2015
@@ -101,7 +101,7 @@ public:
         Clear ();
         
         static void
-        LoopThrough (TypeSummaryImpl::SummaryCallback callback, void* callback_baton);
+        ForEach (std::function<bool(ConstString, const lldb::TypeSummaryImplSP&)> callback);
         
         static uint32_t
         GetCount ();
@@ -158,9 +158,6 @@ public:
         DisableStar ();
         
         static void
-        LoopThrough (FormatManager::CategoryCallback callback, void* callback_baton);
-        
-        static void
         ForEach (TypeCategoryMap::ForEachCallback callback);
         
         static uint32_t

Modified: lldb/trunk/include/lldb/DataFormatters/FormatManager.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/FormatManager.h?rev=253493&r1=253492&r2=253493&view=diff
==============================================================================
--- lldb/trunk/include/lldb/DataFormatters/FormatManager.h (original)
+++ lldb/trunk/include/lldb/DataFormatters/FormatManager.h Wed Nov 18 13:42:44 2015
@@ -43,8 +43,6 @@ class FormatManager : public IFormatChan
 public:
     typedef std::map<lldb::LanguageType, LanguageCategory::UniquePointer> LanguageCategories;
     
-    typedef TypeCategoryMap::CallbackType CategoryCallback;
-    
     FormatManager();
     
     ~FormatManager() override = default;
@@ -140,9 +138,6 @@ public:
     }
     
     void
-    LoopThroughCategories (CategoryCallback callback, void* param);
-
-    void
     ForEachCategory (TypeCategoryMap::ForEachCallback callback);
     
     lldb::TypeCategoryImplSP

Modified: lldb/trunk/include/lldb/DataFormatters/FormattersContainer.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/FormattersContainer.h?rev=253493&r1=253492&r2=253493&view=diff
==============================================================================
--- lldb/trunk/include/lldb/DataFormatters/FormattersContainer.h (original)
+++ lldb/trunk/include/lldb/DataFormatters/FormattersContainer.h Wed Nov 18 13:42:44 2015
@@ -80,8 +80,6 @@ public:
     typedef typename ValueType::SharedPointer ValueSP;
     typedef std::map<KeyType, ValueSP> MapType;
     typedef typename MapType::iterator MapIterator;
-    typedef std::function<bool(void*, KeyType, const ValueSP&)> CallbackType;
-    
     typedef std::function<bool(KeyType, const ValueSP&)> ForEachCallback;
     
     FormatMap(IFormatChangeListener* lst) :
@@ -141,22 +139,6 @@ public:
     }
     
     void
-    LoopThrough (CallbackType callback, void* param)
-    {
-        if (callback)
-        {
-            Mutex::Locker locker(m_map_mutex);
-            MapIterator pos, end = m_map.end();
-            for (pos = m_map.begin(); pos != end; pos++)
-            {
-                KeyType type = pos->first;
-                if (!callback(param, type, pos->second))
-                    break;
-            }
-        }
-    }
-    
-    void
     ForEach (ForEachCallback callback)
     {
         if (callback)
@@ -242,7 +224,6 @@ public:
     typedef typename MapType::iterator MapIterator;
     typedef typename MapType::key_type MapKeyType;
     typedef typename MapType::mapped_type MapValueType;
-    typedef typename BackEndType::CallbackType CallbackType;
     typedef typename BackEndType::ForEachCallback ForEachCallback;
     typedef typename std::shared_ptr<FormattersContainer<KeyType, ValueType> > SharedPointer;
     
@@ -316,12 +297,6 @@ public:
     }
     
     void
-    LoopThrough (CallbackType callback, void* param)
-    {
-        m_format_map.LoopThrough(callback,param);
-    }
-    
-    void
     ForEach (ForEachCallback callback)
     {
         m_format_map.ForEach(callback);

Modified: lldb/trunk/include/lldb/DataFormatters/TypeCategory.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/TypeCategory.h?rev=253493&r1=253492&r2=253493&view=diff
==============================================================================
--- lldb/trunk/include/lldb/DataFormatters/TypeCategory.h (original)
+++ lldb/trunk/include/lldb/DataFormatters/TypeCategory.h Wed Nov 18 13:42:44 2015
@@ -67,14 +67,6 @@ namespace lldb_private {
             return m_regex_sp;
         }
         
-        void
-        LoopThrough (typename ExactMatchContainer::CallbackType exact_callback,
-                     typename RegexMatchContainer::CallbackType regex_callback)
-        {
-            GetExactMatch()->LoopThrough(exact_callback);
-            GetRegexMatch()->LoopThrough(regex_callback);
-        }
-        
         uint32_t
         GetCount ()
         {
@@ -95,7 +87,7 @@ namespace lldb_private {
         typedef FormatterContainerPair<TypeValidatorImpl> ValidatorContainer;
         
 #ifndef LLDB_DISABLE_PYTHON
-        typedef FormatterContainerPair<ScriptedSyntheticChildren> SynthContainer;
+        typedef FormatterContainerPair<SyntheticChildren> SynthContainer;
 #endif // LLDB_DISABLE_PYTHON
 
     public:
@@ -118,74 +110,84 @@ namespace lldb_private {
         typedef ValidatorContainer::ExactMatchContainerSP ValidatorContainerSP;
         typedef ValidatorContainer::RegexMatchContainerSP RegexValidatorContainerSP;
         
-        class ForEach
+        template <typename T>
+        class ForEachCallbacks
         {
         public:
-            ForEach () = default;
-            ~ForEach () = default;
+            ForEachCallbacks () = default;
+            ~ForEachCallbacks () = default;
             
-            ForEach&
-            SetFormatExactCallback (FormatContainer::ExactMatchForEachCallback callback)
+            template<typename U = TypeFormatImpl>
+            typename std::enable_if<std::is_same<U,T>::value, ForEachCallbacks&>::type
+            SetExact (FormatContainer::ExactMatchForEachCallback callback)
             {
                 m_format_exact = callback;
                 return *this;
             }
-            ForEach&
-            SetFormatRegexCallback (FormatContainer::RegexMatchForEachCallback callback)
+            template<typename U = TypeFormatImpl>
+            typename std::enable_if<std::is_same<U,T>::value, ForEachCallbacks&>::type
+            SetWithRegex (FormatContainer::RegexMatchForEachCallback callback)
             {
                 m_format_regex = callback;
                 return *this;
             }
 
-            ForEach&
-            SetSummaryExactCallback (SummaryContainer::ExactMatchForEachCallback callback)
+            template<typename U = TypeSummaryImpl>
+            typename std::enable_if<std::is_same<U,T>::value, ForEachCallbacks&>::type
+            SetExact (SummaryContainer::ExactMatchForEachCallback callback)
             {
                 m_summary_exact = callback;
                 return *this;
             }
-            ForEach&
-            SetSummaryRegexCallback (SummaryContainer::RegexMatchForEachCallback callback)
+            template<typename U = TypeSummaryImpl>
+            typename std::enable_if<std::is_same<U,T>::value, ForEachCallbacks&>::type
+            SetWithRegex (SummaryContainer::RegexMatchForEachCallback callback)
             {
                 m_summary_regex = callback;
                 return *this;
             }
 
-            ForEach&
-            SetFilterExactCallback (FilterContainer::ExactMatchForEachCallback callback)
+            template<typename U = TypeFilterImpl>
+            typename std::enable_if<std::is_same<U,T>::value, ForEachCallbacks&>::type
+            SetExact (FilterContainer::ExactMatchForEachCallback callback)
             {
                 m_filter_exact = callback;
                 return *this;
             }
-            ForEach&
-            SetFilterRegexCallback (FilterContainer::RegexMatchForEachCallback callback)
+            template<typename U = TypeFilterImpl>
+            typename std::enable_if<std::is_same<U,T>::value, ForEachCallbacks&>::type
+            SetWithRegex (FilterContainer::RegexMatchForEachCallback callback)
             {
                 m_filter_regex = callback;
                 return *this;
             }
 
 #ifndef LLDB_DISABLE_PYTHON
-            ForEach&
-            SetSynthExactCallback (SynthContainer::ExactMatchForEachCallback callback)
+            template<typename U = SyntheticChildren>
+            typename std::enable_if<std::is_same<U,T>::value, ForEachCallbacks&>::type
+            SetExact (SynthContainer::ExactMatchForEachCallback callback)
             {
                 m_synth_exact = callback;
                 return *this;
             }
-            ForEach&
-            SetSynthRegexCallback (SynthContainer::RegexMatchForEachCallback callback)
+            template<typename U = SyntheticChildren>
+            typename std::enable_if<std::is_same<U,T>::value, ForEachCallbacks&>::type
+            SetWithRegex (SynthContainer::RegexMatchForEachCallback callback)
             {
                 m_synth_regex = callback;
                 return *this;
             }
 #endif // LLDB_DISABLE_PYTHON
-
-            ForEach&
-            SetValidatorExactCallback (ValidatorContainer::ExactMatchForEachCallback callback)
+            template<typename U = TypeValidatorImpl>
+            typename std::enable_if<std::is_same<U,T>::value, ForEachCallbacks&>::type
+            SetExact (ValidatorContainer::ExactMatchForEachCallback callback)
             {
                 m_validator_exact = callback;
                 return *this;
             }
-            ForEach&
-            SetValidatorRegexCallback (ValidatorContainer::RegexMatchForEachCallback callback)
+            template<typename U = TypeValidatorImpl>
+            typename std::enable_if<std::is_same<U,T>::value, ForEachCallbacks&>::type
+            SetWithRegex (ValidatorContainer::RegexMatchForEachCallback callback)
             {
                 m_validator_regex = callback;
                 return *this;
@@ -271,8 +273,9 @@ namespace lldb_private {
                           ConstString name,
                           std::initializer_list<lldb::LanguageType> langs = {});
         
+        template <typename T>
         void
-        ForEach (const ForEach &foreach)
+        ForEach (const ForEachCallbacks<T> &foreach)
         {
             GetTypeFormatsContainer()->ForEach(foreach.GetFormatExactCallback());
             GetRegexTypeFormatsContainer()->ForEach(foreach.GetFormatRegexCallback());

Modified: lldb/trunk/include/lldb/DataFormatters/TypeCategoryMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/TypeCategoryMap.h?rev=253493&r1=253492&r2=253493&view=diff
==============================================================================
--- lldb/trunk/include/lldb/DataFormatters/TypeCategoryMap.h (original)
+++ lldb/trunk/include/lldb/DataFormatters/TypeCategoryMap.h Wed Nov 18 13:42:44 2015
@@ -37,8 +37,6 @@ namespace lldb_private {
     public:
         typedef std::map<KeyType, ValueSP> MapType;
         typedef MapType::iterator MapIterator;
-        typedef bool(*CallbackType)(void*, const ValueSP&);
-        
         typedef std::function<bool(const ValueSP&)> ForEachCallback;
         
         typedef uint32_t Position;
@@ -88,9 +86,6 @@ namespace lldb_private {
              ValueSP& entry);
         
         void
-        LoopThrough (CallbackType callback, void* param);
-        
-        void
         ForEach (ForEachCallback callback);
         
         lldb::TypeCategoryImplSP

Modified: lldb/trunk/include/lldb/DataFormatters/TypeFormat.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/TypeFormat.h?rev=253493&r1=253492&r2=253493&view=diff
==============================================================================
--- lldb/trunk/include/lldb/DataFormatters/TypeFormat.h (original)
+++ lldb/trunk/include/lldb/DataFormatters/TypeFormat.h Wed Nov 18 13:42:44 2015
@@ -151,7 +151,6 @@ namespace lldb_private {
         TypeFormatImpl (const Flags& flags = Flags());
         
         typedef std::shared_ptr<TypeFormatImpl> SharedPointer;
-        typedef std::function<bool(void*, ConstString, lldb::TypeFormatImplSP)> ValueCallback;
         
         virtual ~TypeFormatImpl ();
         
@@ -259,7 +258,6 @@ namespace lldb_private {
                                const TypeFormatImpl::Flags& flags = Flags());
         
         typedef std::shared_ptr<TypeFormatImpl_Format> SharedPointer;
-        typedef std::function<bool(void*, ConstString, TypeFormatImpl_Format::SharedPointer)> ValueCallback;
         
         ~TypeFormatImpl_Format() override;
         
@@ -302,7 +300,6 @@ namespace lldb_private {
                                  const TypeFormatImpl::Flags& flags = Flags());
         
         typedef std::shared_ptr<TypeFormatImpl_EnumType> SharedPointer;
-        typedef std::function<bool(void*, ConstString, TypeFormatImpl_EnumType::SharedPointer)> ValueCallback;
         
         ~TypeFormatImpl_EnumType() override;
         

Modified: lldb/trunk/include/lldb/DataFormatters/TypeSummary.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/TypeSummary.h?rev=253493&r1=253492&r2=253493&view=diff
==============================================================================
--- lldb/trunk/include/lldb/DataFormatters/TypeSummary.h (original)
+++ lldb/trunk/include/lldb/DataFormatters/TypeSummary.h Wed Nov 18 13:42:44 2015
@@ -406,8 +406,6 @@ namespace lldb_private {
         }
         
         typedef std::shared_ptr<TypeSummaryImpl> SharedPointer;
-        typedef std::function<bool(void*, ConstString, TypeSummaryImpl::SharedPointer)> SummaryCallback;
-        typedef std::function<bool(void*, lldb::RegularExpressionSP, TypeSummaryImpl::SharedPointer)> RegexSummaryCallback;
         
     protected:
         uint32_t m_my_revision;

Modified: lldb/trunk/include/lldb/DataFormatters/TypeSynthetic.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/TypeSynthetic.h?rev=253493&r1=253492&r2=253493&view=diff
==============================================================================
--- lldb/trunk/include/lldb/DataFormatters/TypeSynthetic.h (original)
+++ lldb/trunk/include/lldb/DataFormatters/TypeSynthetic.h Wed Nov 18 13:42:44 2015
@@ -348,7 +348,6 @@ namespace lldb_private {
         GetFrontEnd (ValueObject &backend) = 0;
         
         typedef std::shared_ptr<SyntheticChildren> SharedPointer;
-        typedef std::function<bool(void*, ConstString, SyntheticChildren::SharedPointer)> SyntheticChildrenCallback;
         
         uint32_t&
         GetRevision ()
@@ -479,6 +478,8 @@ namespace lldb_private {
             return SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(this, backend));
         }
         
+        typedef std::shared_ptr<TypeFilterImpl> SharedPointer;
+        
     private:
         DISALLOW_COPY_AND_ASSIGN(TypeFilterImpl);
     };

Modified: lldb/trunk/include/lldb/DataFormatters/TypeValidator.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/TypeValidator.h?rev=253493&r1=253492&r2=253493&view=diff
==============================================================================
--- lldb/trunk/include/lldb/DataFormatters/TypeValidator.h (original)
+++ lldb/trunk/include/lldb/DataFormatters/TypeValidator.h Wed Nov 18 13:42:44 2015
@@ -150,7 +150,6 @@ public:
     TypeValidatorImpl (const Flags& flags = Flags());
     
     typedef std::shared_ptr<TypeValidatorImpl> SharedPointer;
-    typedef std::function<bool(void*, ConstString, TypeValidatorImpl::SharedPointer)> ValueCallback;
     
     virtual ~TypeValidatorImpl ();
     
@@ -265,7 +264,6 @@ public:
     TypeValidatorImpl_CXX (ValidatorFunction f, std::string d, const TypeValidatorImpl::Flags& flags = Flags());
     
     typedef std::shared_ptr<TypeValidatorImpl_CXX> SharedPointer;
-    typedef std::function<bool(void*, ConstString, TypeValidatorImpl_CXX::SharedPointer)> ValueCallback;
     
     ~TypeValidatorImpl_CXX() override;
     

Modified: lldb/trunk/source/API/SBTypeCategory.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBTypeCategory.cpp?rev=253493&r1=253492&r2=253493&view=diff
==============================================================================
--- lldb/trunk/source/API/SBTypeCategory.cpp (original)
+++ lldb/trunk/source/API/SBTypeCategory.cpp Wed Nov 18 13:42:44 2015
@@ -180,7 +180,7 @@ SBTypeCategory::GetFilterForType (SBType
     if (!spec.IsValid())
         return SBTypeFilter();
     
-    lldb::SyntheticChildrenSP children_sp;
+    lldb::TypeFilterImplSP children_sp;
     
     if (spec.IsRegex())
         m_opaque_sp->GetRegexTypeFiltersContainer()->GetExact(ConstString(spec.GetName()), children_sp);

Modified: lldb/trunk/source/Commands/CommandObjectType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectType.cpp?rev=253493&r1=253492&r2=253493&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectType.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectType.cpp Wed Nov 18 13:42:44 2015
@@ -1089,13 +1089,6 @@ CommandObjectTypeFormatterDelete::Comman
     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
 };
 
-
-
-
-
-
-
-
 class CommandObjectTypeFormatterClear : public CommandObjectParsed
 {
 private:
@@ -1224,10 +1217,6 @@ CommandObjectTypeFormatterClear::Command
     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
 };
 
-
-
-
-
 //-------------------------------------------------------------------------
 // CommandObjectTypeFormatDelete
 //-------------------------------------------------------------------------
@@ -1264,26 +1253,11 @@ public:
     }
 };
 
-//-------------------------------------------------------------------------
-// CommandObjectTypeFormatList
-//-------------------------------------------------------------------------
-
-bool CommandObjectTypeFormatList_LoopCallback(void* pt2self, ConstString type, const lldb::TypeFormatImplSP& entry);
-bool CommandObjectTypeRXFormatList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const lldb::TypeFormatImplSP& entry);
-
-class CommandObjectTypeFormatList;
-
-struct CommandObjectTypeFormatList_LoopCallbackParam {
-    CommandObjectTypeFormatList* self;
-    CommandReturnObject* result;
-    RegularExpression* regex;
-    RegularExpression* cate_regex;
-    CommandObjectTypeFormatList_LoopCallbackParam(CommandObjectTypeFormatList* S, CommandReturnObject* R,
-                                            RegularExpression* X = NULL, RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {}
-};
-
-class CommandObjectTypeFormatList : public CommandObjectParsed
+template <typename FormatterType>
+class CommandObjectTypeFormatterList : public CommandObjectParsed
 {
+    typedef typename FormatterType::SharedPointer FormatterSharedPointer;
+
     class CommandOptions : public Options
     {
     public:
@@ -1323,6 +1297,12 @@ class CommandObjectTypeFormatList : publ
         const OptionDefinition*
         GetDefinitions () override
         {
+            static OptionDefinition g_option_table[] =
+            {
+                { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,  "Only show categories matching this filter."},
+                { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+            };
+
             return g_option_table;
         }
         
@@ -1345,10 +1325,12 @@ class CommandObjectTypeFormatList : publ
     }
 
 public:
-    CommandObjectTypeFormatList (CommandInterpreter &interpreter) :
+    CommandObjectTypeFormatterList (CommandInterpreter &interpreter,
+                                    const char* name,
+                                    const char* help) :
         CommandObjectParsed (interpreter,
-                             "type format list",
-                             "Show a list of current formatting styles.",
+                             name,
+                             help,
                              NULL),
     m_options(interpreter)
     {
@@ -1363,115 +1345,141 @@ public:
         m_arguments.push_back (type_arg);
     }
     
-    ~CommandObjectTypeFormatList () override
+    ~CommandObjectTypeFormatterList () override
     {
     }
     
 protected:
+    virtual void
+    FormatterSpecificList (CommandReturnObject &result)
+    {
+    }
+    
     bool
     DoExecute (Args& command, CommandReturnObject &result) override
     {
         const size_t argc = command.GetArgumentCount();
         
-        CommandObjectTypeFormatList_LoopCallbackParam *param;
-        RegularExpression* cate_regex =
-        m_options.m_category_regex.empty() ? NULL :
-        new RegularExpression(m_options.m_category_regex.c_str());
+        std::unique_ptr<RegularExpression> category_regex;
+        std::unique_ptr<RegularExpression> formatter_regex;
+        
+        if (m_options.m_category_regex.size() > 0)
+        {
+            category_regex.reset(new RegularExpression());
+            if (!category_regex->Compile(m_options.m_category_regex.c_str()))
+            {
+                result.AppendErrorWithFormat("syntax error in category regular expression '%s'", m_options.m_category_regex.c_str());
+                result.SetStatus(eReturnStatusFailed);
+                return false;
+            }
+        }
         
         if (argc == 1)
         {
-            RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
-            regex->Compile(command.GetArgumentAtIndex(0));
-            param = new CommandObjectTypeFormatList_LoopCallbackParam(this,&result,regex,cate_regex);
+            const char* arg = command.GetArgumentAtIndex(1);
+            formatter_regex.reset(new RegularExpression());
+            if (!formatter_regex->Compile(arg))
+            {
+                result.AppendErrorWithFormat("syntax error in regular expression '%s'", arg);
+                result.SetStatus(eReturnStatusFailed);
+                return false;
+            }
         }
-        else
-            param = new CommandObjectTypeFormatList_LoopCallbackParam(this,&result,NULL,cate_regex);
         
-        DataVisualization::Categories::LoopThrough(PerCategoryCallback,param);
-        delete param;
+        DataVisualization::Categories::ForEach( [this, &command, &result, &category_regex, &formatter_regex] (const lldb::TypeCategoryImplSP& category) -> bool {
+            if (category_regex)
+            {
+                bool escape = true;
+                if (0 == strcmp(category->GetName(), category_regex->GetText()))
+                {
+                    escape = false;
+                }
+                else if (category_regex->Execute(category->GetName()))
+                {
+                    escape = false;
+                }
+                
+                if (escape)
+                    return true;
+            }
+
+            result.GetOutputStream().Printf("-----------------------\nCategory: %s\n-----------------------\n", category->GetName());
+            
+            typedef const std::shared_ptr<FormatterType> Bar;
+            typedef std::function<bool(ConstString,Bar)> Func1Type;
+            typedef std::function<bool(RegularExpressionSP,Bar)> Func2Type;
+
+            TypeCategoryImpl::ForEachCallbacks<FormatterType> foreach;
+            foreach.SetExact([&result, &formatter_regex] (ConstString name, const FormatterSharedPointer& format_sp) -> bool {
+                if (formatter_regex)
+                {
+                    bool escape = true;
+                    if (0 == strcmp(name.AsCString(), formatter_regex->GetText()))
+                    {
+                        escape = false;
+                    }
+                    else if (formatter_regex->Execute(name.AsCString()))
+                    {
+                        escape = false;
+                    }
+                    
+                    if (escape)
+                        return true;
+                }
+
+                result.GetOutputStream().Printf ("%s: %s\n", name.AsCString(), format_sp->GetDescription().c_str());
+                
+                return true;
+            });
 
-        if (cate_regex)
-            delete cate_regex;
+            foreach.SetWithRegex( [&result, &formatter_regex] (RegularExpressionSP regex_sp, const FormatterSharedPointer& format_sp) -> bool {
+                if (formatter_regex)
+                {
+                    bool escape = true;
+                    if (0 == strcmp(regex_sp->GetText(), formatter_regex->GetText()))
+                    {
+                        escape = false;
+                    }
+                    else if (formatter_regex->Execute(regex_sp->GetText()))
+                    {
+                        escape = false;
+                    }
+                    
+                    if (escape)
+                        return true;
+                }
+                
+                result.GetOutputStream().Printf ("%s: %s\n", regex_sp->GetText(), format_sp->GetDescription().c_str());
+                
+                return true;
+            });
+
+            category->ForEach(foreach);
+            
+            return true;
+        });
         
+        FormatterSpecificList(result);
+
         result.SetStatus(eReturnStatusSuccessFinishResult);
         return result.Succeeded();
     }
-    
-private:
-    
-    static bool
-    PerCategoryCallback(void* param_vp,
-                        const lldb::TypeCategoryImplSP& cate)
-    {
-        
-        CommandObjectTypeFormatList_LoopCallbackParam* param =
-        (CommandObjectTypeFormatList_LoopCallbackParam*)param_vp;
-        CommandReturnObject* result = param->result;
-        
-        const char* cate_name = cate->GetName();
-        
-        // if the category is disabled or empty and there is no regex, just skip it
-        if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemValue | eFormatCategoryItemRegexValue) == 0) && param->cate_regex == NULL)
-            return true;
-        
-        // if we have a regex and this category does not match it, just skip it
-        if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false)
-            return true;
-        
-        result->GetOutputStream().Printf("-----------------------\nCategory: %s\n-----------------------\n", cate->GetDescription().c_str());
-        
-        cate->GetTypeFormatsContainer()->LoopThrough(CommandObjectTypeFormatList_LoopCallback, param_vp);
-        
-        if (cate->GetRegexTypeFormatsContainer()->GetCount() > 0)
-        {
-            result->GetOutputStream().Printf("Regex-based formats (slower):\n");
-            cate->GetRegexTypeFormatsContainer()->LoopThrough(CommandObjectTypeRXFormatList_LoopCallback, param_vp);
-        }
-        return true;
-    }
-    
-    
-    bool
-    LoopCallback (const char* type,
-                  const lldb::TypeFormatImplSP& entry,
-                  RegularExpression* regex,
-                  CommandReturnObject *result)
-    {
-        if (regex == NULL || strcmp(type,regex->GetText()) == 0 || regex->Execute(type))
-            result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str());
-        return true;
-    }
-    
-    friend bool CommandObjectTypeFormatList_LoopCallback(void* pt2self, ConstString type, const lldb::TypeFormatImplSP& entry);
-    friend bool CommandObjectTypeRXFormatList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const lldb::TypeFormatImplSP& entry);
-    
 };
 
-bool
-CommandObjectTypeFormatList_LoopCallback (
-                                    void* pt2self,
-                                    ConstString type,
-                                    const lldb::TypeFormatImplSP& entry)
-{
-    CommandObjectTypeFormatList_LoopCallbackParam* param = (CommandObjectTypeFormatList_LoopCallbackParam*)pt2self;
-    return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result);
-}
-
-bool
-CommandObjectTypeRXFormatList_LoopCallback (
-                                             void* pt2self,
-                                             lldb::RegularExpressionSP regex,
-                                             const lldb::TypeFormatImplSP& entry)
-{
-    CommandObjectTypeFormatList_LoopCallbackParam* param = (CommandObjectTypeFormatList_LoopCallbackParam*)pt2self;
-    return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result);
-}
+//-------------------------------------------------------------------------
+// CommandObjectTypeFormatList
+//-------------------------------------------------------------------------
 
-OptionDefinition
-CommandObjectTypeFormatList::CommandOptions::g_option_table[] =
+class CommandObjectTypeFormatList : public CommandObjectTypeFormatterList<TypeFormatImpl>
 {
-    { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,  "Only show categories matching this filter."},
-    { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+public:
+    
+    CommandObjectTypeFormatList (CommandInterpreter &interpreter) :
+        CommandObjectTypeFormatterList(interpreter,
+                                       "type format list",
+                                       "Show a list of current formats.")
+    {
+    }
 };
 
 #ifndef LLDB_DISABLE_PYTHON
@@ -2046,226 +2054,30 @@ protected:
 // CommandObjectTypeSummaryList
 //-------------------------------------------------------------------------
 
-bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, ConstString type, const StringSummaryFormat::SharedPointer& entry);
-bool CommandObjectTypeRXSummaryList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const StringSummaryFormat::SharedPointer& entry);
-
-class CommandObjectTypeSummaryList;
-
-struct CommandObjectTypeSummaryList_LoopCallbackParam {
-    CommandObjectTypeSummaryList* self;
-    CommandReturnObject* result;
-    RegularExpression* regex;
-    RegularExpression* cate_regex;
-    CommandObjectTypeSummaryList_LoopCallbackParam(CommandObjectTypeSummaryList* S, CommandReturnObject* R,
-                                                  RegularExpression* X = NULL,
-                                                  RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {}
-};
-
-class CommandObjectTypeSummaryList : public CommandObjectParsed
+class CommandObjectTypeSummaryList : public CommandObjectTypeFormatterList<TypeSummaryImpl>
 {
-    
-    class CommandOptions : public Options
-    {
-    public:
-        
-        CommandOptions (CommandInterpreter &interpreter) :
-        Options (interpreter)
-        {
-        }
-        
-        ~CommandOptions () override {}
-        
-        Error
-        SetOptionValue (uint32_t option_idx, const char *option_arg) override
-        {
-            Error error;
-            const int short_option = m_getopt_table[option_idx].val;
-            
-            switch (short_option)
-            {
-                case 'w':
-                    m_category_regex = std::string(option_arg);
-                    break;
-                default:
-                    error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
-                    break;
-            }
-            
-            return error;
-        }
-        
-        void
-        OptionParsingStarting () override
-        {
-            m_category_regex = "";
-        }
-        
-        const OptionDefinition*
-        GetDefinitions () override
-        {
-            return g_option_table;
-        }
-        
-        // Options table: Required for subclasses of Options.
-        
-        static OptionDefinition g_option_table[];
-        
-        // Instance variables to hold the values for command options.
-        
-        std::string m_category_regex;
-        
-    };
-    
-    CommandOptions m_options;
-    
-    Options *
-    GetOptions () override
-    {
-        return &m_options;
-    }
-    
 public:
-    CommandObjectTypeSummaryList (CommandInterpreter &interpreter) :
-        CommandObjectParsed (interpreter,
-                             "type summary list",
-                             "Show a list of current summary styles.",
-                             NULL),
-        m_options(interpreter)
-    {
-        CommandArgumentEntry type_arg;
-        CommandArgumentData type_style_arg;
-        
-        type_style_arg.arg_type = eArgTypeName;
-        type_style_arg.arg_repetition = eArgRepeatOptional;
-        
-        type_arg.push_back (type_style_arg);
-        
-        m_arguments.push_back (type_arg);
-    }
     
-    ~CommandObjectTypeSummaryList () override
+    CommandObjectTypeSummaryList (CommandInterpreter &interpreter) :
+    CommandObjectTypeFormatterList(interpreter,
+                                   "type summary list",
+                                   "Show a list of current summaries.")
     {
     }
     
 protected:
-    bool
-    DoExecute (Args& command, CommandReturnObject &result) override
+    void
+    FormatterSpecificList (CommandReturnObject &result) override
     {
-        const size_t argc = command.GetArgumentCount();
-        
-        CommandObjectTypeSummaryList_LoopCallbackParam *param;
-        RegularExpression* cate_regex = 
-        m_options.m_category_regex.empty() ? NULL :
-        new RegularExpression(m_options.m_category_regex.c_str());
-        
-        if (argc == 1)
-        {
-            RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
-            regex->Compile(command.GetArgumentAtIndex(0));
-            param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,regex,cate_regex);
-        }
-        else
-            param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,NULL,cate_regex);
-        
-        DataVisualization::Categories::LoopThrough(PerCategoryCallback,param);
-        delete param;
-
         if (DataVisualization::NamedSummaryFormats::GetCount() > 0)
         {
             result.GetOutputStream().Printf("Named summaries:\n");
-            if (argc == 1)
-            {
-                RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
-                regex->Compile(command.GetArgumentAtIndex(0));
-                param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,regex);
-            }
-            else
-                param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result);
-            DataVisualization::NamedSummaryFormats::LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param);
-            delete param;
+            DataVisualization::NamedSummaryFormats::ForEach( [&result] (ConstString name, const TypeSummaryImplSP& summary_sp) -> bool {
+                result.GetOutputStream().Printf ("%s: %s\n", name.AsCString(), summary_sp->GetDescription().c_str());
+                return true;
+            });
         }
-        
-        if (cate_regex)
-            delete cate_regex;
-        
-        result.SetStatus(eReturnStatusSuccessFinishResult);
-        return result.Succeeded();
     }
-    
-private:
-    
-    static bool
-    PerCategoryCallback(void* param_vp,
-                        const lldb::TypeCategoryImplSP& cate)
-    {
-        
-        CommandObjectTypeSummaryList_LoopCallbackParam* param = 
-            (CommandObjectTypeSummaryList_LoopCallbackParam*)param_vp;
-        CommandReturnObject* result = param->result;
-        
-        const char* cate_name = cate->GetName();
-        
-        // if the category is disabled or empty and there is no regex, just skip it
-        if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary) == 0) && param->cate_regex == NULL)
-            return true;
-        
-        // if we have a regex and this category does not match it, just skip it
-        if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false)
-            return true;
-        
-        result->GetOutputStream().Printf("-----------------------\nCategory: %s\n-----------------------\n", cate->GetDescription().c_str());
-
-        cate->GetTypeSummariesContainer()->LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param_vp);
-        
-        if (cate->GetRegexTypeSummariesContainer()->GetCount() > 0)
-        {
-            result->GetOutputStream().Printf("Regex-based summaries (slower):\n");
-            cate->GetRegexTypeSummariesContainer()->LoopThrough(CommandObjectTypeRXSummaryList_LoopCallback, param_vp);
-        }
-        return true;
-    }
-
-    
-    bool
-    LoopCallback (const char* type,
-                  const lldb::TypeSummaryImplSP& entry,
-                  RegularExpression* regex,
-                  CommandReturnObject *result)
-    {
-        if (regex == NULL || strcmp(type,regex->GetText()) == 0 || regex->Execute(type))
-                result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str());
-        return true;
-    }
-    
-    friend bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, ConstString type, const lldb::TypeSummaryImplSP& entry);
-    friend bool CommandObjectTypeRXSummaryList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const lldb::TypeSummaryImplSP& entry);
-};
-
-bool
-CommandObjectTypeSummaryList_LoopCallback (
-                                          void* pt2self,
-                                          ConstString type,
-                                          const lldb::TypeSummaryImplSP& entry)
-{
-    CommandObjectTypeSummaryList_LoopCallbackParam* param = (CommandObjectTypeSummaryList_LoopCallbackParam*)pt2self;
-    return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result);
-}
-
-bool
-CommandObjectTypeRXSummaryList_LoopCallback (
-                                           void* pt2self,
-                                           lldb::RegularExpressionSP regex,
-                                           const lldb::TypeSummaryImplSP& entry)
-{
-    CommandObjectTypeSummaryList_LoopCallbackParam* param = (CommandObjectTypeSummaryList_LoopCallbackParam*)pt2self;
-    return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result);
-}
-
-OptionDefinition
-CommandObjectTypeSummaryList::CommandOptions::g_option_table[] =
-{
-    { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,  "Only show categories matching this filter."},
-    { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
 };
 
 //-------------------------------------------------------------------------
@@ -2625,274 +2437,20 @@ protected:
             return result.Succeeded();
         }
         else
-        {
-            result.AppendError("cannot delete one or more categories\n");
-            result.SetStatus(eReturnStatusFailed);
-            return false;
-        }
-    }
-};
-
-//-------------------------------------------------------------------------
-// CommandObjectTypeCategoryDisable
-//-------------------------------------------------------------------------
-
-class CommandObjectTypeCategoryDisable : public CommandObjectParsed
-{
-    class CommandOptions : public Options
-    {
-    public:
-        
-        CommandOptions (CommandInterpreter &interpreter) :
-        Options (interpreter)
-        {
-        }
-        
-        ~CommandOptions () override {}
-        
-        Error
-        SetOptionValue (uint32_t option_idx, const char *option_arg) override
-        {
-            Error error;
-            const int short_option = m_getopt_table[option_idx].val;
-            
-            switch (short_option)
-            {
-                case 'l':
-                    if (option_arg)
-                    {
-                        m_language = Language::GetLanguageTypeFromString(option_arg);
-                        if (m_language == lldb::eLanguageTypeUnknown)
-                            error.SetErrorStringWithFormat ("unrecognized language '%s'", option_arg);
-                    }
-                    break;
-                default:
-                    error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
-                    break;
-            }
-            
-            return error;
-        }
-        
-        void
-        OptionParsingStarting () override
-        {
-            m_language = lldb::eLanguageTypeUnknown;
-        }
-        
-        const OptionDefinition*
-        GetDefinitions () override
-        {
-            return g_option_table;
-        }
-        
-        // Options table: Required for subclasses of Options.
-        
-        static OptionDefinition g_option_table[];
-        
-        // Instance variables to hold the values for command options.
-        
-        lldb::LanguageType m_language;
-        
-    };
-    
-    CommandOptions m_options;
-    
-    Options *
-    GetOptions () override
-    {
-        return &m_options;
-    }
-
-public:
-    CommandObjectTypeCategoryDisable (CommandInterpreter &interpreter) :
-        CommandObjectParsed (interpreter,
-                             "type category disable",
-                             "Disable a category as a source of formatters.",
-                             NULL),
-        m_options(interpreter)
-    {
-        CommandArgumentEntry type_arg;
-        CommandArgumentData type_style_arg;
-        
-        type_style_arg.arg_type = eArgTypeName;
-        type_style_arg.arg_repetition = eArgRepeatPlus;
-        
-        type_arg.push_back (type_style_arg);
-        
-        m_arguments.push_back (type_arg);
-        
-    }
-    
-    ~CommandObjectTypeCategoryDisable () override
-    {
-    }
-    
-protected:
-    bool
-    DoExecute (Args& command, CommandReturnObject &result) override
-    {
-        const size_t argc = command.GetArgumentCount();
-        
-        if (argc < 1 &&
-            m_options.m_language == lldb::eLanguageTypeUnknown)
-        {
-            result.AppendErrorWithFormat ("%s takes arguments and/or a language", m_cmd_name.c_str());
-            result.SetStatus(eReturnStatusFailed);
-            return false;
-        }
-        
-        if (argc == 1 && strcmp(command.GetArgumentAtIndex(0),"*") == 0)
-        {
-            DataVisualization::Categories::DisableStar();
-        }
-        else if (argc > 0)
-        {
-            // the order is not relevant here
-            for (int i = argc - 1; i >= 0; i--)
-            {
-                const char* typeA = command.GetArgumentAtIndex(i);
-                ConstString typeCS(typeA);
-                
-                if (!typeCS)
-                {
-                    result.AppendError("empty category name not allowed");
-                    result.SetStatus(eReturnStatusFailed);
-                    return false;
-                }
-                DataVisualization::Categories::Disable(typeCS);
-            }
-        }
-        
-        if (m_options.m_language != lldb::eLanguageTypeUnknown)
-            DataVisualization::Categories::Disable(m_options.m_language);
-
-        result.SetStatus(eReturnStatusSuccessFinishResult);
-        return result.Succeeded();
-    }
-    
-};
-
-OptionDefinition
-CommandObjectTypeCategoryDisable::CommandOptions::g_option_table[] =
-{
-    { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,  "Enable the category for this language."},
-    { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
-};
-
-//-------------------------------------------------------------------------
-// CommandObjectTypeCategoryList
-//-------------------------------------------------------------------------
-
-class CommandObjectTypeCategoryList : public CommandObjectParsed
-{
-private:
-    
-    struct CommandObjectTypeCategoryList_CallbackParam
-    {
-        CommandReturnObject* result;
-        RegularExpression* regex;
-        
-        CommandObjectTypeCategoryList_CallbackParam(CommandReturnObject* res,
-                                                    RegularExpression* rex = NULL) :
-        result(res),
-        regex(rex)
-        {
-        }
-        
-    };
-    
-    static bool
-    PerCategoryCallback(void* param_vp,
-                        const lldb::TypeCategoryImplSP& cate)
-    {
-        CommandObjectTypeCategoryList_CallbackParam* param =
-            (CommandObjectTypeCategoryList_CallbackParam*)param_vp;
-        CommandReturnObject* result = param->result;
-        RegularExpression* regex = param->regex;
-        
-        const char* cate_name = cate->GetName();
-        
-        if (regex == NULL || strcmp(cate_name, regex->GetText()) == 0 || regex->Execute(cate_name))
-            result->GetOutputStream().Printf("Category: %s\n", cate->GetDescription().c_str());
-        return true;
-    }
-public:
-    CommandObjectTypeCategoryList (CommandInterpreter &interpreter) :
-        CommandObjectParsed (interpreter,
-                             "type category list",
-                             "Provide a list of all existing categories.",
-                             NULL)
-    {
-        CommandArgumentEntry type_arg;
-        CommandArgumentData type_style_arg;
-        
-        type_style_arg.arg_type = eArgTypeName;
-        type_style_arg.arg_repetition = eArgRepeatOptional;
-        
-        type_arg.push_back (type_style_arg);
-        
-        m_arguments.push_back (type_arg);
-    }
-    
-    ~CommandObjectTypeCategoryList () override
-    {
-    }
-    
-protected:
-    bool
-    DoExecute (Args& command, CommandReturnObject &result) override
-    {
-        const size_t argc = command.GetArgumentCount();
-        RegularExpression* regex = NULL;
-        
-        if (argc == 0)
-            ;
-        else if (argc == 1)
-            regex = new RegularExpression(command.GetArgumentAtIndex(0));
-        else
-        {
-            result.AppendErrorWithFormat ("%s takes 0 or one arg.\n", m_cmd_name.c_str());
-            result.SetStatus(eReturnStatusFailed);
-            return false;
-        }
-        
-        CommandObjectTypeCategoryList_CallbackParam param(&result,
-                                                          regex);
-        
-        DataVisualization::Categories::LoopThrough(PerCategoryCallback, &param);
-        
-        if (regex)
-            delete regex;
-        
-        result.SetStatus(eReturnStatusSuccessFinishResult);
-        return result.Succeeded();
+        {
+            result.AppendError("cannot delete one or more categories\n");
+            result.SetStatus(eReturnStatusFailed);
+            return false;
+        }
     }
-    
 };
 
 //-------------------------------------------------------------------------
-// CommandObjectTypeFilterList
+// CommandObjectTypeCategoryDisable
 //-------------------------------------------------------------------------
 
-bool CommandObjectTypeFilterList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry);
-bool CommandObjectTypeFilterRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry);
-
-class CommandObjectTypeFilterList;
-
-struct CommandObjectTypeFilterList_LoopCallbackParam {
-    CommandObjectTypeFilterList* self;
-    CommandReturnObject* result;
-    RegularExpression* regex;
-    RegularExpression* cate_regex;
-    CommandObjectTypeFilterList_LoopCallbackParam(CommandObjectTypeFilterList* S, CommandReturnObject* R,
-                                                  RegularExpression* X = NULL,
-                                                  RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {}
-};
-
-class CommandObjectTypeFilterList : public CommandObjectParsed
+class CommandObjectTypeCategoryDisable : public CommandObjectParsed
 {
-    
     class CommandOptions : public Options
     {
     public:
@@ -2912,8 +2470,13 @@ class CommandObjectTypeFilterList : publ
             
             switch (short_option)
             {
-                case 'w':
-                    m_category_regex = std::string(option_arg);
+                case 'l':
+                    if (option_arg)
+                    {
+                        m_language = Language::GetLanguageTypeFromString(option_arg);
+                        if (m_language == lldb::eLanguageTypeUnknown)
+                            error.SetErrorStringWithFormat ("unrecognized language '%s'", option_arg);
+                    }
                     break;
                 default:
                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
@@ -2926,7 +2489,7 @@ class CommandObjectTypeFilterList : publ
         void
         OptionParsingStarting () override
         {
-            m_category_regex = "";
+            m_language = lldb::eLanguageTypeUnknown;
         }
         
         const OptionDefinition*
@@ -2941,7 +2504,7 @@ class CommandObjectTypeFilterList : publ
         
         // Instance variables to hold the values for command options.
         
-        std::string m_category_regex;
+        lldb::LanguageType m_language;
         
     };
     
@@ -2952,12 +2515,12 @@ class CommandObjectTypeFilterList : publ
     {
         return &m_options;
     }
-    
+
 public:
-    CommandObjectTypeFilterList (CommandInterpreter &interpreter) :
+    CommandObjectTypeCategoryDisable (CommandInterpreter &interpreter) :
         CommandObjectParsed (interpreter,
-                             "type filter list",
-                             "Show a list of current filters.",
+                             "type category disable",
+                             "Disable a category as a source of formatters.",
                              NULL),
         m_options(interpreter)
     {
@@ -2965,14 +2528,15 @@ public:
         CommandArgumentData type_style_arg;
         
         type_style_arg.arg_type = eArgTypeName;
-        type_style_arg.arg_repetition = eArgRepeatOptional;
+        type_style_arg.arg_repetition = eArgRepeatPlus;
         
         type_arg.push_back (type_style_arg);
         
         m_arguments.push_back (type_arg);
+        
     }
     
-    ~CommandObjectTypeFilterList () override
+    ~CommandObjectTypeCategoryDisable () override
     {
     }
     
@@ -2982,196 +2546,64 @@ protected:
     {
         const size_t argc = command.GetArgumentCount();
         
-        CommandObjectTypeFilterList_LoopCallbackParam *param;
-        RegularExpression* cate_regex = 
-        m_options.m_category_regex.empty() ? NULL :
-        new RegularExpression(m_options.m_category_regex.c_str());
-        
-        if (argc == 1)
+        if (argc < 1 &&
+            m_options.m_language == lldb::eLanguageTypeUnknown)
         {
-            RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
-            regex->Compile(command.GetArgumentAtIndex(0));
-            param = new CommandObjectTypeFilterList_LoopCallbackParam(this,&result,regex,cate_regex);
+            result.AppendErrorWithFormat ("%s takes arguments and/or a language", m_cmd_name.c_str());
+            result.SetStatus(eReturnStatusFailed);
+            return false;
         }
-        else
-            param = new CommandObjectTypeFilterList_LoopCallbackParam(this,&result,NULL,cate_regex);
-        
-        DataVisualization::Categories::LoopThrough(PerCategoryCallback,param);
-        delete param;
-        
-        if (cate_regex)
-            delete cate_regex;
-        
-        result.SetStatus(eReturnStatusSuccessFinishResult);
-        return result.Succeeded();
-    }
-    
-private:
-    
-    static bool
-    PerCategoryCallback(void* param_vp,
-                        const lldb::TypeCategoryImplSP& cate)
-    {
-        
-        const char* cate_name = cate->GetName();
         
-        CommandObjectTypeFilterList_LoopCallbackParam* param = 
-        (CommandObjectTypeFilterList_LoopCallbackParam*)param_vp;
-        CommandReturnObject* result = param->result;
-        
-        // if the category is disabled or empty and there is no regex, just skip it
-        if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter) == 0) && param->cate_regex == NULL)
-            return true;
-        
-        // if we have a regex and this category does not match it, just skip it
-        if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false)
-            return true;
-        
-        result->GetOutputStream().Printf("-----------------------\nCategory: %s\n-----------------------\n", cate->GetDescription().c_str());
-        
-        cate->GetTypeFiltersContainer()->LoopThrough(CommandObjectTypeFilterList_LoopCallback, param_vp);
-        
-        if (cate->GetRegexTypeFiltersContainer()->GetCount() > 0)
+        if (argc == 1 && strcmp(command.GetArgumentAtIndex(0),"*") == 0)
         {
-            result->GetOutputStream().Printf("Regex-based filters (slower):\n");
-            cate->GetRegexTypeFiltersContainer()->LoopThrough(CommandObjectTypeFilterRXList_LoopCallback, param_vp);
+            DataVisualization::Categories::DisableStar();
+        }
+        else if (argc > 0)
+        {
+            // the order is not relevant here
+            for (int i = argc - 1; i >= 0; i--)
+            {
+                const char* typeA = command.GetArgumentAtIndex(i);
+                ConstString typeCS(typeA);
+                
+                if (!typeCS)
+                {
+                    result.AppendError("empty category name not allowed");
+                    result.SetStatus(eReturnStatusFailed);
+                    return false;
+                }
+                DataVisualization::Categories::Disable(typeCS);
+            }
         }
         
-        return true;
-    }
-    
-    bool
-    LoopCallback (const char* type,
-                  const SyntheticChildren::SharedPointer& entry,
-                  RegularExpression* regex,
-                  CommandReturnObject *result)
-    {
-        if (regex == NULL || regex->Execute(type))
-            result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str());
-        return true;
+        if (m_options.m_language != lldb::eLanguageTypeUnknown)
+            DataVisualization::Categories::Disable(m_options.m_language);
+
+        result.SetStatus(eReturnStatusSuccessFinishResult);
+        return result.Succeeded();
     }
     
-    friend bool CommandObjectTypeFilterList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry);
-    friend bool CommandObjectTypeFilterRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry);
 };
 
-bool
-CommandObjectTypeFilterList_LoopCallback (void* pt2self,
-                                         ConstString type,
-                                         const SyntheticChildren::SharedPointer& entry)
-{
-    CommandObjectTypeFilterList_LoopCallbackParam* param = (CommandObjectTypeFilterList_LoopCallbackParam*)pt2self;
-    return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result);
-}
-
-bool
-CommandObjectTypeFilterRXList_LoopCallback (void* pt2self,
-                                           lldb::RegularExpressionSP regex,
-                                           const SyntheticChildren::SharedPointer& entry)
-{
-    CommandObjectTypeFilterList_LoopCallbackParam* param = (CommandObjectTypeFilterList_LoopCallbackParam*)pt2self;
-    return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result);
-}
-
-
 OptionDefinition
-CommandObjectTypeFilterList::CommandOptions::g_option_table[] =
+CommandObjectTypeCategoryDisable::CommandOptions::g_option_table[] =
 {
-    { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,  "Only show categories matching this filter."},
+    { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,  "Enable the category for this language."},
     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
 };
 
-#ifndef LLDB_DISABLE_PYTHON
-
 //-------------------------------------------------------------------------
-// CommandObjectTypeSynthList
+// CommandObjectTypeCategoryList
 //-------------------------------------------------------------------------
 
-bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry);
-bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry);
-
-class CommandObjectTypeSynthList;
-
-struct CommandObjectTypeSynthList_LoopCallbackParam {
-    CommandObjectTypeSynthList* self;
-    CommandReturnObject* result;
-    RegularExpression* regex;
-    RegularExpression* cate_regex;
-    CommandObjectTypeSynthList_LoopCallbackParam(CommandObjectTypeSynthList* S, CommandReturnObject* R,
-                                                 RegularExpression* X = NULL,
-                                                 RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {}
-};
-
-class CommandObjectTypeSynthList : public CommandObjectParsed
+class CommandObjectTypeCategoryList : public CommandObjectParsed
 {
-    
-    class CommandOptions : public Options
-    {
-    public:
-        
-        CommandOptions (CommandInterpreter &interpreter) :
-        Options (interpreter)
-        {
-        }
-        
-        ~CommandOptions () override {}
-        
-        Error
-        SetOptionValue (uint32_t option_idx, const char *option_arg) override
-        {
-            Error error;
-            const int short_option = m_getopt_table[option_idx].val;
-            
-            switch (short_option)
-            {
-                case 'w':
-                    m_category_regex = std::string(option_arg);
-                    break;
-                default:
-                    error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
-                    break;
-            }
-            
-            return error;
-        }
-        
-        void
-        OptionParsingStarting () override
-        {
-            m_category_regex = "";
-        }
-        
-        const OptionDefinition*
-        GetDefinitions () override
-        {
-            return g_option_table;
-        }
-        
-        // Options table: Required for subclasses of Options.
-        
-        static OptionDefinition g_option_table[];
-        
-        // Instance variables to hold the values for command options.
-        
-        std::string m_category_regex;
-        
-    };
-    
-    CommandOptions m_options;
-    
-    Options *
-    GetOptions () override
-    {
-        return &m_options;
-    }
-    
 public:
-    CommandObjectTypeSynthList (CommandInterpreter &interpreter) :
+    CommandObjectTypeCategoryList (CommandInterpreter &interpreter) :
         CommandObjectParsed (interpreter,
-                             "type synthetic list",
-                             "Show a list of current synthetic providers.",
-                             NULL),
-        m_options(interpreter)
+                             "type category list",
+                             "Provide a list of all existing categories.",
+                             NULL)
     {
         CommandArgumentEntry type_arg;
         CommandArgumentData type_style_arg;
@@ -3184,7 +2616,7 @@ public:
         m_arguments.push_back (type_arg);
     }
     
-    ~CommandObjectTypeSynthList () override
+    ~CommandObjectTypeCategoryList () override
     {
     }
     
@@ -3193,104 +2625,87 @@ protected:
     DoExecute (Args& command, CommandReturnObject &result) override
     {
         const size_t argc = command.GetArgumentCount();
-        
-        CommandObjectTypeSynthList_LoopCallbackParam *param;
-        RegularExpression* cate_regex = 
-        m_options.m_category_regex.empty() ? NULL :
-        new RegularExpression(m_options.m_category_regex.c_str());
+
+        std::unique_ptr<RegularExpression> regex;
         
         if (argc == 1)
         {
-            RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
-            regex->Compile(command.GetArgumentAtIndex(0));
-            param = new CommandObjectTypeSynthList_LoopCallbackParam(this,&result,regex,cate_regex);
+            regex.reset(new RegularExpression());
+            const char* arg = command.GetArgumentAtIndex(0);
+            if (!regex->Compile(arg))
+            {
+                result.AppendErrorWithFormat("syntax error in category regular expression '%s'", arg);
+                result.SetStatus(eReturnStatusFailed);
+                return false;
+            }
+        }
+        else if (argc != 0)
+        {
+            result.AppendErrorWithFormat ("%s takes 0 or one arg.\n", m_cmd_name.c_str());
+            result.SetStatus(eReturnStatusFailed);
+            return false;
         }
-        else
-            param = new CommandObjectTypeSynthList_LoopCallbackParam(this,&result,NULL,cate_regex);
         
-        DataVisualization::Categories::LoopThrough(PerCategoryCallback,param);
-        delete param;
-
-        if (cate_regex)
-            delete cate_regex;
+        DataVisualization::Categories::ForEach( [&regex, &result] (const lldb::TypeCategoryImplSP& category_sp) -> bool {
+            if (regex)
+            {
+                bool escape = true;
+                if (0 == strcmp(category_sp->GetName(), regex->GetText()))
+                {
+                    escape = false;
+                }
+                else if (regex->Execute(category_sp->GetName()))
+                {
+                    escape = false;
+                }
+                
+                if (escape)
+                    return true;
+            }
+            
+            result.GetOutputStream().Printf("Category: %s\n", category_sp->GetDescription().c_str());
+            
+            return true;
+        });
         
         result.SetStatus(eReturnStatusSuccessFinishResult);
         return result.Succeeded();
     }
     
-private:
-    
-    static bool
-    PerCategoryCallback(void* param_vp,
-                        const lldb::TypeCategoryImplSP& cate)
-    {
-        
-        CommandObjectTypeSynthList_LoopCallbackParam* param = 
-        (CommandObjectTypeSynthList_LoopCallbackParam*)param_vp;
-        CommandReturnObject* result = param->result;
-        
-        const char* cate_name = cate->GetName();
-        
-        // if the category is disabled or empty and there is no regex, just skip it
-        if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth) == 0) && param->cate_regex == NULL)
-            return true;
-        
-        // if we have a regex and this category does not match it, just skip it
-        if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false)
-            return true;
-        
-        result->GetOutputStream().Printf("-----------------------\nCategory: %s\n-----------------------\n", cate->GetDescription().c_str());
-        
-        cate->GetTypeSyntheticsContainer()->LoopThrough(CommandObjectTypeSynthList_LoopCallback, param_vp);
-        
-        if (cate->GetRegexTypeSyntheticsContainer()->GetCount() > 0)
-        {
-            result->GetOutputStream().Printf("Regex-based synthetic providers (slower):\n");
-            cate->GetRegexTypeSyntheticsContainer()->LoopThrough(CommandObjectTypeSynthRXList_LoopCallback, param_vp);
-        }
-        
-        return true;
-    }
+};
+
+//-------------------------------------------------------------------------
+// CommandObjectTypeFilterList
+//-------------------------------------------------------------------------
+
+class CommandObjectTypeFilterList : public CommandObjectTypeFormatterList<TypeFilterImpl>
+{
+public:
     
-    bool
-    LoopCallback (const char* type,
-                  const SyntheticChildren::SharedPointer& entry,
-                  RegularExpression* regex,
-                  CommandReturnObject *result)
+    CommandObjectTypeFilterList (CommandInterpreter &interpreter) :
+    CommandObjectTypeFormatterList(interpreter,
+                                   "type filter list",
+                                   "Show a list of current filters.")
     {
-        if (regex == NULL || regex->Execute(type))
-            result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str());
-        return true;
     }
-    
-    friend bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry);
-    friend bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry);
 };
 
-bool
-CommandObjectTypeSynthList_LoopCallback (void* pt2self,
-                                         ConstString type,
-                                         const SyntheticChildren::SharedPointer& entry)
-{
-    CommandObjectTypeSynthList_LoopCallbackParam* param = (CommandObjectTypeSynthList_LoopCallbackParam*)pt2self;
-    return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result);
-}
-
-bool
-CommandObjectTypeSynthRXList_LoopCallback (void* pt2self,
-                                         lldb::RegularExpressionSP regex,
-                                         const SyntheticChildren::SharedPointer& entry)
-{
-    CommandObjectTypeSynthList_LoopCallbackParam* param = (CommandObjectTypeSynthList_LoopCallbackParam*)pt2self;
-    return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result);
-}
+#ifndef LLDB_DISABLE_PYTHON
 
+//-------------------------------------------------------------------------
+// CommandObjectTypeSynthList
+//-------------------------------------------------------------------------
 
-OptionDefinition
-CommandObjectTypeSynthList::CommandOptions::g_option_table[] =
+class CommandObjectTypeSynthList : public CommandObjectTypeFormatterList<SyntheticChildren>
 {
-    { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,  "Only show categories matching this filter."},
-    { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+public:
+    
+    CommandObjectTypeSynthList (CommandInterpreter &interpreter) :
+    CommandObjectTypeFormatterList(interpreter,
+                                   "type synthetic list",
+                                   "Show a list of current synthetic providers.")
+    {
+    }
 };
 
 #endif // #ifndef LLDB_DISABLE_PYTHON
@@ -3664,7 +3079,7 @@ private:
     
     bool
     AddFilter(ConstString type_name,
-              SyntheticChildrenSP entry,
+              TypeFilterImplSP entry,
               FilterFormatType type,
               std::string category_name,
               Error* error)
@@ -3787,19 +3202,15 @@ protected:
             return false;
         }
         
-        SyntheticChildrenSP entry;
-        
-        TypeFilterImpl* impl = new TypeFilterImpl(SyntheticChildren::Flags().SetCascades(m_options.m_cascade).
-                                                    SetSkipPointers(m_options.m_skip_pointers).
-                                                    SetSkipReferences(m_options.m_skip_references));
-        
-        entry.reset(impl);
+        TypeFilterImplSP entry(new TypeFilterImpl(SyntheticChildren::Flags().SetCascades(m_options.m_cascade).
+                                       SetSkipPointers(m_options.m_skip_pointers).
+                                                  SetSkipReferences(m_options.m_skip_references)));
         
         // go through the expression paths
         CommandOptions::ExpressionPathsIterator begin, end = m_options.m_expr_paths.end();
         
         for (begin = m_options.m_expr_paths.begin(); begin != end; begin++)
-            impl->AddExpressionPath(*begin);
+            entry->AddExpressionPath(*begin);
         
         
         // now I have a valid provider, let's add it to every type
@@ -4289,5 +3700,3 @@ CommandObjectType::CommandObjectType (Co
 CommandObjectType::~CommandObjectType ()
 {
 }
-
-

Modified: lldb/trunk/source/DataFormatters/DataVisualization.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/DataFormatters/DataVisualization.cpp?rev=253493&r1=253492&r2=253493&view=diff
==============================================================================
--- lldb/trunk/source/DataFormatters/DataVisualization.cpp (original)
+++ lldb/trunk/source/DataFormatters/DataVisualization.cpp Wed Nov 18 13:42:44 2015
@@ -226,12 +226,6 @@ DataVisualization::Categories::DisableSt
 }
 
 void
-DataVisualization::Categories::LoopThrough (FormatManager::CategoryCallback callback, void* callback_baton)
-{
-    GetFormatManager().LoopThroughCategories(callback, callback_baton);
-}
-
-void
 DataVisualization::Categories::ForEach (TypeCategoryMap::ForEachCallback callback)
 {
     GetFormatManager().ForEachCategory(callback);
@@ -274,9 +268,9 @@ DataVisualization::NamedSummaryFormats::
 }
 
 void
-DataVisualization::NamedSummaryFormats::LoopThrough (TypeSummaryImpl::SummaryCallback callback, void* callback_baton)
+DataVisualization::NamedSummaryFormats::ForEach (std::function<bool(ConstString, const lldb::TypeSummaryImplSP&)> callback)
 {
-    GetFormatManager().GetNamedSummaryContainer().LoopThrough(callback, callback_baton);
+    GetFormatManager().GetNamedSummaryContainer().ForEach(callback);
 }
 
 uint32_t

Modified: lldb/trunk/source/DataFormatters/FormatManager.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/DataFormatters/FormatManager.cpp?rev=253493&r1=253492&r2=253493&view=diff
==============================================================================
--- lldb/trunk/source/DataFormatters/FormatManager.cpp (original)
+++ lldb/trunk/source/DataFormatters/FormatManager.cpp Wed Nov 18 13:42:44 2015
@@ -486,21 +486,6 @@ FormatManager::GetValidatorForType (lldb
 }
 
 void
-FormatManager::LoopThroughCategories (CategoryCallback callback, void* param)
-{
-    m_categories_map.LoopThrough(callback, param);
-    Mutex::Locker locker(m_language_categories_mutex);
-    for (const auto& entry : m_language_categories_map)
-    {
-        if (auto category_sp = entry.second->GetCategory())
-        {
-            if (!callback(param, category_sp))
-                break;
-        }
-    }
-}
-
-void
 FormatManager::ForEachCategory(TypeCategoryMap::ForEachCallback callback)
 {
     m_categories_map.ForEach(callback);

Modified: lldb/trunk/source/DataFormatters/TypeCategoryMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/DataFormatters/TypeCategoryMap.cpp?rev=253493&r1=253492&r2=253493&view=diff
==============================================================================
--- lldb/trunk/source/DataFormatters/TypeCategoryMap.cpp (original)
+++ lldb/trunk/source/DataFormatters/TypeCategoryMap.cpp Wed Nov 18 13:42:44 2015
@@ -373,39 +373,6 @@ TypeCategoryMap::GetValidator (Formatter
 }
 
 void
-TypeCategoryMap::LoopThrough(CallbackType callback, void* param)
-{
-    if (callback)
-    {
-        Mutex::Locker locker(m_map_mutex);
-        
-        // loop through enabled categories in respective order
-        {
-            ActiveCategoriesIterator begin, end = m_active_categories.end();
-            for (begin = m_active_categories.begin(); begin != end; begin++)
-            {
-                lldb::TypeCategoryImplSP category = *begin;
-                if (!callback(param, category))
-                    break;
-            }
-        }
-        
-        // loop through disabled categories in just any order
-        {
-            MapIterator pos, end = m_map.end();
-            for (pos = m_map.begin(); pos != end; pos++)
-            {
-                if (pos->second->IsEnabled())
-                    continue;
-                KeyType type = pos->first;
-                if (!callback(param, pos->second))
-                    break;
-            }
-        }
-    }
-}
-
-void
 TypeCategoryMap::ForEach(ForEachCallback callback)
 {
     if (callback)




More information about the lldb-commits mailing list