[Lldb-commits] [lldb] r137416 - in /lldb/trunk: include/lldb/Core/ include/lldb/Interpreter/ include/lldb/Target/ source/API/ source/Commands/ source/Core/ source/Interpreter/ source/Target/ test/functionalities/data-formatter/data-formatter-advanced/ test/functionalities/data-formatter/data-formatter-categories/ test/functionalities/data-formatter/data-formatter-python-synth/ test/functionalities/data-formatter/data-formatter-synth/

Enrico Granata granata.enrico at gmail.com
Thu Aug 11 19:00:07 PDT 2011


Author: enrico
Date: Thu Aug 11 21:00:06 2011
New Revision: 137416

URL: http://llvm.org/viewvc/llvm-project?rev=137416&view=rev
Log:
*Some more optimizations in usage of ConstString
*New setting target.max-children-count gives an upper-bound to the number of child objects that will be displayed at each depth-level
  This might be a breaking change in some scenarios. To override the new limit you can use the --show-all-children (-A) option
  to frame variable or increase the limit in your lldbinit file
*Command "type synthetic" has been split in two:
  - "type synthetic" now only handles Python synthetic children providers
  - the new command "type filter" handles filters
  Because filters and synthetic providers are both ways to replace the children of a ValueObject, only one can be effective at any given time.

Modified:
    lldb/trunk/include/lldb/Core/FormatClasses.h
    lldb/trunk/include/lldb/Core/FormatManager.h
    lldb/trunk/include/lldb/Core/ValueObject.h
    lldb/trunk/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h
    lldb/trunk/include/lldb/Target/Target.h
    lldb/trunk/source/API/SBValue.cpp
    lldb/trunk/source/Commands/CommandObjectExpression.cpp
    lldb/trunk/source/Commands/CommandObjectFrame.cpp
    lldb/trunk/source/Commands/CommandObjectMemory.cpp
    lldb/trunk/source/Commands/CommandObjectTarget.cpp
    lldb/trunk/source/Commands/CommandObjectType.cpp
    lldb/trunk/source/Commands/CommandObjectType.h
    lldb/trunk/source/Core/Debugger.cpp
    lldb/trunk/source/Core/FormatManager.cpp
    lldb/trunk/source/Core/ValueObject.cpp
    lldb/trunk/source/Interpreter/OptionGroupValueObjectDisplay.cpp
    lldb/trunk/source/Target/Target.cpp
    lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py
    lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/main.cpp
    lldb/trunk/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py
    lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py
    lldb/trunk/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py

Modified: lldb/trunk/include/lldb/Core/FormatClasses.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/FormatClasses.h?rev=137416&r1=137415&r2=137416&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/FormatClasses.h (original)
+++ lldb/trunk/include/lldb/Core/FormatClasses.h Thu Aug 11 21:00:06 2011
@@ -40,6 +40,7 @@
 
 struct ValueFormat
 {
+    uint32_t m_my_revision;
     bool m_cascades;
     bool m_skip_pointers;
     bool m_skip_references;
@@ -123,6 +124,7 @@
 class SyntheticChildren
 {
 public:
+    uint32_t m_my_revision;
     bool m_cascades;
     bool m_skip_pointers;
     bool m_skip_references;
@@ -157,6 +159,9 @@
         return m_skip_references;
     }
     
+    virtual bool
+    IsScripted() = 0;
+    
     virtual std::string
     GetDescription() = 0;
     
@@ -207,6 +212,12 @@
         return m_expression_paths[i];
     }
     
+    bool
+    IsScripted()
+    {
+        return false;
+    }
+    
     std::string
     GetDescription();
     
@@ -289,6 +300,12 @@
     std::string
     GetDescription();
     
+    bool
+    IsScripted()
+    {
+        return true;
+    }
+    
     class FrontEnd : public SyntheticChildrenFrontEnd
     {
     private:
@@ -367,6 +384,7 @@
 
 struct SummaryFormat
 {
+    uint32_t m_my_revision;
     bool m_cascades;
     bool m_skip_pointers;
     bool m_skip_references;

Modified: lldb/trunk/include/lldb/Core/FormatManager.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/FormatManager.h?rev=137416&r1=137415&r2=137416&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/FormatManager.h (original)
+++ lldb/trunk/include/lldb/Core/FormatManager.h Thu Aug 11 21:00:06 2011
@@ -74,6 +74,9 @@
     virtual
     ~IFormatChangeListener() {}
     
+    virtual uint32_t
+    GetCurrentRevision() = 0;
+    
 };
     
 template<typename KeyType, typename ValueType>
@@ -120,6 +123,11 @@
     Add(KeyType name,
         const ValueSP& entry)
     {
+        if (listener)
+            entry->m_my_revision = listener->GetCurrentRevision();
+        else
+            entry->m_my_revision = 0;
+
         Mutex::Locker(m_map_mutex);
         m_map[name] = entry;
         if (listener)
@@ -208,7 +216,8 @@
     FormatNavigator(std::string name,
                     IFormatChangeListener* lst = NULL) :
     m_format_map(lst),
-    m_name(name)
+    m_name(name),
+    m_id_cs(ConstString("id"))
     {
     }
     
@@ -266,6 +275,8 @@
     
     DISALLOW_COPY_AND_ASSIGN(FormatNavigator);
     
+    ConstString m_id_cs;
+    
     // using const char* instead of MapKeyType is necessary here
     // to make the partial template specializations below work
     bool
@@ -442,7 +453,7 @@
         if (typePtr->isObjCObjectPointerType())
         {
             if (use_dynamic != lldb::eNoDynamicValues &&
-                name.GetCString() == ConstString("id").GetCString())
+                name.GetCString() == m_id_cs.GetCString())
             {
                 if (log)
                     log->Printf("this is an ObjC 'id', let's do dynamic search");
@@ -584,6 +595,13 @@
 bool
 FormatNavigator<lldb::RegularExpressionSP, SyntheticFilter>::Delete(const char* type);
 
+template<>
+bool
+FormatNavigator<lldb::RegularExpressionSP, SyntheticScriptProvider>::Get(const char* key, SyntheticFilter::SharedPointer& value);
+
+template<>
+bool
+FormatNavigator<lldb::RegularExpressionSP, SyntheticScriptProvider>::Delete(const char* type);
     
 class CategoryMap;
     
@@ -595,16 +613,23 @@
     typedef FormatNavigator<const char*, SyntheticFilter> FilterNavigator;
     typedef FormatNavigator<lldb::RegularExpressionSP, SyntheticFilter> RegexFilterNavigator;
     
+    typedef FormatNavigator<const char*, SyntheticScriptProvider> SynthNavigator;
+    typedef FormatNavigator<lldb::RegularExpressionSP, SyntheticScriptProvider> RegexSynthNavigator;
+
     typedef SummaryNavigator::MapType SummaryMap;
     typedef RegexSummaryNavigator::MapType RegexSummaryMap;
     typedef FilterNavigator::MapType FilterMap;
     typedef RegexFilterNavigator::MapType RegexFilterMap;
-        
+    typedef SynthNavigator::MapType SynthMap;
+    typedef RegexSynthNavigator::MapType RegexSynthMap;
+
     SummaryNavigator::SharedPointer m_summary_nav;
     RegexSummaryNavigator::SharedPointer m_regex_summary_nav;
     FilterNavigator::SharedPointer m_filter_nav;
     RegexFilterNavigator::SharedPointer m_regex_filter_nav;
-    
+    SynthNavigator::SharedPointer m_synth_nav;
+    RegexSynthNavigator::SharedPointer m_regex_synth_nav;
+
     bool m_enabled;
     
     IFormatChangeListener* m_change_listener;
@@ -638,6 +663,8 @@
         eRegexSummary =    0x1001,
         eFilter =          0x0002,
         eRegexFilter =     0x1002,
+        eSynth =           0x0004,
+        eRegexSynth =      0x1004,
     };
     
     typedef uint16_t FormatCategoryItems;
@@ -647,13 +674,17 @@
     typedef RegexSummaryNavigator::SharedPointer RegexSummaryNavigatorSP;
     typedef FilterNavigator::SharedPointer FilterNavigatorSP;
     typedef RegexFilterNavigator::SharedPointer RegexFilterNavigatorSP;
-    
+    typedef SynthNavigator::SharedPointer SynthNavigatorSP;
+    typedef RegexSynthNavigator::SharedPointer RegexSynthNavigatorSP;
+
     FormatCategory(IFormatChangeListener* clist,
                    std::string name) :
     m_summary_nav(new SummaryNavigator("summary",clist)),
     m_regex_summary_nav(new RegexSummaryNavigator("regex-summary",clist)),
     m_filter_nav(new FilterNavigator("filter",clist)),
     m_regex_filter_nav(new RegexFilterNavigator("regex-filter",clist)),
+    m_synth_nav(new SynthNavigator("synth",clist)),
+    m_regex_synth_nav(new RegexSynthNavigator("regex-synth",clist)),
     m_enabled(false),
     m_change_listener(clist),
     m_mutex(Mutex::eMutexTypeRecursive),
@@ -684,6 +715,18 @@
         return RegexFilterNavigatorSP(m_regex_filter_nav);
     }
     
+    SynthNavigatorSP
+    Synth()
+    {
+        return SynthNavigatorSP(m_synth_nav);
+    }
+    
+    RegexSynthNavigatorSP
+    RegexSynth()
+    {
+        return RegexSynthNavigatorSP(m_regex_synth_nav);
+    }
+    
     bool
     IsEnabled() const
     {
@@ -714,12 +757,53 @@
     {
         if (!IsEnabled())
             return false;
-        if (Filter()->Get(vobj, entry, use_dynamic, reason))
+        SyntheticFilter::SharedPointer filter;
+        SyntheticScriptProvider::SharedPointer synth;
+        bool regex_filter, regex_synth;
+        uint32_t reason_filter;
+        uint32_t reason_synth;
+        
+        bool pick_synth = false;
+        
+        // first find both Filter and Synth, and then check which is most recent
+        
+        if (!Filter()->Get(vobj, filter, use_dynamic, &reason_filter))
+            regex_filter = RegexFilter()->Get(vobj, filter, use_dynamic, &reason_filter);
+        
+        if (!Synth()->Get(vobj, synth, use_dynamic, &reason_synth))
+            regex_synth = RegexSynth()->Get(vobj, synth, use_dynamic, &reason_synth);
+        
+        if (!filter.get() && !synth.get())
+            return false;
+        
+        else if (!filter.get() && synth.get())
+            pick_synth = true;
+
+        else if (filter.get() && !synth.get())
+            pick_synth = false;
+        
+        else /*if (filter.get() && synth.get())*/
+        {
+            if (filter->m_my_revision > synth->m_my_revision)
+                pick_synth = false;
+            else
+                pick_synth = true;
+        }
+        
+        if (pick_synth)
+        {
+            if (regex_synth && reason)
+                *reason |= lldb::eFormatterChoiceCriterionRegularExpressionFilter;
+            entry = synth;
             return true;
-        bool regex = RegexFilter()->Get(vobj, entry, use_dynamic, reason);
-        if (regex && reason)
-            *reason |= lldb::eFormatterChoiceCriterionRegularExpressionFilter;
-        return regex;
+        }
+        else
+        {
+            if (regex_filter && reason)
+                *reason |= lldb::eFormatterChoiceCriterionRegularExpressionFilter;
+            entry = filter;
+            return true;
+        }
     }
     
     // just a shortcut for Summary()->Clear; RegexSummary()->Clear()
@@ -748,6 +832,10 @@
             m_filter_nav->Clear();
         if ( (items & eRegexFilter) )
             m_regex_filter_nav->Clear();
+        if ( (items & eSynth) )
+            m_synth_nav->Clear();
+        if ( (items & eRegexSynth) )
+            m_regex_synth_nav->Clear();
     }
     
     bool
@@ -763,6 +851,10 @@
             success = m_filter_nav->Delete(name) || success;
         if ( (items & eRegexFilter) )
             success = m_regex_filter_nav->Delete(name) || success;
+        if ( (items & eSynth) )
+            success = m_synth_nav->Delete(name) || success;
+        if ( (items & eRegexSynth) )
+            success = m_regex_synth_nav->Delete(name) || success;
         return success;
     }
     
@@ -778,6 +870,10 @@
             count += m_filter_nav->GetCount();
         if ( (items & eRegexFilter) )
             count += m_regex_filter_nav->GetCount();
+        if ( (items & eSynth) )
+            count += m_synth_nav->GetCount();
+        if ( (items & eRegexSynth) )
+            count += m_regex_synth_nav->GetCount();
         return count;
     }
     
@@ -1048,7 +1144,12 @@
     const char* m_system_category_name;
         
     typedef CategoryMap::MapType::iterator CategoryMapIterator;
-        
+    
+    ConstString m_default_cs;
+    ConstString m_system_cs;
+    ConstString m_charstar_cs;
+    ConstString m_constcharstar_cs;
+
 public:
     
     typedef bool (*CategoryCallback)(void*, const char*, const FormatCategory::SharedPointer&);
@@ -1057,13 +1158,17 @@
     m_value_nav("format",this),
     m_named_summaries_map(this),
     m_last_revision(0),
-    m_categories_map(this)
+    m_categories_map(this),
+    m_default_cs(ConstString("default")),
+    m_system_cs(ConstString("system")), 
+    m_charstar_cs(ConstString("char *")),
+    m_constcharstar_cs(ConstString("const char *"))
     {
         
         // build default categories
         
-        m_default_category_name = ConstString("default").GetCString();
-        m_system_category_name = ConstString("system").GetCString();
+        m_default_category_name = m_default_cs.GetCString();
+        m_system_category_name = m_system_cs.GetCString();
 
         // add some default stuff
         // most formats, summaries, ... actually belong to the users' lldbinit file rather than here
@@ -1087,8 +1192,8 @@
         lldb::RegularExpressionSP any_size_char_arr(new RegularExpression("char \\[[0-9]+\\]"));
         
         
-        Category(m_system_category_name)->Summary()->Add(ConstString("char *").GetCString(), string_format);
-        Category(m_system_category_name)->Summary()->Add(ConstString("const char *").GetCString(), string_format);
+        Category(m_system_category_name)->Summary()->Add(m_charstar_cs.GetCString(), string_format);
+        Category(m_system_category_name)->Summary()->Add(m_constcharstar_cs.GetCString(), string_format);
         Category(m_system_category_name)->RegexSummary()->Add(any_size_char_arr, string_array_format);
         
         Category(m_default_category_name); // this call is there to force LLDB into creating an empty "default" category
@@ -1184,7 +1289,7 @@
     }
     
     uint32_t
-    GetCurrentRevision() const
+    GetCurrentRevision()
     {
         return m_last_revision;
     }

Modified: lldb/trunk/include/lldb/Core/ValueObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=137416&r1=137415&r2=137416&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObject.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObject.h Thu Aug 11 21:00:06 2011
@@ -631,7 +631,8 @@
                      bool use_synthetic,
                      bool scope_already_checked,
                      bool flat_output,
-                     uint32_t omit_summary_depth);
+                     uint32_t omit_summary_depth,
+                     bool ignore_cap);
     
     // returns true if this is a char* or a char[]
     // if it is a char* and check_pointer is true,

Modified: lldb/trunk/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h?rev=137416&r1=137415&r2=137416&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h (original)
+++ lldb/trunk/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h Thu Aug 11 21:00:06 2011
@@ -56,6 +56,7 @@
     lldb::DynamicValueType use_dynamic;
     bool use_synth;
     bool be_raw;
+    bool ignore_cap;
 };
 
 } // namespace lldb_private

Modified: lldb/trunk/include/lldb/Target/Target.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=137416&r1=137415&r2=137416&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Target.h (original)
+++ lldb/trunk/include/lldb/Target/Target.h Thu Aug 11 21:00:06 2011
@@ -86,6 +86,12 @@
         return m_source_map;
     }
     
+    uint32_t
+    GetMaximumNumberOfChildrenToDisplay()
+    {
+        return m_max_children_display;
+    }
+    
 protected:
 
     void
@@ -100,6 +106,7 @@
     int                m_prefer_dynamic_value;
     OptionValueBoolean m_skip_prologue;
     PathMappingList m_source_map;
+    uint32_t m_max_children_display;
     
 
 };

Modified: lldb/trunk/source/API/SBValue.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBValue.cpp?rev=137416&r1=137415&r2=137416&view=diff
==============================================================================
--- lldb/trunk/source/API/SBValue.cpp (original)
+++ lldb/trunk/source/API/SBValue.cpp Thu Aug 11 21:00:06 2011
@@ -934,6 +934,7 @@
         bool flat_output = false;
         bool use_synthetic = true;
         uint32_t no_summary_depth = 0;
+        bool ignore_cap = false;
         ValueObject::DumpValueObject (description.ref(), 
                                       m_opaque_sp.get(), 
                                       m_opaque_sp->GetName().GetCString(), 
@@ -946,7 +947,8 @@
                                       use_synthetic,
                                       scope_already_checked, 
                                       flat_output,
-                                      no_summary_depth);
+                                      no_summary_depth,
+                                      ignore_cap);
     }
     else
         description.Printf ("No value");

Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=137416&r1=137415&r2=137416&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Thu Aug 11 21:00:06 2011
@@ -340,7 +340,8 @@
                                               true,                     // Use synthetic children if available
                                               true,                     // Scope is already checked. Const results are always in scope.
                                               false,                    // Don't flatten output
-                                              0);                       // Always use summaries (you might want an option --no-summary like there is for frame variable)
+                                              0,                        // Always use summaries (you might want an option --no-summary like there is for frame variable)
+                                              false);                   // Do not show more children than settings allow
                 if (result)
                     result->SetStatus (eReturnStatusSuccessFinishResult);
             }

Modified: lldb/trunk/source/Commands/CommandObjectFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectFrame.cpp?rev=137416&r1=137415&r2=137416&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectFrame.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectFrame.cpp Thu Aug 11 21:00:06 2011
@@ -502,7 +502,8 @@
                                                                               m_varobj_options.be_raw ? false : m_varobj_options.use_synth,
                                                                               false,
                                                                               m_varobj_options.flat_output,
-                                                                              m_varobj_options.be_raw ? UINT32_MAX : m_varobj_options.no_summary_depth);                                        
+                                                                              m_varobj_options.be_raw ? UINT32_MAX : m_varobj_options.no_summary_depth,
+                                                                              m_varobj_options.be_raw ? true : m_varobj_options.ignore_cap);                                        
                                             }
                                         }
                                     }
@@ -555,7 +556,8 @@
                                                               m_varobj_options.be_raw ? false : m_varobj_options.use_synth,
                                                               false,
                                                               m_varobj_options.flat_output,
-                                                              m_varobj_options.be_raw ? UINT32_MAX : m_varobj_options.no_summary_depth);
+                                                              m_varobj_options.be_raw ? UINT32_MAX : m_varobj_options.no_summary_depth,
+                                                              m_varobj_options.be_raw ? true : m_varobj_options.ignore_cap);
                             }
                             else
                             {
@@ -647,7 +649,8 @@
                                                                       m_varobj_options.be_raw ? false : m_varobj_options.use_synth,
                                                                       false,
                                                                       m_varobj_options.flat_output,
-                                                                      m_varobj_options.be_raw ? UINT32_MAX : m_varobj_options.no_summary_depth);                                        
+                                                                      m_varobj_options.be_raw ? UINT32_MAX : m_varobj_options.no_summary_depth,
+                                                                      m_varobj_options.be_raw ? true : m_varobj_options.ignore_cap);                                        
                                     }
                                 }
                             }

Modified: lldb/trunk/source/Commands/CommandObjectMemory.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectMemory.cpp?rev=137416&r1=137415&r2=137416&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectMemory.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectMemory.cpp Thu Aug 11 21:00:06 2011
@@ -660,7 +660,8 @@
                                                   m_varobj_options.be_raw ? false : m_varobj_options.use_synth,
                                                   scope_already_checked,
                                                   m_varobj_options.flat_output,
-                                                  m_varobj_options.be_raw ? UINT32_MAX : 0);
+                                                  m_varobj_options.be_raw ? UINT32_MAX : m_varobj_options.no_summary_depth,
+                                                  m_varobj_options.be_raw ? true : m_varobj_options.ignore_cap);
                 }
                 else
                 {

Modified: lldb/trunk/source/Commands/CommandObjectTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectTarget.cpp?rev=137416&r1=137415&r2=137416&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectTarget.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectTarget.cpp Thu Aug 11 21:00:06 2011
@@ -607,7 +607,8 @@
                                       m_varobj_options.be_raw ? false : m_varobj_options.use_synth,
                                       false,
                                       m_varobj_options.flat_output,
-                                      m_varobj_options.be_raw ? UINT32_MAX : m_varobj_options.no_summary_depth);                                        
+                                      m_varobj_options.be_raw ? UINT32_MAX : m_varobj_options.no_summary_depth,
+                                      m_varobj_options.be_raw ? true : m_varobj_options.ignore_cap);                                        
 
     }
     

Modified: lldb/trunk/source/Commands/CommandObjectType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectType.cpp?rev=137416&r1=137415&r2=137416&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectType.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectType.cpp Thu Aug 11 21:00:06 2011
@@ -1121,7 +1121,7 @@
                     m_delete_all = true;
                     break;
                 case 'w':
-                    m_category = ConstString(option_arg).GetCString();
+                    m_category = std::string(option_arg);
                     break;
                 default:
                     error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
@@ -1135,7 +1135,7 @@
         OptionParsingStarting ()
         {
             m_delete_all = false;
-            m_category = NULL;
+            m_category = "default";
         }
         
         const OptionDefinition*
@@ -1151,7 +1151,7 @@
         // Instance variables to hold the values for command options.
         
         bool m_delete_all;
-        const char* m_category;
+        std::string m_category;
         
     };
     
@@ -1226,7 +1226,7 @@
         }
         
         lldb::FormatCategorySP category;
-        Debugger::Formatting::Categories::Get(ConstString(m_options.m_category), category);
+        Debugger::Formatting::Categories::Get(ConstString(m_options.m_category.c_str()), category);
         
         bool delete_category = category->DeleteSummaries(typeCS.GetCString());
         bool delete_named = Debugger::Formatting::NamedSummaryFormats::Delete(typeCS);
@@ -1888,11 +1888,219 @@
 };
 
 //-------------------------------------------------------------------------
+// CommandObjectTypeFilterList
+//-------------------------------------------------------------------------
+
+bool CommandObjectTypeFilterList_LoopCallback(void* pt2self, const char* 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 CommandObject
+{
+    
+    class CommandOptions : public Options
+    {
+    public:
+        
+        CommandOptions (CommandInterpreter &interpreter) :
+        Options (interpreter)
+        {
+        }
+        
+        virtual
+        ~CommandOptions (){}
+        
+        virtual Error
+        SetOptionValue (uint32_t option_idx, const char *option_arg)
+        {
+            Error error;
+            char short_option = (char) 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'.\n", short_option);
+                    break;
+            }
+            
+            return error;
+        }
+        
+        void
+        OptionParsingStarting ()
+        {
+            m_category_regex = "";
+        }
+        
+        const OptionDefinition*
+        GetDefinitions ()
+        {
+            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;
+    
+    virtual Options *
+    GetOptions ()
+    {
+        return &m_options;
+    }
+    
+public:
+    CommandObjectTypeFilterList (CommandInterpreter &interpreter) :
+    CommandObject (interpreter,
+                   "type filter list",
+                   "Show a list of current filters.",
+                   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);
+    }
+    
+    ~CommandObjectTypeFilterList ()
+    {
+    }
+    
+    bool
+    Execute (Args& command, CommandReturnObject &result)
+    {
+        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) {
+            RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
+            regex->Compile(command.GetArgumentAtIndex(0));
+            param = new CommandObjectTypeFilterList_LoopCallbackParam(this,&result,regex,cate_regex);
+        }
+        else
+            param = new CommandObjectTypeFilterList_LoopCallbackParam(this,&result,NULL,cate_regex);
+        
+        Debugger::Formatting::Categories::LoopThrough(PerCategoryCallback,param);
+        
+        if (cate_regex)
+            delete cate_regex;
+        
+        result.SetStatus(eReturnStatusSuccessFinishResult);
+        return result.Succeeded();
+    }
+    
+private:
+    
+    static bool
+    PerCategoryCallback(void* param_vp,
+                        const char* cate_name,
+                        const FormatCategory::SharedPointer& cate)
+    {
+        
+        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->Filter()->GetCount() == 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 && param->cate_regex->Execute(cate_name) == false)
+            return true;
+        
+        result->GetOutputStream().Printf("-----------------------\nCategory: %s (%s)\n-----------------------\n",
+                                         cate_name,
+                                         (cate->IsEnabled() ? "enabled" : "disabled"));
+        
+        cate->Filter()->LoopThrough(CommandObjectTypeFilterList_LoopCallback, param_vp);
+        
+        if (cate->RegexFilter()->GetCount() > 0)
+        {
+            result->GetOutputStream().Printf("Regex-based filters (slower):\n");
+            cate->RegexFilter()->LoopThrough(CommandObjectTypeFilterRXList_LoopCallback, param_vp);
+        }
+        
+        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;
+    }
+    
+    friend bool CommandObjectTypeFilterList_LoopCallback(void* pt2self, const char* type, const SyntheticChildren::SharedPointer& entry);
+    friend bool CommandObjectTypeFilterRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry);
+};
+
+bool
+CommandObjectTypeFilterList_LoopCallback (void* pt2self,
+                                         const char* type,
+                                         const SyntheticChildren::SharedPointer& entry)
+{
+    CommandObjectTypeFilterList_LoopCallbackParam* param = (CommandObjectTypeFilterList_LoopCallbackParam*)pt2self;
+    return param->self->LoopCallback(type, 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[] =
+{
+    { LLDB_OPT_SET_ALL, false, "category-regex", 'w', required_argument, NULL, 0, eArgTypeName,  "Only show categories matching this filter."},
+    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
+};
+
+//-------------------------------------------------------------------------
 // CommandObjectTypeSynthList
 //-------------------------------------------------------------------------
 
-bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, const char* type, const SyntheticFilter::SharedPointer& entry);
-bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticFilter::SharedPointer& entry);
+bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, const char* type, const SyntheticChildren::SharedPointer& entry);
+bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry);
 
 class CommandObjectTypeSynthList;
 
@@ -2032,7 +2240,7 @@
         CommandReturnObject* result = param->result;
         
         // if the category is disabled or empty and there is no regex, just skip it
-        if ((cate->IsEnabled() == false || cate->Filter()->GetCount() == 0) && param->cate_regex == NULL)
+        if ((cate->IsEnabled() == false || cate->Synth()->GetCount() == 0) && param->cate_regex == NULL)
             return true;
         
         // if we have a regex and this category does not match it, just skip it
@@ -2043,12 +2251,12 @@
                                          cate_name,
                                          (cate->IsEnabled() ? "enabled" : "disabled"));
         
-        cate->Filter()->LoopThrough(CommandObjectTypeSynthList_LoopCallback, param_vp);
+        cate->Synth()->LoopThrough(CommandObjectTypeSynthList_LoopCallback, param_vp);
         
-        if (cate->RegexFilter()->GetCount() > 0)
+        if (cate->RegexSynth()->GetCount() > 0)
         {
-            result->GetOutputStream().Printf("Regex-based filters (slower):\n");
-            cate->RegexFilter()->LoopThrough(CommandObjectTypeSynthRXList_LoopCallback, param_vp);
+            result->GetOutputStream().Printf("Regex-based synthetic providers (slower):\n");
+            cate->RegexSynth()->LoopThrough(CommandObjectTypeSynthRXList_LoopCallback, param_vp);
         }
         
         return true;
@@ -2056,23 +2264,23 @@
     
     bool
     LoopCallback (const char* type,
-                  const SyntheticFilter::SharedPointer& entry,
+                  const SyntheticChildren::SharedPointer& entry,
                   RegularExpression* regex,
                   CommandReturnObject *result)
     {
-        if (regex == NULL || regex->Execute(type)) 
+        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, const char* type, const SyntheticFilter::SharedPointer& entry);
-    friend bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticFilter::SharedPointer& entry);
+    friend bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, const char* type, const SyntheticChildren::SharedPointer& entry);
+    friend bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry);
 };
 
 bool
 CommandObjectTypeSynthList_LoopCallback (void* pt2self,
                                          const char* type,
-                                         const SyntheticFilter::SharedPointer& entry)
+                                         const SyntheticChildren::SharedPointer& entry)
 {
     CommandObjectTypeSynthList_LoopCallbackParam* param = (CommandObjectTypeSynthList_LoopCallbackParam*)pt2self;
     return param->self->LoopCallback(type, entry, param->regex, param->result);
@@ -2081,7 +2289,7 @@
 bool
 CommandObjectTypeSynthRXList_LoopCallback (void* pt2self,
                                          lldb::RegularExpressionSP regex,
-                                         const SyntheticFilter::SharedPointer& entry)
+                                         const SyntheticChildren::SharedPointer& entry)
 {
     CommandObjectTypeSynthList_LoopCallbackParam* param = (CommandObjectTypeSynthList_LoopCallbackParam*)pt2self;
     return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result);
@@ -2096,6 +2304,169 @@
 };
 
 //-------------------------------------------------------------------------
+// CommandObjectTypeFilterDelete
+//-------------------------------------------------------------------------
+
+class CommandObjectTypeFilterDelete : public CommandObject
+{
+private:
+    class CommandOptions : public Options
+    {
+    public:
+        
+        CommandOptions (CommandInterpreter &interpreter) :
+        Options (interpreter)
+        {
+        }
+        
+        virtual
+        ~CommandOptions (){}
+        
+        virtual Error
+        SetOptionValue (uint32_t option_idx, const char *option_arg)
+        {
+            Error error;
+            char short_option = (char) m_getopt_table[option_idx].val;
+            
+            switch (short_option)
+            {
+                case 'a':
+                    m_delete_all = true;
+                    break;
+                case 'w':
+                    m_category = std::string(option_arg);
+                    break;
+                default:
+                    error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
+                    break;
+            }
+            
+            return error;
+        }
+        
+        void
+        OptionParsingStarting ()
+        {
+            m_delete_all = false;
+            m_category = "default";
+        }
+        
+        const OptionDefinition*
+        GetDefinitions ()
+        {
+            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.
+        
+        bool m_delete_all;
+        std::string m_category;
+        
+    };
+    
+    CommandOptions m_options;
+    
+    virtual Options *
+    GetOptions ()
+    {
+        return &m_options;
+    }
+    
+    static bool
+    PerCategoryCallback(void* param,
+                        const char* cate_name,
+                        const FormatCategory::SharedPointer& cate)
+    {
+        const char* name = (const char*)param;
+        return cate->Delete(name, FormatCategory::eFilter | FormatCategory::eRegexFilter);
+    }
+    
+public:
+    CommandObjectTypeFilterDelete (CommandInterpreter &interpreter) :
+    CommandObject (interpreter,
+                   "type filter delete",
+                   "Delete an existing filter for a type.",
+                   NULL), m_options(interpreter)
+    {
+        CommandArgumentEntry type_arg;
+        CommandArgumentData type_style_arg;
+        
+        type_style_arg.arg_type = eArgTypeName;
+        type_style_arg.arg_repetition = eArgRepeatPlain;
+        
+        type_arg.push_back (type_style_arg);
+        
+        m_arguments.push_back (type_arg);
+        
+    }
+    
+    ~CommandObjectTypeFilterDelete ()
+    {
+    }
+    
+    bool
+    Execute (Args& command, CommandReturnObject &result)
+    {
+        const size_t argc = command.GetArgumentCount();
+        
+        if (argc != 1)
+        {
+            result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str());
+            result.SetStatus(eReturnStatusFailed);
+            return false;
+        }
+        
+        const char* typeA = command.GetArgumentAtIndex(0);
+        ConstString typeCS(typeA);
+        
+        if (!typeCS)
+        {
+            result.AppendError("empty typenames not allowed");
+            result.SetStatus(eReturnStatusFailed);
+            return false;
+        }
+        
+        if (m_options.m_delete_all)
+        {
+            Debugger::Formatting::Categories::LoopThrough(PerCategoryCallback, (void*)typeCS.GetCString());
+            result.SetStatus(eReturnStatusSuccessFinishNoResult);
+            return result.Succeeded();
+        }
+        
+        lldb::FormatCategorySP category;
+        Debugger::Formatting::Categories::Get(ConstString(m_options.m_category.c_str()), category);
+        
+        bool delete_category = category->Filter()->Delete(typeCS.GetCString());
+        delete_category = category->RegexFilter()->Delete(typeCS.GetCString()) || delete_category;
+        
+        if (delete_category)
+        {
+            result.SetStatus(eReturnStatusSuccessFinishNoResult);
+            return result.Succeeded();
+        }
+        else
+        {
+            result.AppendErrorWithFormat ("no custom synthetic provider for %s.\n", typeA);
+            result.SetStatus(eReturnStatusFailed);
+            return false;
+        }
+        
+    }
+};
+
+OptionDefinition
+CommandObjectTypeFilterDelete::CommandOptions::g_option_table[] =
+{
+    { LLDB_OPT_SET_1, false, "all", 'a', no_argument, NULL, 0, eArgTypeNone,  "Delete from every category."},
+    { LLDB_OPT_SET_2, false, "category", 'w', required_argument, NULL, 0, eArgTypeName,  "Delete from given category."},
+    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
+};
+
+//-------------------------------------------------------------------------
 // CommandObjectTypeSynthDelete
 //-------------------------------------------------------------------------
 
@@ -2126,7 +2497,7 @@
                     m_delete_all = true;
                     break;
                 case 'w':
-                    m_category = ConstString(option_arg).GetCString();
+                    m_category = std::string(option_arg);
                     break;
                 default:
                     error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
@@ -2140,7 +2511,7 @@
         OptionParsingStarting ()
         {
             m_delete_all = false;
-            m_category = NULL;
+            m_category = "default";
         }
         
         const OptionDefinition*
@@ -2156,7 +2527,7 @@
         // Instance variables to hold the values for command options.
         
         bool m_delete_all;
-        const char* m_category;
+        std::string m_category;
         
     };
     
@@ -2174,7 +2545,7 @@
                         const FormatCategory::SharedPointer& cate)
     {
         const char* name = (const char*)param;
-        return cate->Delete(name, FormatCategory::eFilter | FormatCategory::eRegexFilter);
+        return cate->Delete(name, FormatCategory::eSynth | FormatCategory::eRegexSynth);
     }
     
 public:
@@ -2230,31 +2601,158 @@
         }
         
         lldb::FormatCategorySP category;
-        Debugger::Formatting::Categories::Get(ConstString(m_options.m_category), category);
+        Debugger::Formatting::Categories::Get(ConstString(m_options.m_category.c_str()), category);
         
-        bool delete_category = category->Filter()->Delete(typeCS.GetCString());
-        delete_category = category->RegexFilter()->Delete(typeCS.GetCString()) || delete_category;
+        bool delete_category = category->Synth()->Delete(typeCS.GetCString());
+        delete_category = category->RegexSynth()->Delete(typeCS.GetCString()) || delete_category;
+        
+        if (delete_category)
+        {
+            result.SetStatus(eReturnStatusSuccessFinishNoResult);
+            return result.Succeeded();
+        }
+        else
+        {
+            result.AppendErrorWithFormat ("no custom synthetic provider for %s.\n", typeA);
+            result.SetStatus(eReturnStatusFailed);
+            return false;
+        }
+        
+    }
+};
+
+OptionDefinition
+CommandObjectTypeSynthDelete::CommandOptions::g_option_table[] =
+{
+    { LLDB_OPT_SET_1, false, "all", 'a', no_argument, NULL, 0, eArgTypeNone,  "Delete from every category."},
+    { LLDB_OPT_SET_2, false, "category", 'w', required_argument, NULL, 0, eArgTypeName,  "Delete from given category."},
+    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
+};
+
+//-------------------------------------------------------------------------
+// CommandObjectTypeFilterClear
+//-------------------------------------------------------------------------
+
+class CommandObjectTypeFilterClear : public CommandObject
+{
+private:
+    
+    class CommandOptions : public Options
+    {
+    public:
+        
+        CommandOptions (CommandInterpreter &interpreter) :
+        Options (interpreter)
+        {
+        }
+        
+        virtual
+        ~CommandOptions (){}
+        
+        virtual Error
+        SetOptionValue (uint32_t option_idx, const char *option_arg)
+        {
+            Error error;
+            char short_option = (char) m_getopt_table[option_idx].val;
+            
+            switch (short_option)
+            {
+                case 'a':
+                    m_delete_all = true;
+                    break;
+                default:
+                    error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
+                    break;
+            }
+            
+            return error;
+        }
+        
+        void
+        OptionParsingStarting ()
+        {
+            m_delete_all = false;
+        }
+        
+        const OptionDefinition*
+        GetDefinitions ()
+        {
+            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.
+        
+        bool m_delete_all;
+        bool m_delete_named;
+    };
+    
+    CommandOptions m_options;
+    
+    virtual Options *
+    GetOptions ()
+    {
+        return &m_options;
+    }
+    
+    static bool
+    PerCategoryCallback(void* param,
+                        const char* cate_name,
+                        const FormatCategory::SharedPointer& cate)
+    {
+        cate->Clear(FormatCategory::eFilter | FormatCategory::eRegexFilter);
+        return true;
+        
+    }
+    
+public:
+    CommandObjectTypeFilterClear (CommandInterpreter &interpreter) :
+    CommandObject (interpreter,
+                   "type filter clear",
+                   "Delete all existing filters.",
+                   NULL), m_options(interpreter)
+    {
+    }
+    
+    ~CommandObjectTypeFilterClear ()
+    {
+    }
+    
+    bool
+    Execute (Args& command, CommandReturnObject &result)
+    {
+        
+        if (m_options.m_delete_all)
+            Debugger::Formatting::Categories::LoopThrough(PerCategoryCallback, NULL);
         
-        if (delete_category)
-        {
-            result.SetStatus(eReturnStatusSuccessFinishNoResult);
-            return result.Succeeded();
-        }
         else
-        {
-            result.AppendErrorWithFormat ("no custom synthetic provider for %s.\n", typeA);
-            result.SetStatus(eReturnStatusFailed);
-            return false;
+        {        
+            lldb::FormatCategorySP category;
+            if (command.GetArgumentCount() > 0)
+            {
+                const char* cat_name = command.GetArgumentAtIndex(0);
+                ConstString cat_nameCS(cat_name);
+                Debugger::Formatting::Categories::Get(cat_nameCS, category);
+            }
+            else
+                Debugger::Formatting::Categories::Get(ConstString(NULL), category);
+            category->Filter()->Clear();
+            category->RegexFilter()->Clear();
         }
         
+        result.SetStatus(eReturnStatusSuccessFinishResult);
+        return result.Succeeded();
     }
+    
 };
 
 OptionDefinition
-CommandObjectTypeSynthDelete::CommandOptions::g_option_table[] =
+CommandObjectTypeFilterClear::CommandOptions::g_option_table[] =
 {
-    { LLDB_OPT_SET_1, false, "all", 'a', no_argument, NULL, 0, eArgTypeNone,  "Delete from every category."},
-    { LLDB_OPT_SET_2, false, "category", 'w', required_argument, NULL, 0, eArgTypeName,  "Delete from given category."},
+    { LLDB_OPT_SET_ALL, false, "all", 'a', no_argument, NULL, 0, eArgTypeNone,  "Clear every category."},
     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
 };
 
@@ -2332,7 +2830,7 @@
                         const char* cate_name,
                         const FormatCategory::SharedPointer& cate)
     {
-        cate->Clear(FormatCategory::eFilter | FormatCategory::eRegexFilter);
+        cate->Clear(FormatCategory::eSynth | FormatCategory::eRegexSynth);
         return true;
         
     }
@@ -2368,8 +2866,8 @@
             }
             else
                 Debugger::Formatting::Categories::Get(ConstString(NULL), category);
-            category->Filter()->Clear();
-            category->RegexFilter()->Clear();
+            category->Synth()->Clear();
+            category->RegexSynth()->Clear();
         }
         
         result.SetStatus(eReturnStatusSuccessFinishResult);
@@ -2594,67 +3092,7 @@
     CollectPythonScript(options,result);
     return result.Succeeded();
 }
-    
-bool
-CommandObjectTypeSynthAdd::Execute_ChildrenList (Args& command, CommandReturnObject &result)
-{
-    const size_t argc = command.GetArgumentCount();
-    
-    if (argc < 1)
-    {
-        result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
-        result.SetStatus(eReturnStatusFailed);
-        return false;
-    }
-    
-    if (m_options.m_expr_paths.size() == 0)
-    {
-        result.AppendErrorWithFormat ("%s needs one or more children.\n", m_cmd_name.c_str());
-        result.SetStatus(eReturnStatusFailed);
-        return false;
-    }
-    
-    SyntheticChildrenSP entry;
-    
-    SyntheticFilter* impl = new SyntheticFilter(m_options.m_cascade,
-                                                m_options.m_skip_pointers,
-                                                m_options.m_skip_references);
-    
-    entry.reset(impl);
-    
-    // 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);
-    
-    
-    // now I have a valid provider, let's add it to every type
-    
-    lldb::FormatCategorySP category;
-    Debugger::Formatting::Categories::Get(ConstString(m_options.m_category.c_str()), category);
-    
-    for (size_t i = 0; i < argc; i++) {
-        const char* typeA = command.GetArgumentAtIndex(i);
-        ConstString typeCS(typeA);
-        if (typeCS)
-            AddSynth(typeCS,
-                     entry,
-                     m_options.m_regex ? eRegexSynth : eRegularSynth,
-                     m_options.m_category,
-                     NULL);
-        else
-        {
-            result.AppendError("empty typenames not allowed");
-            result.SetStatus(eReturnStatusFailed);
-            return false;
-        }
-    }
-    
-    result.SetStatus(eReturnStatusSuccessFinishNoResult);
-    return result.Succeeded();
-}
-    
+
 bool
 CommandObjectTypeSynthAdd::Execute_PythonClass (Args& command, CommandReturnObject &result)
 {
@@ -2747,14 +3185,14 @@
             return false;
         }
         
-        category->RegexFilter()->Delete(type_name.GetCString());
-        category->RegexFilter()->Add(typeRX, entry);
+        category->RegexSynth()->Delete(type_name.GetCString());
+        category->RegexSynth()->Add(typeRX, entry);
         
         return true;
     }
     else
     {
-        category->Filter()->Add(type_name.GetCString(), entry);
+        category->Synth()->Add(type_name.GetCString(), entry);
         return true;
     }
 }
@@ -2766,8 +3204,6 @@
         return Execute_HandwritePython(command, result);
     else if (m_options.is_class_based)
         return Execute_PythonClass(command, result);
-    else if (m_options.has_child_list)
-        return Execute_ChildrenList(command, result);
     else
     {
         result.AppendError("must either provide a children list, a Python class name, or use -P and type a Python class line-by-line");
@@ -2783,13 +3219,252 @@
     { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeNone,         "Don't use this format for pointers-to-type objects."},
     { LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeNone,         "Don't use this format for references-to-type objects."},
     { LLDB_OPT_SET_ALL, false, "category", 'w', required_argument, NULL, 0, eArgTypeName,         "Add this to the given category instead of the default one."},
-    { LLDB_OPT_SET_1, false, "child", 'c', required_argument, NULL, 0, eArgTypeName,    "Include this expression path in the synthetic view."},
     { LLDB_OPT_SET_2, false, "python-class", 'l', required_argument, NULL, 0, eArgTypeName,    "Use this Python class to produce synthetic children."},
     { LLDB_OPT_SET_3, false, "input-python", 'P', no_argument, NULL, 0, eArgTypeNone,    "Type Python code to generate a class that provides synthetic children."},
     { LLDB_OPT_SET_ALL, false,  "regex", 'x', no_argument, NULL, 0, eArgTypeNone,    "Type names are actually regular expressions."},
     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
 };
 
+class CommandObjectTypeFilterAdd : public CommandObject
+{
+    
+private:
+    
+    class CommandOptions : public Options
+    {
+        typedef std::vector<std::string> option_vector;
+    public:
+        
+        CommandOptions (CommandInterpreter &interpreter) :
+        Options (interpreter)
+        {
+        }
+        
+        virtual
+        ~CommandOptions (){}
+        
+        virtual Error
+        SetOptionValue (uint32_t option_idx, const char *option_arg)
+        {
+            Error error;
+            char short_option = (char) m_getopt_table[option_idx].val;
+            bool success;
+            
+            switch (short_option)
+            {
+                case 'C':
+                    m_cascade = Args::StringToBoolean(option_arg, true, &success);
+                    if (!success)
+                        error.SetErrorStringWithFormat("Invalid value for cascade: %s.\n", option_arg);
+                    break;
+                case 'c':
+                    m_expr_paths.push_back(option_arg);
+                    has_child_list = true;
+                    break;
+                case 'p':
+                    m_skip_pointers = true;
+                    break;
+                case 'r':
+                    m_skip_references = true;
+                    break;
+                case 'w':
+                    m_category = std::string(option_arg);
+                    break;
+                case 'x':
+                    m_regex = true;
+                    break;
+                default:
+                    error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
+                    break;
+            }
+            
+            return error;
+        }
+        
+        void
+        OptionParsingStarting ()
+        {
+            m_cascade = true;
+            m_skip_pointers = false;
+            m_skip_references = false;
+            m_category = "default";
+            m_expr_paths.clear();
+            has_child_list = false;
+            m_regex = false;
+        }
+        
+        const OptionDefinition*
+        GetDefinitions ()
+        {
+            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.
+        
+        bool m_cascade;
+        bool m_skip_references;
+        bool m_skip_pointers;
+        bool m_input_python;
+        option_vector m_expr_paths;
+        std::string m_category;
+                
+        bool has_child_list;
+        
+        bool m_regex;
+        
+        typedef option_vector::iterator ExpressionPathsIterator;
+    };
+    
+    CommandOptions m_options;
+    
+    virtual Options *
+    GetOptions ()
+    {
+        return &m_options;
+    }
+    
+    enum SynthFormatType
+    {
+        eRegularSynth,
+        eRegexSynth,
+    };
+    
+    bool
+    AddSynth(const ConstString& type_name,
+             SyntheticChildrenSP entry,
+             SynthFormatType type,
+             std::string category_name,
+             Error* error)
+    {
+        lldb::FormatCategorySP category;
+        Debugger::Formatting::Categories::Get(ConstString(category_name.c_str()), category);
+        
+        if (type == eRegexSynth)
+        {
+            RegularExpressionSP typeRX(new RegularExpression());
+            if (!typeRX->Compile(type_name.GetCString()))
+            {
+                if (error)
+                    error->SetErrorString("regex format error (maybe this is not really a regex?)");
+                return false;
+            }
+            
+            category->RegexFilter()->Delete(type_name.GetCString());
+            category->RegexFilter()->Add(typeRX, entry);
+            
+            return true;
+        }
+        else
+        {
+            category->Filter()->Add(type_name.GetCString(), entry);
+            return true;
+        }
+    }
+
+        
+public:
+    
+    CommandObjectTypeFilterAdd (CommandInterpreter &interpreter) :
+    CommandObject (interpreter,
+                   "type filter add",
+                   "Add a new filter for a type.",
+                   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);
+        
+    }
+    
+    ~CommandObjectTypeFilterAdd ()
+    {
+    }
+    
+    bool
+    Execute (Args& command, CommandReturnObject &result)
+    {
+        const size_t argc = command.GetArgumentCount();
+        
+        if (argc < 1)
+        {
+            result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
+            result.SetStatus(eReturnStatusFailed);
+            return false;
+        }
+        
+        if (m_options.m_expr_paths.size() == 0)
+        {
+            result.AppendErrorWithFormat ("%s needs one or more children.\n", m_cmd_name.c_str());
+            result.SetStatus(eReturnStatusFailed);
+            return false;
+        }
+        
+        SyntheticChildrenSP entry;
+        
+        SyntheticFilter* impl = new SyntheticFilter(m_options.m_cascade,
+                                                    m_options.m_skip_pointers,
+                                                    m_options.m_skip_references);
+        
+        entry.reset(impl);
+        
+        // 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);
+        
+        
+        // now I have a valid provider, let's add it to every type
+        
+        lldb::FormatCategorySP category;
+        Debugger::Formatting::Categories::Get(ConstString(m_options.m_category.c_str()), category);
+        
+        for (size_t i = 0; i < argc; i++) {
+            const char* typeA = command.GetArgumentAtIndex(i);
+            ConstString typeCS(typeA);
+            if (typeCS)
+                AddSynth(typeCS,
+                         entry,
+                         m_options.m_regex ? eRegexSynth : eRegularSynth,
+                         m_options.m_category,
+                         NULL);
+            else
+            {
+                result.AppendError("empty typenames not allowed");
+                result.SetStatus(eReturnStatusFailed);
+                return false;
+            }
+        }
+        
+        result.SetStatus(eReturnStatusSuccessFinishNoResult);
+        return result.Succeeded();
+    }
+
+};
+
+OptionDefinition
+CommandObjectTypeFilterAdd::CommandOptions::g_option_table[] =
+{
+    { LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean,    "If true, cascade to derived typedefs."},
+    { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeNone,         "Don't use this format for pointers-to-type objects."},
+    { LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeNone,         "Don't use this format for references-to-type objects."},
+    { LLDB_OPT_SET_ALL, false, "category", 'w', required_argument, NULL, 0, eArgTypeName,         "Add this to the given category instead of the default one."},
+    { LLDB_OPT_SET_ALL, false, "child", 'c', required_argument, NULL, 0, eArgTypeName,    "Include this expression path in the synthetic view."},
+    { LLDB_OPT_SET_ALL, false,  "regex", 'x', no_argument, NULL, 0, eArgTypeNone,    "Type names are actually regular expressions."},
+    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
+};
+
 class CommandObjectTypeFormat : public CommandObjectMultiword
 {
 public:
@@ -2832,6 +3507,27 @@
     }
 };
 
+class CommandObjectTypeFilter : public CommandObjectMultiword
+{
+public:
+    CommandObjectTypeFilter (CommandInterpreter &interpreter) :
+    CommandObjectMultiword (interpreter,
+                            "type filter",
+                            "A set of commands for operating on type filters",
+                            "type synthetic [<sub-command-options>] ")
+    {
+        LoadSubCommand ("add",           CommandObjectSP (new CommandObjectTypeFilterAdd (interpreter)));
+        LoadSubCommand ("clear",         CommandObjectSP (new CommandObjectTypeFilterClear (interpreter)));
+        LoadSubCommand ("delete",        CommandObjectSP (new CommandObjectTypeFilterDelete (interpreter)));
+        LoadSubCommand ("list",          CommandObjectSP (new CommandObjectTypeFilterList (interpreter)));
+    }
+    
+    
+    ~CommandObjectTypeFilter ()
+    {
+    }
+};
+
 class CommandObjectTypeCategory : public CommandObjectMultiword
 {
 public:
@@ -2885,9 +3581,10 @@
                             "type [<sub-command-options>]")
 {
     LoadSubCommand ("category",  CommandObjectSP (new CommandObjectTypeCategory (interpreter)));
+    LoadSubCommand ("filter",    CommandObjectSP (new CommandObjectTypeFilter (interpreter)));
     LoadSubCommand ("format",    CommandObjectSP (new CommandObjectTypeFormat (interpreter)));
     LoadSubCommand ("summary",   CommandObjectSP (new CommandObjectTypeSummary (interpreter)));
-    LoadSubCommand ("synthetic",     CommandObjectSP (new CommandObjectTypeSynth (interpreter)));
+    LoadSubCommand ("synthetic", CommandObjectSP (new CommandObjectTypeSynth (interpreter)));
 }
 
 

Modified: lldb/trunk/source/Commands/CommandObjectType.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectType.h?rev=137416&r1=137415&r2=137416&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectType.h (original)
+++ lldb/trunk/source/Commands/CommandObjectType.h Thu Aug 11 21:00:06 2011
@@ -214,7 +214,6 @@
     
     class CommandOptions : public Options
     {
-        typedef std::vector<std::string> option_vector;
     public:
         
         CommandOptions (CommandInterpreter &interpreter) :
@@ -239,10 +238,6 @@
                     if (!success)
                         error.SetErrorStringWithFormat("Invalid value for cascade: %s.\n", option_arg);
                     break;
-                case 'c':
-                    m_expr_paths.push_back(option_arg);
-                    has_child_list = true;
-                    break;
                 case 'P':
                     handwrite_python = true;
                     break;
@@ -278,10 +273,8 @@
             m_skip_pointers = false;
             m_skip_references = false;
             m_category = "default";
-            m_expr_paths.clear();
             is_class_based = false;
             handwrite_python = false;
-            has_child_list = false;
             m_regex = false;
         }
         
@@ -302,18 +295,14 @@
         bool m_skip_pointers;
         std::string m_class_name;
         bool m_input_python;
-        option_vector m_expr_paths;
         std::string m_category;
         
         bool is_class_based;
         
         bool handwrite_python;
-        
-        bool has_child_list;
-        
+                
         bool m_regex;
         
-        typedef option_vector::iterator ExpressionPathsIterator;
     };
     
     CommandOptions m_options;
@@ -329,10 +318,10 @@
                          CommandReturnObject &result);    
     bool
     Execute_HandwritePython (Args& command, CommandReturnObject &result);    
-    bool
-    Execute_ChildrenList (Args& command, CommandReturnObject &result);    
+
     bool
     Execute_PythonClass (Args& command, CommandReturnObject &result);
+    
     bool
     Execute (Args& command, CommandReturnObject &result);
     

Modified: lldb/trunk/source/Core/Debugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=137416&r1=137415&r2=137416&view=diff
==============================================================================
--- lldb/trunk/source/Core/Debugger.cpp (original)
+++ lldb/trunk/source/Core/Debugger.cpp Thu Aug 11 21:00:06 2011
@@ -1200,6 +1200,8 @@
                                     if (index_higher < 0)
                                         index_higher = vobj->GetNumChildren() - 1;
                                     
+                                    uint32_t max_num_children = target->GetUpdatePoint().GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
+                                    
                                     for (;index_lower<=index_higher;index_lower++)
                                     {
                                         ValueObject* item = ExpandIndexedExpression(target,
@@ -1223,6 +1225,12 @@
                                         else
                                             var_success &= FormatPrompt(special_directions, sc, exe_ctx, addr, s, NULL, item);
                                         
+                                        if (--max_num_children == 0)
+                                        {
+                                            s.PutCString(", ...");
+                                            break;
+                                        }
+                                        
                                         if (index_lower < index_higher)
                                             s.PutChar(',');
                                     }

Modified: lldb/trunk/source/Core/FormatManager.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FormatManager.cpp?rev=137416&r1=137415&r2=137416&view=diff
==============================================================================
--- lldb/trunk/source/Core/FormatManager.cpp (original)
+++ lldb/trunk/source/Core/FormatManager.cpp Thu Aug 11 21:00:06 2011
@@ -230,6 +230,44 @@
     return false;
 }
 
+template<>
+bool
+FormatNavigator<lldb::RegularExpressionSP, SyntheticScriptProvider>::Get(const char* key, SyntheticFilter::SharedPointer& value)
+{
+    Mutex::Locker(m_format_map.mutex());
+    MapIterator pos, end = m_format_map.map().end();
+    for (pos = m_format_map.map().begin(); pos != end; pos++)
+    {
+        lldb::RegularExpressionSP regex = pos->first;
+        if (regex->Execute(key))
+        {
+            value = pos->second;
+            return true;
+        }
+    }
+    return false;
+}
+
+template<>
+bool
+FormatNavigator<lldb::RegularExpressionSP, SyntheticScriptProvider>::Delete(const char* type)
+{
+    Mutex::Locker(m_format_map.mutex());
+    MapIterator pos, end = m_format_map.map().end();
+    for (pos = m_format_map.map().begin(); pos != end; pos++)
+    {
+        lldb::RegularExpressionSP regex = pos->first;
+        if ( ::strcmp(type,regex->GetText()) == 0)
+        {
+            m_format_map.map().erase(pos);
+            if (m_format_map.listener)
+                m_format_map.listener->Changed();
+            return true;
+        }
+    }
+    return false;
+}
+
 lldb::Format
 FormatManager::GetSingleItemFormat(lldb::Format vector_format)
 {

Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=137416&r1=137415&r2=137416&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Thu Aug 11 21:00:06 2011
@@ -2687,7 +2687,8 @@
     bool use_synth,
     bool scope_already_checked,
     bool flat_output,
-    uint32_t omit_summary_depth
+    uint32_t omit_summary_depth,
+    bool ignore_cap
 )
 {
     if (valobj)
@@ -2864,7 +2865,8 @@
                     ValueObjectSP synth_vobj = valobj->GetSyntheticValue(use_synth ?
                                                                          lldb::eUseSyntheticFilter : 
                                                                          lldb::eNoSyntheticFilter);
-                    const uint32_t num_children = synth_vobj->GetNumChildren();
+                    uint32_t num_children = synth_vobj->GetNumChildren();
+                    bool print_dotdotdot = false;
                     if (num_children)
                     {
                         if (flat_output)
@@ -2878,6 +2880,14 @@
                                 s.PutCString(is_ref ? ": {\n" : " {\n");
                             s.IndentMore();
                         }
+                        
+                        uint32_t max_num_children = valobj->GetUpdatePoint().GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
+                        
+                        if (num_children > max_num_children && !ignore_cap)
+                        {
+                            num_children = max_num_children;
+                            print_dotdotdot = true;
+                        }
 
                         for (uint32_t idx=0; idx<num_children; ++idx)
                         {
@@ -2897,12 +2907,15 @@
                                                  use_synth,
                                                  true,
                                                  flat_output,
-                                                 omit_summary_depth > 1 ? omit_summary_depth - 1 : 0);
+                                                 omit_summary_depth > 1 ? omit_summary_depth - 1 : 0,
+                                                 ignore_cap);
                             }
                         }
 
                         if (!flat_output)
                         {
+                            if (print_dotdotdot)
+                                s.Indent("...\n");
                             s.IndentLess();
                             s.Indent("}\n");
                         }

Modified: lldb/trunk/source/Interpreter/OptionGroupValueObjectDisplay.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/OptionGroupValueObjectDisplay.cpp?rev=137416&r1=137415&r2=137416&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/OptionGroupValueObjectDisplay.cpp (original)
+++ lldb/trunk/source/Interpreter/OptionGroupValueObjectDisplay.cpp Thu Aug 11 21:00:06 2011
@@ -30,17 +30,18 @@
 static OptionDefinition
 g_option_table[] =
 {
-    { LLDB_OPT_SET_1, false, "dynamic-type",    'd', required_argument, TargetInstanceSettings::g_dynamic_value_types, 
+    { LLDB_OPT_SET_1, false, "dynamic-type",     'd', required_argument, TargetInstanceSettings::g_dynamic_value_types, 
                                                                               0, eArgTypeNone,      "Show the object as its full dynamic type, not its static type, if available."},
-    { LLDB_OPT_SET_1, false, "synthetic-type",  'S', required_argument, NULL, 0, eArgTypeBoolean,   "Show the object obeying its synthetic provider, if available."},
-    { LLDB_OPT_SET_1, false, "depth",           'D', required_argument, NULL, 0, eArgTypeCount,     "Set the max recurse depth when dumping aggregate types (default is infinity)."},
-    { LLDB_OPT_SET_1, false, "flat",            'F', no_argument,       NULL, 0, eArgTypeNone,      "Display results in a flat format that uses expression paths for each variable or member."},
-    { LLDB_OPT_SET_1, false, "location",        'L', no_argument,       NULL, 0, eArgTypeNone,      "Show variable location information."},
-    { LLDB_OPT_SET_1, false, "objc",            'O', no_argument,       NULL, 0, eArgTypeNone,      "Print as an Objective-C object."},
-    { LLDB_OPT_SET_1, false, "ptr-depth",       'P', required_argument, NULL, 0, eArgTypeCount,     "The number of pointers to be traversed when dumping values (default is zero)."},
-    { LLDB_OPT_SET_1, false, "show-types",      'T', no_argument,       NULL, 0, eArgTypeNone,      "Show variable types when dumping values."},
-    { LLDB_OPT_SET_1, false, "no-summary-depth",'Y', optional_argument, NULL, 0, eArgTypeCount,     "Set a depth for omitting summary information (default is 1)."},
-    { LLDB_OPT_SET_1, false, "raw-output",      'R', no_argument,       NULL, 0, eArgTypeNone,      "Don't use formatting options."},
+    { LLDB_OPT_SET_1, false, "synthetic-type",   'S', required_argument, NULL, 0, eArgTypeBoolean,   "Show the object obeying its synthetic provider, if available."},
+    { LLDB_OPT_SET_1, false, "depth",            'D', required_argument, NULL, 0, eArgTypeCount,     "Set the max recurse depth when dumping aggregate types (default is infinity)."},
+    { LLDB_OPT_SET_1, false, "flat",             'F', no_argument,       NULL, 0, eArgTypeNone,      "Display results in a flat format that uses expression paths for each variable or member."},
+    { LLDB_OPT_SET_1, false, "location",         'L', no_argument,       NULL, 0, eArgTypeNone,      "Show variable location information."},
+    { LLDB_OPT_SET_1, false, "objc",             'O', no_argument,       NULL, 0, eArgTypeNone,      "Print as an Objective-C object."},
+    { LLDB_OPT_SET_1, false, "ptr-depth",        'P', required_argument, NULL, 0, eArgTypeCount,     "The number of pointers to be traversed when dumping values (default is zero)."},
+    { LLDB_OPT_SET_1, false, "show-types",       'T', no_argument,       NULL, 0, eArgTypeNone,      "Show variable types when dumping values."},
+    { LLDB_OPT_SET_1, false, "no-summary-depth", 'Y', optional_argument, NULL, 0, eArgTypeCount,     "Set a depth for omitting summary information (default is 1)."},
+    { LLDB_OPT_SET_1, false, "raw-output",       'R', no_argument,       NULL, 0, eArgTypeNone,      "Don't use formatting options."},
+    { LLDB_OPT_SET_1, false, "show-all-children",'A', no_argument,       NULL, 0, eArgTypeNone,      "Ignore the upper bound on the number of children to show."},
     { 0, false, NULL, 0, 0, NULL, NULL, eArgTypeNone, NULL }
 };
 
@@ -86,6 +87,7 @@
         case 'F':   flat_output  = true;  break;
         case 'O':   use_objc     = true;  break;
         case 'R':   be_raw       = true;  break;
+        case 'A':   ignore_cap   = true;  break;
             
         case 'D':
             max_depth = Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success);
@@ -135,6 +137,7 @@
     ptr_depth         = 0;
     use_synth         = true;
     be_raw            = false;
+    ignore_cap        = false;
     
     Target *target = interpreter.GetExecutionContext().target;
     if (target != NULL)

Modified: lldb/trunk/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=137416&r1=137415&r2=137416&view=diff
==============================================================================
--- lldb/trunk/source/Target/Target.cpp (original)
+++ lldb/trunk/source/Target/Target.cpp Thu Aug 11 21:00:06 2011
@@ -1578,6 +1578,7 @@
 #define TSC_PREFER_DYNAMIC    "prefer-dynamic-value"
 #define TSC_SKIP_PROLOGUE     "skip-prologue"
 #define TSC_SOURCE_MAP        "source-map"
+#define TSC_MAX_CHILDREN      "max-children-count"
 
 
 static const ConstString &
@@ -1615,6 +1616,12 @@
     return g_const_string;
 }
 
+static const ConstString &
+GetSettingNameForMaxChildren ()
+{
+    static ConstString g_const_string (TSC_MAX_CHILDREN);
+    return g_const_string;
+}
 
 
 bool
@@ -1668,7 +1675,8 @@
     m_expr_prefix_contents_sp (),
     m_prefer_dynamic_value (2),
     m_skip_prologue (true, true),
-    m_source_map (NULL, NULL)
+    m_source_map (NULL, NULL),
+    m_max_children_display(256)
 {
     // CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called
     // until the vtables for TargetInstanceSettings are properly set up, i.e. AFTER all the initializers.
@@ -1694,7 +1702,8 @@
     m_expr_prefix_contents_sp (rhs.m_expr_prefix_contents_sp),
     m_prefer_dynamic_value (rhs.m_prefer_dynamic_value),
     m_skip_prologue (rhs.m_skip_prologue),
-    m_source_map (rhs.m_source_map)
+    m_source_map (rhs.m_source_map),
+    m_max_children_display(rhs.m_max_children_display)
 {
     if (m_instance_name != InstanceSettings::GetDefaultName())
     {
@@ -1771,6 +1780,13 @@
     {
         err = UserSettingsController::UpdateBooleanOptionValue (value, op, m_skip_prologue);
     }
+    else if (var_name == GetSettingNameForMaxChildren())
+    {
+        bool ok;
+        uint32_t new_value = Args::StringToUInt32(value, 0, 10, &ok);
+        if (ok)
+            m_max_children_display = new_value;
+    }
     else if (var_name == GetSettingNameForSourcePathMap ())
     {
         switch (op)
@@ -1841,6 +1857,7 @@
     m_expr_prefix_contents_sp   = new_settings_ptr->m_expr_prefix_contents_sp;
     m_prefer_dynamic_value      = new_settings_ptr->m_prefer_dynamic_value;
     m_skip_prologue             = new_settings_ptr->m_skip_prologue;
+    m_max_children_display      = new_settings_ptr->m_max_children_display;
 }
 
 bool
@@ -1870,6 +1887,12 @@
     else if (var_name == GetSettingNameForSourcePathMap ())
     {
     }
+    else if (var_name == GetSettingNameForMaxChildren())
+    {
+        StreamString count_str;
+        count_str.Printf ("%d", m_max_children_display);
+        value.AppendString (count_str.GetData());
+    }
     else 
     {
         if (err)
@@ -1923,5 +1946,6 @@
     { TSC_PREFER_DYNAMIC, eSetVarTypeEnum   , NULL          , g_dynamic_value_types, false, false, "Should printed values be shown as their dynamic value." },
     { TSC_SKIP_PROLOGUE , eSetVarTypeBoolean, "true"        , NULL,                  false, false, "Skip function prologues when setting breakpoints by name." },
     { TSC_SOURCE_MAP    , eSetVarTypeArray  , NULL          , NULL,                  false, false, "Source path remappings to use when locating source files from debug information." },
+    { TSC_MAX_CHILDREN  , eSetVarTypeInt    , "256"         , NULL,                  true,  false, "Maximum number of children to expand in any level of depth." },
     { NULL              , eSetVarTypeNone   , NULL          , NULL,                  false, false, NULL }
 };

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py?rev=137416&r1=137415&r2=137416&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py Thu Aug 11 21:00:06 2011
@@ -49,6 +49,8 @@
         def cleanup():
             self.runCmd('type format clear', check=False)
             self.runCmd('type summary clear', check=False)
+            self.runCmd("settings set target.max-children-count 256", check=False)
+
 
         # Execute the cleanup function during test case tear down.
         self.addTearDownHook(cleanup)
@@ -190,6 +192,94 @@
         self.expect("frame variable a_simple_object", matching=True,
                     substrs = ['x=0x00000003'])
 
+        # check that we can correctly cap the number of children shown
+        self.runCmd("settings set target.max-children-count 5")
+
+        self.expect('frame variable a_long_guy', matching=True,
+            substrs = ['a_1',
+                       'b_1',
+                       'c_1',
+                       'd_1',
+                       'e_1',
+                       '...'])
+
+        # check that no further stuff is printed (not ALL values are checked!)
+        self.expect('frame variable a_long_guy', matching=False,
+                    substrs = ['f_1',
+                               'g_1',
+                               'h_1',
+                               'i_1',
+                               'j_1',
+                               'q_1',
+                               'a_2',
+                               'f_2',
+                               't_2',
+                               'w_2'])
+
+        self.runCmd("settings set target.max-children-count 1")
+        self.expect('frame variable a_long_guy', matching=True,
+                    substrs = ['a_1',
+                               '...'])
+        self.expect('frame variable a_long_guy', matching=False,
+                    substrs = ['b_1',
+                               'c_1',
+                               'd_1',
+                               'e_1'])
+        self.expect('frame variable a_long_guy', matching=False,
+                    substrs = ['f_1',
+                               'g_1',
+                               'h_1',
+                               'i_1',
+                               'j_1',
+                               'q_1',
+                               'a_2',
+                               'f_2',
+                               't_2',
+                               'w_2'])
+
+        self.runCmd("settings set target.max-children-count 30")
+        self.expect('frame variable a_long_guy', matching=True,
+                    substrs = ['a_1',
+                               'b_1',
+                               'c_1',
+                               'd_1',
+                               'e_1',
+                               'z_1',
+                               'a_2',
+                               'b_2',
+                               'c_2',
+                               'd_2',
+                               '...'])
+        self.expect('frame variable a_long_guy', matching=False,
+                    substrs = ['e_2',
+                               'n_2',
+                               'r_2',
+                               'i_2',
+                               'k_2',
+                               'o_2'])
+
+        # override the cap 
+        self.expect('frame variable a_long_guy --show-all-children', matching=True,
+                    substrs = ['a_1',
+                               'b_1',
+                               'c_1',
+                               'd_1',
+                               'e_1',
+                               'z_1',
+                               'a_2',
+                               'b_2',
+                               'c_2',
+                               'd_2'])
+        self.expect('frame variable a_long_guy --show-all-children', matching=True,
+                    substrs = ['e_2',
+                               'n_2',
+                               'r_2',
+                               'i_2',
+                               'k_2',
+                               'o_2'])
+        self.expect('frame variable a_long_guy -A', matching=False,
+                    substrs = ['...'])
+
 
 if __name__ == '__main__':
     import atexit

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/main.cpp?rev=137416&r1=137415&r2=137416&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/main.cpp (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-advanced/main.cpp Thu Aug 11 21:00:06 2011
@@ -73,6 +73,63 @@
 	s(new Simple(X,Y,Z)) {}
 };
 
+struct VeryLong
+{
+    int a_1;
+    int b_1;
+    int c_1;
+    int d_1;
+    int e_1;
+    int f_1;
+    int g_1;
+    int h_1;
+    int i_1;
+    int j_1;
+    int k_1;
+    int l_1;
+    int m_1;
+    int n_1;
+    int o_1;
+    int p_1;
+    int q_1;
+    int r_1;
+    int s_1;
+    int t_1;
+    int u_1;
+    int v_1;
+    int w_1;
+    int x_1;
+    int y_1;
+    int z_1;
+    
+    int a_2;
+    int b_2;
+    int c_2;
+    int d_2;
+    int e_2;
+    int f_2;
+    int g_2;
+    int h_2;
+    int i_2;
+    int j_2;
+    int k_2;
+    int l_2;
+    int m_2;
+    int n_2;
+    int o_2;
+    int p_2;
+    int q_2;
+    int r_2;
+    int s_2;
+    int t_2;
+    int u_2;
+    int v_2;
+    int w_2;
+    int x_2;
+    int y_2;
+    int z_2;
+};
+
 int main (int argc, const char * argv[])
 {
     
@@ -108,5 +165,7 @@
     
     Simple a_simple_object(3,0.14,'E');
     
+    VeryLong a_long_guy;
+    
     return 0; // Set break point at this line.
 }
\ No newline at end of file

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py?rev=137416&r1=137415&r2=137416&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py Thu Aug 11 21:00:06 2011
@@ -319,8 +319,8 @@
                                'AShape',
                                'ARectangleStar'])
 
-        # check that synthetic children work into categories
-        self.runCmd("type synth add Rectangle --child w --category RectangleCategory")
+        # check that filters work into categories
+        self.runCmd("type filter add Rectangle --child w --category RectangleCategory")
         self.runCmd("type category enable RectangleCategory")
         self.runCmd("type summary add Rectangle -f \" \" -e --category RectangleCategory")
         self.expect('frame variable r2',
@@ -332,7 +332,7 @@
         # Now delete all categories
         self.runCmd("type category delete CircleCategory RectangleStarCategory BaseCategory RectangleCategory")
 
-        # last of all, check that a deleted category with synth does not blow us up
+        # last of all, check that a deleted category with filter does not blow us up
         self.expect('frame variable r2',
                     substrs = ['w = 9',
                                'h = 16'])

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py?rev=137416&r1=137415&r2=137416&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py Thu Aug 11 21:00:06 2011
@@ -49,7 +49,9 @@
         def cleanup():
             self.runCmd('type format clear', check=False)
             self.runCmd('type summary clear', check=False)
+            self.runCmd('type filter clear', check=False)
             self.runCmd('type synth clear', check=False)
+            self.runCmd("settings set target.max-children-count 256", check=False)
 
         # Execute the cleanup function during test case tear down.
         self.addTearDownHook(cleanup)
@@ -114,18 +116,75 @@
                                'fake_a = 16777217',
                                'a = 280']);
         
+        # check that capping works for synthetic children as well
+        self.runCmd("settings set target.max-children-count 2", check=False)
+        
+        self.expect("frame variable f00_1",
+                    substrs = ['...',
+                               'fake_a = 16777217',
+                               'a = 280']);
+        
+        self.expect("frame variable f00_1", matching=False,
+                    substrs = ['r = 33']);
+
+        
+        self.runCmd("settings set target.max-children-count 256", check=False)
+
         # check that expanding a pointer does the right thing
         self.expect("frame variable -P 1 f00_ptr",
             substrs = ['r = 45',
                        'fake_a = 218103808',
                        'a = 12'])
         
+        # now mix synth and filter and check consistent output
+        self.runCmd("type filter add foo --child b --child j")
+        self.expect('frame variable f00_1',
+            substrs = ['b = 1',
+                       'j = 17'])
+        self.expect("frame variable -P 1 f00_ptr", matching=False,
+                    substrs = ['r = 45',
+                               'fake_a = 218103808',
+                               'a = 12'])
+        
+        # now add the synth again to see that it prevails
+        self.runCmd("type synth add -l fooSynthProvider foo")
+        self.expect('frame variable f00_1', matching=False,
+                    substrs = ['b = 1',
+                               'j = 17'])
+        self.expect("frame variable -P 1 f00_ptr", 
+                    substrs = ['r = 45',
+                               'fake_a = 218103808',
+                               'a = 12'])
+
+        # check the listing
+        self.expect('type synth list',
+                    substrs = ['foo',
+                               'Python class fooSynthProvider'])
+        self.expect('type filter list',
+                    substrs = ['foo',
+                               '.b',
+                               '.j'])
+        
         # delete the synth and check that we get good output
         self.runCmd("type synth delete foo")
+        
+        # first let the filter win
+        self.expect('frame variable f00_1',
+                        substrs = ['b = 1',
+                                   'j = 17'])
+        self.expect("frame variable -P 1 f00_ptr", matching=False,
+                    substrs = ['r = 45',
+                               'fake_a = 218103808',
+                               'a = 12'])
+
+        # then delete the filter
+        self.runCmd("type filter delete foo")
+        
+        # and show real children        
         self.expect("frame variable f00_1",
                     substrs = ['a = 280',
                                'b = 1',
-                               'r = 33']);
+                               'j = 17']);
 
         self.expect("frame variable f00_1", matching=False,
                 substrs = ['fake_a = '])

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py?rev=137416&r1=137415&r2=137416&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py Thu Aug 11 21:00:06 2011
@@ -49,13 +49,13 @@
         def cleanup():
             self.runCmd('type format clear', check=False)
             self.runCmd('type summary clear', check=False)
-            self.runCmd('type synth clear', check=False)
+            self.runCmd('type filter clear', check=False)
 
         # Execute the cleanup function during test case tear down.
         self.addTearDownHook(cleanup)
 
         # Pick some values and check that the basics work
-        self.runCmd("type synth add BagOfInts --child x --child z")
+        self.runCmd("type filter add BagOfInts --child x --child z")
         self.expect("frame variable int_bag",
             substrs = ['x = 6',
                        'z = 8'])
@@ -102,14 +102,14 @@
                                'z = 8'])
 
         # Delete synth and check that the view reflects it immediately
-        self.runCmd("type synth delete BagOfInts")
+        self.runCmd("type filter delete BagOfInts")
         self.expect("frame variable int_bag",
                     substrs = ['x = 6',
                                'y = 7',
                                'z = 8'])
 
         # Add the synth again and check that it's honored deeper in the hierarchy
-        self.runCmd("type synth add BagOfInts --child x --child z")
+        self.runCmd("type filter add BagOfInts --child x --child z")
         self.expect('frame variable bag_bag',
             substrs = ['x = y=70 {',
                        'x = 69',
@@ -122,25 +122,25 @@
                                'y = 67'])
 
         # Check that a synth can expand nested stuff
-        self.runCmd("type synth add BagOfBags --child x.y --child y.z")
+        self.runCmd("type filter add BagOfBags --child x.y --child y.z")
         self.expect('frame variable bag_bag',
                     substrs = ['x.y = 70',
                                'y.z = 68'])
 
         # ...even if we get -> and . wrong
-        self.runCmd("type synth add BagOfBags --child x.y --child \"y->z\"")
+        self.runCmd("type filter add BagOfBags --child x.y --child \"y->z\"")
         self.expect('frame variable bag_bag',
                     substrs = ['x.y = 70',
                                'y->z = 68'])
 
         # ...even bitfields
-        self.runCmd("type synth add BagOfBags --child x.y --child \"y->z[1-2]\"")
+        self.runCmd("type filter add BagOfBags --child x.y --child \"y->z[1-2]\"")
         self.expect('frame variable bag_bag -T',
                     substrs = ['x.y = 70',
                                '(int:2) y->z[1-2] = 2'])
 
         # ...even if we format the bitfields
-        self.runCmd("type synth add BagOfBags --child x.y --child \"y->y[0-0]\"")
+        self.runCmd("type filter add BagOfBags --child x.y --child \"y->y[0-0]\"")
         self.runCmd("type format add \"int:1\" -f bool")
         self.expect('frame variable bag_bag -T',
                     substrs = ['x.y = 70',
@@ -154,7 +154,7 @@
         self.runCmd("type summary delete BagOfBags")
 
         # now check we are dynamic (and arrays work)
-        self.runCmd("type synth add Plenty --child bitfield --child array[0] --child array[2]")
+        self.runCmd("type filter add Plenty --child bitfield --child array[0] --child array[2]")
         self.expect('frame variable plenty_of_stuff',
             substrs = ['bitfield = 1',
                        'array[0] = 5',
@@ -191,7 +191,7 @@
                                'z = 7'])
 
         # but not if we don't want to
-        self.runCmd("type synth add BagOfInts --child x --child z -p")
+        self.runCmd("type filter add BagOfInts --child x --child z -p")
         self.expect('frame variable plenty_of_stuff.some_values -P1',
                     substrs = ['(BagOfInts *) plenty_of_stuff.some_values',
                                'x = 5',
@@ -199,7 +199,7 @@
                                'z = 7'])
 
         # check we're dynamic even if nested
-        self.runCmd("type synth add BagOfBags --child x.z")
+        self.runCmd("type filter add BagOfBags --child x.z")
         self.expect('frame variable bag_bag',
             substrs = ['x.z = 71'])
 





More information about the lldb-commits mailing list