[Lldb-commits] [lldb] r135463 - in /lldb/trunk: include/lldb/ include/lldb/Core/ source/Commands/ source/Core/ test/functionalities/data-formatter/data-formatter-categories/ test/functionalities/data-formatter/data-formatter-globals/ test/functionalities/data-formatter/data-formatter-skip-summary/ www/

Enrico Granata granata.enrico at gmail.com
Mon Jul 18 19:34:22 PDT 2011


Author: enrico
Date: Mon Jul 18 21:34:21 2011
New Revision: 135463

URL: http://llvm.org/viewvc/llvm-project?rev=135463&view=rev
Log:
Fixed a bug where deleting a regex summary would not immediately reflect in the variables display
The "systemwide summaries" feature has been removed and replaced with a more general and
powerful mechanism.
Categories:
 - summaries can now be grouped into buckets, called "categories" (it is expected that categories
   correspond to libraries and/or runtime environments)
 - to add a summary to a category, you can use the -w option to type summary add and give
   a category name (e.g. type summary add -f "foo" foo_t -w foo_category)
 - categories are by default disabled, which means LLDB will not look into them for summaries,
   to enable a category use "type category enable". once a category is enabled, LLDB will
   look into that category for summaries. the rules are quite trivial: every enabled category
   is searched for an exact match. if an exact match is nowhere to be found, any match is
   searched for in every enabled category (whether it involves cascading, going to base classes,
   ...). categories are searched into the order in which they were enabled (the most recently
   enabled category first, then the second most and so on..)
 - by default, most commands that deal with summaries, use a category named "default" if no
   explicit -w parameter is given (the observable behavior of LLDB should not change when
   categories are not explicitly used)
 - the systemwide summaries are now part of a "system" category

Added:
    lldb/trunk/test/functionalities/data-formatter/data-formatter-categories/
    lldb/trunk/test/functionalities/data-formatter/data-formatter-categories/Makefile
    lldb/trunk/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py
    lldb/trunk/test/functionalities/data-formatter/data-formatter-categories/main.cpp
    lldb/trunk/test/functionalities/data-formatter/data-formatter-globals/
    lldb/trunk/test/functionalities/data-formatter/data-formatter-globals/Makefile
    lldb/trunk/test/functionalities/data-formatter/data-formatter-globals/TestDataFormatterGlobals.py
    lldb/trunk/test/functionalities/data-formatter/data-formatter-globals/main.cpp
Modified:
    lldb/trunk/include/lldb/Core/Debugger.h
    lldb/trunk/include/lldb/Core/FormatManager.h
    lldb/trunk/include/lldb/lldb-enumerations.h
    lldb/trunk/include/lldb/lldb-forward-rtti.h
    lldb/trunk/include/lldb/lldb-forward.h
    lldb/trunk/source/Commands/CommandObjectFrame.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/test/functionalities/data-formatter/data-formatter-skip-summary/TestDataFormatterSkipSummary.py
    lldb/trunk/www/varformats.html

Modified: lldb/trunk/include/lldb/Core/Debugger.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Debugger.h?rev=135463&r1=135462&r2=135463&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Debugger.h (original)
+++ lldb/trunk/include/lldb/Core/Debugger.h Mon Jul 18 21:34:21 2011
@@ -474,159 +474,100 @@
     
 public:
     
-    class ValueFormats
+    class Formatting
     {
     public:
-        static bool
-        Get(ValueObject& vobj, ValueFormat::SharedPointer &entry);
-        
-        static void
-        Add(const ConstString &type, const ValueFormat::SharedPointer &entry);
-        
-        static bool
-        Delete(const ConstString &type);
-        
-        static void
-        Clear();
-        
-        static void
-        LoopThrough(ValueFormat::ValueCallback callback, void* callback_baton);
-        
-        static uint32_t
-        GetCurrentRevision();
-    
-        static uint32_t
-        GetCount();
-    };
-    
-    class SummaryFormats
-    {
-    public:
-    
-        static bool
-        Get(ValueObject& vobj, SummaryFormat::SharedPointer &entry);
-        
-        static void
-        Add(const ConstString &type, const SummaryFormat::SharedPointer &entry);
-        
-        static bool
-        Delete(const ConstString &type);
-        
-        static void
-        Clear();
-        
-        static void
-        LoopThrough(SummaryFormat::SummaryCallback callback, void* callback_baton);
-        
-        static uint32_t
-        GetCurrentRevision();
-    
-        static uint32_t
-        GetCount();
-    };
-    
-    class SystemSummaryFormats
-    {
-    public:
-        
-        static bool
-        Get(ValueObject& vobj, SummaryFormat::SharedPointer &entry);
-        
-        static void
-        Add(const ConstString &type, const SummaryFormat::SharedPointer &entry);
-        
-        static bool
-        Delete(const ConstString &type);
-        
-        static void
-        Clear();
-        
-        static void
-        LoopThrough(SummaryFormat::SummaryCallback callback, void* callback_baton);
-        
-        static uint32_t
-        GetCurrentRevision();
-        
-        static uint32_t
-        GetCount();
-    };
-    
-    class RegexSummaryFormats
-    {
-    public:
-        
-        static bool
-        Get(ValueObject& vobj, SummaryFormat::SharedPointer &entry);
-        
-        static void
-        Add(const lldb::RegularExpressionSP &type, const SummaryFormat::SharedPointer &entry);
-        
-        static bool
-        Delete(const ConstString &type);
-        
-        static void
-        Clear();
-        
-        static void
-        LoopThrough(SummaryFormat::RegexSummaryCallback callback, void* callback_baton);
-        
-        static uint32_t
-        GetCurrentRevision();
-        
-        static uint32_t
-        GetCount();
-    };
-    
-    class SystemRegexSummaryFormats
-    {
-    public:
-        
-        static bool
-        Get(ValueObject& vobj, SummaryFormat::SharedPointer &entry);
-        
-        static void
-        Add(const lldb::RegularExpressionSP &type, const SummaryFormat::SharedPointer &entry);
-        
-        static bool
-        Delete(const ConstString &type);
-        
-        static void
-        Clear();
-        
-        static void
-        LoopThrough(SummaryFormat::RegexSummaryCallback callback, void* callback_baton);
-        
-        static uint32_t
-        GetCurrentRevision();
-        
-        static uint32_t
-        GetCount();
-    };
-    
-    class NamedSummaryFormats
-    {
-    public:
-        
-        static bool
-        Get(const ConstString &type, SummaryFormat::SharedPointer &entry);
-        
-        static void
-        Add(const ConstString &type, const SummaryFormat::SharedPointer &entry);
-        
-        static bool
-        Delete(const ConstString &type);
-        
-        static void
-        Clear();
-        
-        static void
-        LoopThrough(SummaryFormat::SummaryCallback callback, void* callback_baton);
-        
-        static uint32_t
-        GetCurrentRevision();
-        
-        static uint32_t
-        GetCount();
+        class ValueFormats
+        {
+        public:
+            static bool
+            Get(ValueObject& vobj, ValueFormat::SharedPointer &entry);
+            
+            static void
+            Add(const ConstString &type, const ValueFormat::SharedPointer &entry);
+            
+            static bool
+            Delete(const ConstString &type);
+            
+            static void
+            Clear();
+            
+            static void
+            LoopThrough(ValueFormat::ValueCallback callback, void* callback_baton);
+            
+            static uint32_t
+            GetCurrentRevision();
+            
+            static uint32_t
+            GetCount();
+        };
+        
+        static lldb::FormatCategorySP
+        SummaryFormats(const char* category_name = NULL);
+        
+        static bool
+        GetSummaryFormat(ValueObject& vobj,
+                         lldb::SummaryFormatSP& entry);
+        
+        class NamedSummaryFormats
+        {
+        public:
+            static bool
+            Get(const ConstString &type, SummaryFormat::SharedPointer &entry);
+            
+            static void
+            Add(const ConstString &type, const SummaryFormat::SharedPointer &entry);
+            
+            static bool
+            Delete(const ConstString &type);
+            
+            static void
+            Clear();
+            
+            static void
+            LoopThrough(SummaryFormat::SummaryCallback callback, void* callback_baton);
+            
+            static uint32_t
+            GetCurrentRevision();
+            
+            static uint32_t
+            GetCount();
+        };
+                
+        class Categories
+        {
+        public:
+            
+            static bool
+            Get(const ConstString &category, lldb::FormatCategorySP &entry);
+            
+            static void
+            Add(const ConstString &category);
+            
+            static bool
+            Delete(const ConstString &category);
+            
+            static void
+            Clear();
+            
+            static void
+            Clear(ConstString &category);
+            
+            static void
+            Enable(ConstString& category);
+            
+            static void
+            Disable(ConstString& category);
+            
+            static void
+            LoopThrough(FormatManager::CategoryCallback callback, void* callback_baton);
+            
+            static uint32_t
+            GetCurrentRevision();
+            
+            static uint32_t
+            GetCount();
+        };
     };
 };
 

Modified: lldb/trunk/include/lldb/Core/FormatManager.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/FormatManager.h?rev=135463&r1=135462&r2=135463&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/FormatManager.h (original)
+++ lldb/trunk/include/lldb/Core/FormatManager.h Mon Jul 18 21:34:21 2011
@@ -29,6 +29,7 @@
 #include <hash_map>
 #endif
 
+#include <list>
 #include <map>
 #include <stack>
 
@@ -152,20 +153,24 @@
     bool m_show_members_oneliner;
     bool m_is_system;
     
+    uint32_t m_priority;
+    
     SummaryFormat(bool casc = false,
                   bool skipptr = false,
                   bool skipref = false,
                   bool nochildren = true,
                   bool novalue = true,
                   bool oneliner = false,
-                  bool system = false) :
+                  bool system = false,
+                  uint32_t priority = 2) :
     m_cascades(casc),
     m_skip_pointers(skipptr),
     m_skip_references(skipref),
     m_dont_show_children(nochildren),
     m_dont_show_value(novalue),
     m_show_members_oneliner(oneliner),
-    m_is_system(system)
+    m_is_system(system),
+    m_priority(priority)
     {
     }
     
@@ -209,6 +214,18 @@
         return m_is_system;
     }
     
+    uint32_t
+    GetPriority() const
+    {
+        return m_priority;
+    }
+    
+    void
+    SetPriority(uint32_t newprio)
+    {
+        m_priority = newprio;
+    }
+    
     virtual
     ~SummaryFormat()
     {
@@ -238,8 +255,9 @@
                         bool novalue = true,
                         bool oneliner = false,
                         bool system = false,
-                        std::string f = "") :
-    SummaryFormat(casc,skipptr,skipref,nochildren,novalue,oneliner,system),
+                        std::string f = "",
+                        uint32_t priority = 2) :
+    SummaryFormat(casc,skipptr,skipref,nochildren,novalue,oneliner,system, priority),
     m_format(f)
     {
     }
@@ -289,8 +307,9 @@
                         bool oneliner = false,
                         bool system = false,
                         std::string fname = "",
-                        std::string pscri = "") :
-    SummaryFormat(casc,skipptr,skipref,nochildren,novalue,oneliner,system),
+                        std::string pscri = "",
+                        uint32_t priority = 2) :
+    SummaryFormat(casc,skipptr,skipref,nochildren,novalue,oneliner,system,priority),
     m_function_name(fname),
     m_python_script(pscri)
     {
@@ -422,6 +441,8 @@
 template<typename KeyType, typename ValueType>
 class FormatNavigator;
     
+class FormatManager;
+    
 template<typename KeyType, typename ValueType>
 class FormatMap
 {
@@ -431,6 +452,7 @@
     IFormatChangeListener* listener;
     
     friend class FormatNavigator<KeyType, ValueType>;
+    friend class FormatManager;
     
 public:
     typedef std::map<KeyType, ValueSP> MapType;
@@ -528,6 +550,8 @@
     
 };
 
+class FormatCategory;
+    
 template<typename KeyType, typename ValueType>
 class FormatNavigator
 {
@@ -542,6 +566,10 @@
     typedef typename MapType::key_type MapKeyType;
     typedef typename MapType::mapped_type MapValueType;
     typedef typename BackEndType::CallbackType CallbackType;
+    
+    typedef typename lldb::SharedPtr<FormatNavigator<KeyType, ValueType> >::Type SharedPointer;
+    
+    friend class FormatCategory;
 
     FormatNavigator(IFormatChangeListener* lst = NULL) :
     m_format_map(lst)
@@ -561,16 +589,21 @@
     {
         return m_format_map.Delete(type);
     }
-    
+        
     bool
-    Get(ValueObject& vobj, MapValueType& entry)
+    Get(ValueObject& vobj,
+        MapValueType& entry,
+        uint32_t* why = NULL)
     {
+        uint32_t value = lldb::eFormatterDirectChoice;
         clang::QualType type = clang::QualType::getFromOpaquePtr(vobj.GetClangType());
-        bool ret = Get(vobj, type, entry);
-        if(ret)
+        bool ret = Get(vobj, type, entry, value);
+        if (ret)
             entry = MapValueType(entry);
         else
-            entry = MapValueType();
+            entry = MapValueType();        
+        if (why)
+            *why = value;
         return ret;
     }
     
@@ -591,7 +624,7 @@
     {
         return m_format_map.GetCount();
     }
-
+        
 private:
     
     DISALLOW_COPY_AND_ASSIGN(FormatNavigator);
@@ -606,7 +639,8 @@
     
     bool Get(ValueObject& vobj,
              clang::QualType type,
-             MapValueType& entry)
+             MapValueType& entry,
+             uint32_t& reason)
     {
         if (type.isNull())
             return false;
@@ -629,13 +663,19 @@
         // look for a "base type", whatever that means
         if (typePtr->isReferenceType())
         {
-            if (Get(vobj,type.getNonReferenceType(),entry) && !entry->m_skip_references)
+            if (Get(vobj,type.getNonReferenceType(),entry, reason) && !entry->m_skip_references)
+            {
+                reason |= lldb::eFormatterStrippedPointerReference;
                 return true;
+            }
         }
         if (typePtr->isPointerType())
         {
-            if (Get(vobj, typePtr->getPointeeType(), entry) && !entry->m_skip_pointers)
+            if (Get(vobj, typePtr->getPointeeType(), entry, reason) && !entry->m_skip_pointers)
+            {
+                reason |= lldb::eFormatterStrippedPointerReference;
                 return true;
+            }
         }
         if (typePtr->isObjCObjectPointerType())
         {
@@ -649,8 +689,11 @@
             ValueObject* target = vobj.Dereference(error).get();
             if(error.Fail() || !target)
                 return false;
-            if (Get(*target, typePtr->getPointeeType(), entry) && !entry->m_skip_pointers)
+            if (Get(*target, typePtr->getPointeeType(), entry, reason) && !entry->m_skip_pointers)
+            {
+                reason |= lldb::eFormatterStrippedPointerReference;
                 return true;
+            }
         }
         const clang::ObjCObjectType *objc_class_type = typePtr->getAs<clang::ObjCObjectType>();
         if (objc_class_type)
@@ -669,8 +712,11 @@
                     {
                         //printf("the end is here\n");
                         clang::QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl));
-                        if (Get(vobj, ivar_qual_type, entry) && entry->m_cascades)
+                        if (Get(vobj, ivar_qual_type, entry, reason) && entry->m_cascades)
+                        {
+                            reason |= lldb::eFormatterNavigatedBaseClasses;
                             return true;
+                        }
                     }
                 }
             }
@@ -691,8 +737,11 @@
                         end = record->bases_end();
                         for (pos = record->bases_begin(); pos != end; pos++)
                         {
-                            if((Get(vobj, pos->getType(), entry)) && entry->m_cascades)
-                                return true; // if it does not cascade, just move on to other base classes which might
+                            if((Get(vobj, pos->getType(), entry, reason)) && entry->m_cascades)
+                            {
+                                reason |= lldb::eFormatterNavigatedBaseClasses;
+                                return true;
+                            }
                         }
                     }
                     if (record->getNumVBases() > 0)
@@ -700,8 +749,11 @@
                         end = record->vbases_end();
                         for (pos = record->vbases_begin(); pos != end; pos++)
                         {
-                            if((Get(vobj, pos->getType(), entry)) && entry->m_cascades)
+                            if((Get(vobj, pos->getType(), entry, reason)) && entry->m_cascades)
+                            {
+                                reason |= lldb::eFormatterNavigatedBaseClasses;
                                 return true;
+                            }
                         }
                     }
                 }
@@ -711,8 +763,11 @@
         const clang::TypedefType* type_tdef = type->getAs<clang::TypedefType>();
         if (type_tdef)
         {
-            if ((Get(vobj, type_tdef->getDecl()->getUnderlyingType(), entry)) && entry->m_cascades)
+            if ((Get(vobj, type_tdef->getDecl()->getUnderlyingType(), entry, reason)) && entry->m_cascades)
+            {
+                reason |= lldb::eFormatterNavigatedTypedefs;
                 return true;
+            }
         }
         return false;
     }
@@ -726,42 +781,194 @@
 bool
 FormatNavigator<lldb::RegularExpressionSP, SummaryFormat>::Delete(const char* type);
 
-class FormatManager : public IFormatChangeListener
+class FormatCategory
 {
 private:
-    
-    typedef FormatNavigator<const char*, ValueFormat> ValueNavigator;
     typedef FormatNavigator<const char*, SummaryFormat> SummaryNavigator;
     typedef FormatNavigator<lldb::RegularExpressionSP, SummaryFormat> RegexSummaryNavigator;
-    typedef FormatNavigator<const char*, SummaryFormat> ScriptNavigator;
     
-    typedef ValueNavigator::MapType ValueMap;
     typedef SummaryNavigator::MapType SummaryMap;
     typedef RegexSummaryNavigator::MapType RegexSummaryMap;
+        
+    SummaryNavigator::SharedPointer m_summary_nav;
+    RegexSummaryNavigator::SharedPointer m_regex_summary_nav;
+    
+    bool m_enabled;
+    
+    IFormatChangeListener* m_change_listener;
+    
+    Mutex m_mutex;
+    
+public:
+    
+    typedef SummaryNavigator::SharedPointer SummaryNavigatorSP;
+    typedef RegexSummaryNavigator::SharedPointer RegexSummaryNavigatorSP;
+    
+    FormatCategory(IFormatChangeListener* clist) :
+    m_summary_nav(new SummaryNavigator(clist)),
+    m_regex_summary_nav(new RegexSummaryNavigator(clist)),
+    m_enabled(false),
+    m_change_listener(clist),
+    m_mutex(Mutex::eMutexTypeRecursive)
+    {}
+    
+    SummaryNavigatorSP
+    Summary()
+    {
+        return SummaryNavigatorSP(m_summary_nav);
+    }
+    
+    RegexSummaryNavigatorSP
+    RegexSummary()
+    {
+        return RegexSummaryNavigatorSP(m_regex_summary_nav);
+    }
+    
+    bool
+    IsEnabled() const
+    {
+        return m_enabled;
+    }
+    
+    void
+    Enable(bool value = true)
+    {
+        Mutex::Locker(m_mutex);
+        m_enabled = value;        
+        if(m_change_listener)
+            m_change_listener->Changed();
+    }
+    
+    void
+    Disable()
+    {
+        Enable(false);
+    }
+    
+    bool
+    Get(ValueObject& vobj,
+        lldb::SummaryFormatSP& entry,
+        uint32_t* reason = NULL)
+    {
+        if (!IsEnabled())
+            return false;
+        if (Summary()->Get(vobj, entry, reason))
+            return true;
+        bool regex = RegexSummary()->Get(vobj, entry, reason);
+        if (regex && reason)
+            *reason |= lldb::eFormatterRegularExpressionSummary; // penalize regex summaries over normal ones
+        return regex;
+    }
+    
+    void
+    Clear()
+    {
+        m_summary_nav->Clear();
+        m_regex_summary_nav->Clear();
+    }
+    
+    bool
+    Delete(const char* name)
+    {
+        bool del_sum = m_summary_nav->Delete(name);
+        bool del_rex = m_regex_summary_nav->Delete(name);
+        
+        return (del_sum || del_rex);
+    }
+    
+    void
+    ChooseAsPreferential(const char* name);
+    
+    typedef lldb::SharedPtr<FormatCategory>::Type SharedPointer;
+};
+
+class FormatManager : public IFormatChangeListener
+{
+private:
+    
+    typedef FormatNavigator<const char*, ValueFormat> ValueNavigator;
+
+    typedef FormatMap<const char*, FormatCategory> CategoryMap;
+
+    typedef ValueNavigator::MapType ValueMap;
     typedef FormatMap<const char*, SummaryFormat> NamedSummariesMap;
-    typedef ScriptNavigator::MapType ScriptMap;
+    
+    typedef std::list<FormatCategory::SharedPointer> ActiveCategoriesList;
+    
+    typedef ActiveCategoriesList::iterator ActiveCategoriesIterator;
     
     ValueNavigator m_value_nav;
-    SummaryNavigator m_summary_nav;
-    SummaryNavigator m_system_summary_nav;
-    RegexSummaryNavigator m_regex_summary_nav;
-    RegexSummaryNavigator m_system_regex_summary_nav;
-
     NamedSummariesMap m_named_summaries_map;
-        
     uint32_t m_last_revision;
+    CategoryMap m_categories_map;
+    ActiveCategoriesList m_active_categories;
+
+    const char* m_default_category_name;
+    const char* m_system_category_name;
+        
+    typedef CategoryMap::MapType::iterator CategoryMapIterator;
     
-public:
+    bool
+    Get_ExactMatch(ValueObject& vobj,
+                   lldb::SummaryFormatSP& entry)
+    {
+        ActiveCategoriesIterator begin, end = m_active_categories.end();
+        
+        SummaryFormat::SharedPointer current_category_pick;
+        uint32_t reason_to_pick_current;
         
+        for (begin = m_active_categories.begin(); begin != end; begin++)
+        {
+            FormatCategory::SharedPointer category = *begin;
+            if ( category->Get(vobj, current_category_pick, &reason_to_pick_current) && reason_to_pick_current == lldb::eFormatterDirectChoice )
+            {
+                entry = SummaryFormat::SharedPointer(current_category_pick);
+                return true;
+            }
+        }
+        return false;
+    }
+        
+    bool
+    Get_AnyMatch(ValueObject& vobj,
+                 lldb::SummaryFormatSP& entry)
+    {
+        ActiveCategoriesIterator begin, end = m_active_categories.end();
+        
+        SummaryFormat::SharedPointer current_category_pick;
+        
+        for (begin = m_active_categories.begin(); begin != end; begin++)
+        {
+            FormatCategory::SharedPointer category = *begin;
+            if ( category->Get(vobj, current_category_pick, NULL) )
+            {
+                entry = SummaryFormat::SharedPointer(current_category_pick);
+                return true;
+            }
+        }
+        return false;
+    }
+    
+public:
+    
+    typedef bool (*CategoryCallback)(void*, const char*, const FormatCategory::SharedPointer&);
+    
     FormatManager() : 
     m_value_nav(this),
-    m_summary_nav(this),
-    m_system_summary_nav(this),
-    m_regex_summary_nav(this),
-    m_system_regex_summary_nav(this),
     m_named_summaries_map(this),
-    m_last_revision(0)
+    m_last_revision(0),
+    m_categories_map(this),
+    m_active_categories()
     {
+        
+        // build default categories
+        
+        m_default_category_name = ConstString("default").GetCString();
+        m_system_category_name = ConstString("system").GetCString();
+                
+        Category(m_default_category_name)->Enable();
+        Category(m_system_category_name)->Enable();
+        
         // add some default stuff
         // most formats, summaries, ... actually belong to the users' lldbinit file rather than here
         SummaryFormat::SharedPointer string_format(new StringSummaryFormat(false,
@@ -771,34 +978,119 @@
                                                                            false,
                                                                            false,
                                                                            true,
-                                                                           "${var%s}"));
+                                                                           "${var%s}",
+                                                                           1));
         
         
         SummaryFormat::SharedPointer string_array_format(new StringSummaryFormat(false,
-                                                                           true,
-                                                                           false,
-                                                                           false,
-                                                                           false,
-                                                                           false,
-                                                                           true,
-                                                                           "${var%s}"));
+                                                                                 true,
+                                                                                 false,
+                                                                                 false,
+                                                                                 false,
+                                                                                 false,
+                                                                                 true,
+                                                                                 "${var%s}",
+                                                                                 1));
         
         lldb::RegularExpressionSP any_size_char_arr(new RegularExpression("char \\[[0-9]+\\]"));
-                                              
         
-        SystemSummary().Add(ConstString("char *").GetCString(), string_format);
-        SystemSummary().Add(ConstString("const char *").GetCString(), string_format);
-        SystemRegexSummary().Add(any_size_char_arr, string_array_format);
+        
+        Summary(m_system_category_name)->Add(ConstString("char *").GetCString(), string_format);
+        Summary(m_system_category_name)->Add(ConstString("const char *").GetCString(), string_format);
+        RegexSummary(m_system_category_name)->Add(any_size_char_arr, string_array_format);
+        
+        m_active_categories.push_front(Category(m_system_category_name));
+        m_active_categories.push_front(Category(m_default_category_name));
+        
     }
 
-
+    
+    CategoryMap& Categories() { return m_categories_map; }
     ValueNavigator& Value() { return m_value_nav; }
-    SummaryNavigator& Summary() { return m_summary_nav; }
-    SummaryNavigator& SystemSummary() { return m_system_summary_nav; }
-    RegexSummaryNavigator& RegexSummary() { return m_regex_summary_nav; }
-    RegexSummaryNavigator& SystemRegexSummary() { return m_system_regex_summary_nav; }
     NamedSummariesMap& NamedSummary() { return m_named_summaries_map; }
+
+    void
+    EnableCategory(const char* category_name)
+    {
+        Category(category_name)->Enable();
+        m_active_categories.push_front(Category(category_name));
+    }
+    
+    class delete_matching_categories
+    {
+        FormatCategory::SharedPointer ptr;
+    public:
+        delete_matching_categories(FormatCategory::SharedPointer p) : ptr(p)
+        {}
+        
+        bool operator()(const FormatCategory::SharedPointer& other)
+        {
+            return ptr.get() == other.get();
+        }
+    };
+    
+    void
+    DisableCategory(const char* category_name)
+    {
+        Category(category_name)->Disable();
+        m_active_categories.remove_if(delete_matching_categories(Category(category_name)));
+    }
+    
+    void
+    LoopThroughCategories(CategoryCallback callback, void* param)
+    {
+        CategoryMapIterator begin, end = m_categories_map.m_map.end();
+        
+        for (begin = m_categories_map.m_map.begin(); begin != end; begin++)
+        {
+            if (!callback(param, begin->first, begin->second))
+                return;
+        }
+    }
+    
+    FormatCategory::SummaryNavigatorSP
+    Summary(const char* category_name = NULL)
+    {
+        if (!category_name)
+            return Summary(m_default_category_name);
+        lldb::FormatCategorySP category;
+        if (m_categories_map.Get(category_name, category))
+            return category->Summary();
+        return FormatCategory::SummaryNavigatorSP();
+    }
+    
+    FormatCategory::RegexSummaryNavigatorSP
+    RegexSummary(const char* category_name = NULL)
+    {
+        if (!category_name)
+            return RegexSummary(m_default_category_name);
+        lldb::FormatCategorySP category;
+        if (m_categories_map.Get(category_name, category))
+            return category->RegexSummary();
+        return FormatCategory::RegexSummaryNavigatorSP();
+    }
+    
+    lldb::FormatCategorySP
+    Category(const char* category_name = NULL)
+    {
+        if (!category_name)
+            return Category(m_default_category_name);
+        lldb::FormatCategorySP category;
+        if (m_categories_map.Get(category_name, category))
+            return category;
+        Categories().Add(category_name,lldb::FormatCategorySP(new FormatCategory(this)));
+        return Category(category_name);
+    }
     
+    bool
+    Get(ValueObject& vobj,
+        lldb::SummaryFormatSP& entry)
+    {
+        if ( Get_ExactMatch(vobj,entry) )
+            return true;
+        return Get_AnyMatch(vobj,entry);
+    }
+
     static bool
     GetFormatFromCString (const char *format_cstr,
                           bool partial_match_ok,

Modified: lldb/trunk/include/lldb/lldb-enumerations.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=135463&r1=135462&r2=135463&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-enumerations.h (original)
+++ lldb/trunk/include/lldb/lldb-enumerations.h Mon Jul 18 21:34:21 2011
@@ -490,6 +490,20 @@
         eFunctionNameTypeSelector   = (1u << 5)     // Find function by selector name (ObjC) names
     } FunctionNameType;
     
+    // this enum determines how a FormatNavigator picked a specific format for a datatype
+    // these values can be used together (e.g. eFormatterStrippedPointerReference | eFormatterNavigatedBaseClasses
+    // if you went from DerivedType& to BaseType to find a valid format). the priority rules are embedded in the
+    // ordering of these values (i.e. if you want to make a choice look really bad, give it a high value in this
+    // enum). eFormatterDirectChoice should always be left at 0 because it's our favorite choice all the time
+    typedef enum FormatterChoiceCriterion
+    {
+        eFormatterDirectChoice =                  0x00000000,
+        eFormatterStrippedPointerReference =      0x00000001,
+        eFormatterNavigatedTypedefs =             0x00000002,
+        eFormatterNavigatedBaseClasses =          0x00000004,
+        eFormatterRegularExpressionSummary =      0x00000004
+    } FormatterChoiceCriterion;
+    
 
 } // namespace lldb
 

Modified: lldb/trunk/include/lldb/lldb-forward-rtti.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward-rtti.h?rev=135463&r1=135462&r2=135463&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-forward-rtti.h (original)
+++ lldb/trunk/include/lldb/lldb-forward-rtti.h Mon Jul 18 21:34:21 2011
@@ -38,6 +38,7 @@
     typedef SharedPtr<lldb_private::Disassembler>::Type DisassemblerSP;
     typedef SharedPtr<lldb_private::DynamicLoader>::Type DynamicLoaderSP;
     typedef SharedPtr<lldb_private::Event>::Type EventSP;
+    typedef SharedPtr<lldb_private::FormatCategory>::Type FormatCategorySP;
     typedef SharedPtr<lldb_private::Function>::Type FunctionSP;
     typedef SharedPtr<lldb_private::InlineFunctionInfo>::Type InlineFunctionInfoSP;
     typedef SharedPtr<lldb_private::InputReader>::Type InputReaderSP;

Modified: lldb/trunk/include/lldb/lldb-forward.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward.h?rev=135463&r1=135462&r2=135463&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-forward.h (original)
+++ lldb/trunk/include/lldb/lldb-forward.h Mon Jul 18 21:34:21 2011
@@ -76,6 +76,7 @@
 class   FileSpec;
 class   FileSpecList;
 class   Flags;
+class   FormatCategory;
 class   FormatManager;
 class   FuncUnwinders;
 class   Function;

Modified: lldb/trunk/source/Commands/CommandObjectFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectFrame.cpp?rev=135463&r1=135462&r2=135463&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectFrame.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectFrame.cpp Mon Jul 18 21:34:21 2011
@@ -442,7 +442,7 @@
             
             SummaryFormatSP summary_format_sp;
             if (!m_option_variable.summary.empty())
-                Debugger::NamedSummaryFormats::Get(ConstString(m_option_variable.summary.c_str()), summary_format_sp);
+                Debugger::Formatting::NamedSummaryFormats::Get(ConstString(m_option_variable.summary.c_str()), summary_format_sp);
 
             if (variable_list)
             {

Modified: lldb/trunk/source/Commands/CommandObjectType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectType.cpp?rev=135463&r1=135462&r2=135463&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectType.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectType.cpp Mon Jul 18 21:34:21 2011
@@ -196,7 +196,7 @@
             const char* typeA = command.GetArgumentAtIndex(i);
             ConstString typeCS(typeA);
             if (typeCS)
-                Debugger::ValueFormats::Add(typeCS, entry);
+                Debugger::Formatting::ValueFormats::Add(typeCS, entry);
             else
             {
                 result.AppendError("empty typenames not allowed");
@@ -273,7 +273,7 @@
         }
         
         
-        if (Debugger::ValueFormats::Delete(typeCS))
+        if (Debugger::Formatting::ValueFormats::Delete(typeCS))
         {
             result.SetStatus(eReturnStatusSuccessFinishNoResult);
             return result.Succeeded();
@@ -311,7 +311,7 @@
     bool
     Execute (Args& command, CommandReturnObject &result)
     {
-        Debugger::ValueFormats::Clear();
+        Debugger::Formatting::ValueFormats::Clear();
         result.SetStatus(eReturnStatusSuccessFinishResult);
         return result.Succeeded();
     }
@@ -372,7 +372,7 @@
         }
         else
             param = new CommandObjectTypeFormatList_LoopCallbackParam(this,&result);
-        Debugger::ValueFormats::LoopThrough(CommandObjectTypeFormatList_LoopCallback, param);
+        Debugger::Formatting::ValueFormats::LoopThrough(CommandObjectTypeFormatList_LoopCallback, param);
         delete param;
         result.SetStatus(eReturnStatusSuccessFinishResult);
         return result.Succeeded();
@@ -549,7 +549,7 @@
             CommandObjectTypeSummaryAdd::AddSummary(ConstString(type_name),
                                                     script_format,
                                                     (options->m_regex ? CommandObjectTypeSummaryAdd::eRegexSummary : CommandObjectTypeSummaryAdd::eRegularSummary),
-                                                    options->m_is_system,
+                                                    options->m_category,
                                                     &error);
             if (error.Fail())
             {
@@ -566,7 +566,7 @@
                 CommandObjectTypeSummaryAdd::AddSummary(*(options->m_name),
                                                                   script_format,
                                                                   CommandObjectTypeSummaryAdd::eNamedSummary,
-                                                                  options->m_is_system,
+                                                                  options->m_category,
                                                                   &error);
                 if (error.Fail())
                 {
@@ -635,7 +635,7 @@
             m_is_add_script = true;
             break;
         case 'w':
-            m_is_system = true;
+            m_category = ConstString(option_arg).GetCString();
             break;
         default:
             error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
@@ -660,6 +660,7 @@
     m_python_function = "";
     m_is_add_script = false;
     m_is_system = false;
+    m_category = NULL;
 }
 
 void
@@ -786,7 +787,8 @@
                                                          m_options.m_one_liner,
                                                          m_options.m_regex,
                                                          m_options.m_is_system,
-                                                         m_options.m_name);
+                                                         m_options.m_name,
+                                                         m_options.m_category);
         
         for(int i = 0; i < argc; i++) {
             const char* typeA = command.GetArgumentAtIndex(i);
@@ -815,7 +817,7 @@
         CommandObjectTypeSummaryAdd::AddSummary(ConstString(type_name),
                                                 script_format,
                                                 (m_options.m_regex ? eRegexSummary : eRegularSummary),
-                                                m_options.m_is_system,
+                                                m_options.m_category,
                                                 &error);
         if (error.Fail())
         {
@@ -829,7 +831,7 @@
     {
         if ( (bool)(*(m_options.m_name)) )
         {
-            AddSummary(*(m_options.m_name), script_format, eNamedSummary, m_options.m_is_system, &error);
+            AddSummary(*(m_options.m_name), script_format, eNamedSummary, m_options.m_category, &error);
             if (error.Fail())
             {
                 result.AppendError(error.AsCString());
@@ -903,7 +905,7 @@
         AddSummary(typeCS,
                    entry,
                    (m_options.m_regex ? eRegexSummary : eRegularSummary),
-                   m_options.m_is_system,
+                   m_options.m_category,
                    &error);
         
         if (error.Fail())
@@ -918,7 +920,7 @@
     {
         if ( (bool)(*(m_options.m_name)) )
         {
-            AddSummary(*(m_options.m_name), entry, eNamedSummary, m_options.m_is_system, &error);
+            AddSummary(*(m_options.m_name), entry, eNamedSummary, m_options.m_category, &error);
             if (error.Fail())
             {
                 result.AppendError(error.AsCString());
@@ -1037,7 +1039,7 @@
 CommandObjectTypeSummaryAdd::AddSummary(const ConstString& type_name,
                                         SummaryFormatSP entry,
                                         SummaryFormatType type,
-                                        bool is_system,
+                                        const char* category,
                                         Error* error)
 {
     if (type == eRegexSummary)
@@ -1050,30 +1052,20 @@
             return false;
         }
         
-        if (!is_system)
-        {
-            Debugger::RegexSummaryFormats::Delete(type_name);
-            Debugger::RegexSummaryFormats::Add(typeRX, entry);
-        }
-        else
-        {
-            Debugger::SystemRegexSummaryFormats::Delete(type_name);
-            Debugger::SystemRegexSummaryFormats::Add(typeRX, entry);
-        }
+        Debugger::Formatting::SummaryFormats(category)->RegexSummary()->Delete(type_name.GetCString());
+        Debugger::Formatting::SummaryFormats(category)->RegexSummary()->Add(typeRX, entry);
+        
         return true;
     }
     else if (type == eNamedSummary)
     {
         // system named summaries do not exist (yet?)
-        Debugger::NamedSummaryFormats::Add(type_name,entry);
+        Debugger::Formatting::NamedSummaryFormats::Add(type_name,entry);
         return true;
     }
     else
     {
-        if (!is_system)
-            Debugger::SummaryFormats::Add(type_name,entry);
-        else
-            Debugger::SystemSummaryFormats::Add(type_name,entry);
+        Debugger::Formatting::SummaryFormats(category)->Summary()->Add(type_name.GetCString(), entry);
         return true;
     }
 }    
@@ -1081,7 +1073,7 @@
 OptionDefinition
 CommandObjectTypeSummaryAdd::CommandOptions::g_option_table[] =
 {
-    { LLDB_OPT_SET_ALL, false, "system", 'w', no_argument, NULL, 0, eArgTypeBoolean,    "This is a system summary (makes it harder to delete it by accident)."},
+    { 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, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean,    "If true, cascade to derived typedefs."},
     { LLDB_OPT_SET_ALL, false, "no-value", 'v', no_argument, NULL, 0, eArgTypeBoolean,         "Don't show the value, just show the summary, for this type."},
     { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeBoolean,         "Don't use this format for pointers-to-type objects."},
@@ -1126,7 +1118,10 @@
             switch (short_option)
             {
                 case 'a':
-                    m_delete_system = true;
+                    m_delete_all = true;
+                    break;
+                case 'w':
+                    m_category = ConstString(option_arg).GetCString();
                     break;
                 default:
                     error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
@@ -1139,7 +1134,8 @@
         void
         OptionParsingStarting ()
         {
-            m_delete_system = false;
+            m_delete_all = false;
+            m_category = NULL;
         }
         
         const OptionDefinition*
@@ -1154,7 +1150,9 @@
         
         // Instance variables to hold the values for command options.
         
-        bool m_delete_system;
+        bool m_delete_all;
+        const char* m_category;
+        
     };
     
     CommandOptions m_options;
@@ -1164,6 +1162,17 @@
     {
         return &m_options;
     }
+    
+    static bool
+    PerCategoryCallback(void* param,
+                        const char* cate_name,
+                        const FormatCategory::SharedPointer& cate)
+    {
+        const char* name = (const char*)param;
+        cate->Summary()->Delete(name);
+        cate->RegexSummary()->Delete(name);
+        return true;
+    }
 
 public:
     CommandObjectTypeSummaryDelete (CommandInterpreter &interpreter) :
@@ -1210,13 +1219,17 @@
             return false;
         }
         
-        bool delete_summary = Debugger::SummaryFormats::Delete(typeCS);
-        bool delete_regex = Debugger::RegexSummaryFormats::Delete(typeCS);
-        bool delete_named = Debugger::NamedSummaryFormats::Delete(typeCS);
-        bool delete_sys = m_options.m_delete_system ? Debugger::SystemSummaryFormats::Delete(typeCS) : false;
-        bool delete_sys_regex = m_options.m_delete_system ? Debugger::SystemRegexSummaryFormats::Delete(typeCS) : false;
+        if (m_options.m_delete_all)
+        {
+            Debugger::Formatting::Categories::LoopThrough(PerCategoryCallback, (void*)typeCS.GetCString());
+            result.SetStatus(eReturnStatusSuccessFinishNoResult);
+            return result.Succeeded();
+        }
+        
+        bool delete_category = Debugger::Formatting::SummaryFormats(m_options.m_category)->Delete(typeCS.GetCString());
+        bool delete_named = Debugger::Formatting::NamedSummaryFormats::Delete(typeCS);
         
-        if (delete_summary || delete_regex || delete_named || delete_sys || delete_sys_regex)
+        if (delete_category || delete_named)
         {
             result.SetStatus(eReturnStatusSuccessFinishNoResult);
             return result.Succeeded();
@@ -1234,14 +1247,11 @@
 OptionDefinition
 CommandObjectTypeSummaryDelete::CommandOptions::g_option_table[] =
 {
-    { LLDB_OPT_SET_ALL, false, "all", 'a', no_argument, NULL, 0, eArgTypeBoolean,  "Also delete system summaries (not recommended)."},
+    { LLDB_OPT_SET_1, false, "all", 'a', no_argument, NULL, 0, eArgTypeBoolean,  "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 }
 };
 
-//-------------------------------------------------------------------------
-// CommandObjectTypeSummaryClear
-//-------------------------------------------------------------------------
-
 class CommandObjectTypeSummaryClear : public CommandObject
 {
 private:
@@ -1267,7 +1277,7 @@
             switch (short_option)
             {
                 case 'a':
-                    m_delete_system = true;
+                    m_delete_all = true;
                     break;
                 default:
                     error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
@@ -1280,7 +1290,7 @@
         void
         OptionParsingStarting ()
         {
-            m_delete_system = false;
+            m_delete_all = false;
         }
         
         const OptionDefinition*
@@ -1295,7 +1305,8 @@
         
         // Instance variables to hold the values for command options.
         
-        bool m_delete_system;
+        bool m_delete_all;
+        bool m_delete_named;
     };
     
     CommandOptions m_options;
@@ -1305,7 +1316,18 @@
     {
         return &m_options;
     }
-
+    
+    static bool
+    PerCategoryCallback(void* param,
+                        const char* cate_name,
+                        const FormatCategory::SharedPointer& cate)
+    {
+        cate->Summary()->Clear();
+        cate->RegexSummary()->Clear();
+        return true;
+        
+    }
+    
 public:
     CommandObjectTypeSummaryClear (CommandInterpreter &interpreter) :
     CommandObject (interpreter,
@@ -1322,15 +1344,19 @@
     bool
     Execute (Args& command, CommandReturnObject &result)
     {
-        Debugger::SummaryFormats::Clear();
-        Debugger::RegexSummaryFormats::Clear();
-        Debugger::NamedSummaryFormats::Clear();
         
-        if (m_options.m_delete_system)
-        {
-            Debugger::SystemSummaryFormats::Clear();
-            Debugger::SystemRegexSummaryFormats::Clear();
+        if (m_options.m_delete_all)
+            Debugger::Formatting::Categories::LoopThrough(PerCategoryCallback, NULL);
+        else if (command.GetArgumentCount() > 0)
+        {
+            const char* cat_name = command.GetArgumentAtIndex(0);
+            ConstString cat_nameCS(cat_name);
+            Debugger::Formatting::SummaryFormats(cat_nameCS.GetCString())->Clear();
         }
+        else
+            Debugger::Formatting::SummaryFormats()->Clear();
+        
+        Debugger::Formatting::NamedSummaryFormats::Clear();
         
         result.SetStatus(eReturnStatusSuccessFinishResult);
         return result.Succeeded();
@@ -1341,7 +1367,7 @@
 OptionDefinition
 CommandObjectTypeSummaryClear::CommandOptions::g_option_table[] =
 {
-    { LLDB_OPT_SET_ALL, false, "all", 'a', no_argument, NULL, 0, eArgTypeBoolean,  "Also clear system summaries (not recommended)."},
+    { LLDB_OPT_SET_ALL, false, "all", 'a', no_argument, NULL, 0, eArgTypeBoolean,  "Clear every category."},
     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
 };
 
@@ -1362,14 +1388,6 @@
                                                   RegularExpression* X = NULL) : self(S), result(R), regex(X) {}
 };
 
-struct CommandObjectTypeRXSummaryList_LoopCallbackParam {
-    CommandObjectTypeSummaryList* self;
-    CommandReturnObject* result;
-    RegularExpression* regex;
-    CommandObjectTypeRXSummaryList_LoopCallbackParam(CommandObjectTypeSummaryList* S, CommandReturnObject* R,
-                                                   RegularExpression* X = NULL) : self(S), result(R), regex(X) {}
-};
-
 class CommandObjectTypeSummaryList : public CommandObject
 {
 public:
@@ -1400,7 +1418,6 @@
         const size_t argc = command.GetArgumentCount();
         
         CommandObjectTypeSummaryList_LoopCallbackParam *param;
-        CommandObjectTypeRXSummaryList_LoopCallbackParam *rxparam;
         
         if (argc == 1) {
             RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
@@ -1409,26 +1426,10 @@
         }
         else
             param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result);
-        Debugger::SummaryFormats::LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param);
-        Debugger::SystemSummaryFormats::LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param);
-        delete param;
-        
-        if (Debugger::RegexSummaryFormats::GetCount() > 0 || Debugger::SystemRegexSummaryFormats::GetCount() > 0 )
-        {
-            result.GetOutputStream().Printf("Regex-based summaries (slower):\n");
-            if (argc == 1) {
-                RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
-                regex->Compile(command.GetArgumentAtIndex(0));
-                rxparam = new CommandObjectTypeRXSummaryList_LoopCallbackParam(this,&result,regex);
-            }
-            else
-                rxparam = new CommandObjectTypeRXSummaryList_LoopCallbackParam(this,&result);
-            Debugger::RegexSummaryFormats::LoopThrough(CommandObjectTypeRXSummaryList_LoopCallback, rxparam);
-            Debugger::SystemRegexSummaryFormats::LoopThrough(CommandObjectTypeRXSummaryList_LoopCallback, rxparam);
-            delete rxparam;
-        }
         
-        if (Debugger::NamedSummaryFormats::GetCount() > 0)
+        Debugger::Formatting::Categories::LoopThrough(PerCategoryCallback,param);
+                
+        if (Debugger::Formatting::NamedSummaryFormats::GetCount() > 0)
         {
             result.GetOutputStream().Printf("Named summaries:\n");
             if (argc == 1) {
@@ -1438,7 +1439,7 @@
             }
             else
                 param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result);
-            Debugger::NamedSummaryFormats::LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param);
+            Debugger::Formatting::NamedSummaryFormats::LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param);
             delete param;
         }
         
@@ -1448,6 +1449,28 @@
     
 private:
     
+    static bool
+    PerCategoryCallback(void* param,
+                        const char* cate_name,
+                        const FormatCategory::SharedPointer& cate)
+    {
+        
+        CommandReturnObject* result = ((CommandObjectTypeSummaryList_LoopCallbackParam*)param)->result;
+
+        result->GetOutputStream().Printf("-----------------------\nCategory: %s (%s)\n-----------------------\n",
+                                         cate_name,
+                                         (cate->IsEnabled() ? "enabled" : "disabled"));
+        
+        cate->Summary()->LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param);
+        
+        if (cate->RegexSummary()->GetCount() > 0)
+        {
+            result->GetOutputStream().Printf("Regex-based summaries (slower):\n");
+            cate->RegexSummary()->LoopThrough(CommandObjectTypeRXSummaryList_LoopCallback, param);
+        }
+        return true;
+    }
+    
     bool
     LoopCallback (const char* type,
                   const SummaryFormat::SharedPointer& entry,
@@ -1479,10 +1502,233 @@
                                            lldb::RegularExpressionSP regex,
                                            const SummaryFormat::SharedPointer& entry)
 {
-    CommandObjectTypeRXSummaryList_LoopCallbackParam* param = (CommandObjectTypeRXSummaryList_LoopCallbackParam*)pt2self;
+    CommandObjectTypeSummaryList_LoopCallbackParam* param = (CommandObjectTypeSummaryList_LoopCallbackParam*)pt2self;
     return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result);
 }
 
+//-------------------------------------------------------------------------
+// CommandObjectTypeCategoryEnable
+//-------------------------------------------------------------------------
+
+class CommandObjectTypeCategoryEnable : public CommandObject
+{
+public:
+    CommandObjectTypeCategoryEnable (CommandInterpreter &interpreter) :
+    CommandObject (interpreter,
+                   "type category enable",
+                   "Enable a category as a source of summaries.",
+                   NULL)
+    {
+        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);
+        
+    }
+    
+    ~CommandObjectTypeCategoryEnable ()
+    {
+    }
+    
+    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 category name not allowed");
+            result.SetStatus(eReturnStatusFailed);
+            return false;
+        }
+        
+        Debugger::Formatting::Categories::Enable(typeCS);
+        result.SetStatus(eReturnStatusSuccessFinishResult);
+        return result.Succeeded();
+    }
+    
+};
+
+//-------------------------------------------------------------------------
+// CommandObjectTypeCategoryDelete
+//-------------------------------------------------------------------------
+
+class CommandObjectTypeCategoryDelete : public CommandObject
+{
+public:
+    CommandObjectTypeCategoryDelete (CommandInterpreter &interpreter) :
+    CommandObject (interpreter,
+                   "type category delete",
+                   "Delete a category and all associated summaries.",
+                   NULL)
+    {
+        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);
+        
+    }
+    
+    ~CommandObjectTypeCategoryDelete ()
+    {
+    }
+    
+    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 category name not allowed");
+            result.SetStatus(eReturnStatusFailed);
+            return false;
+        }
+        
+        if (Debugger::Formatting::Categories::Delete(typeCS))
+        {
+            result.SetStatus(eReturnStatusSuccessFinishResult);
+            return result.Succeeded();
+        }
+        else
+        {
+            result.AppendErrorWithFormat ("cannot delete category %s.\n", typeA);
+            result.SetStatus(eReturnStatusFailed);
+            return false;
+        }        
+    }
+    
+};
+
+//-------------------------------------------------------------------------
+// CommandObjectTypeCategoryDisable
+//-------------------------------------------------------------------------
+
+class CommandObjectTypeCategoryDisable : public CommandObject
+{
+public:
+    CommandObjectTypeCategoryDisable (CommandInterpreter &interpreter) :
+    CommandObject (interpreter,
+                   "type category disable",
+                   "Disable a category as a source of summaries.",
+                   NULL)
+    {
+        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);
+        
+    }
+    
+    ~CommandObjectTypeCategoryDisable ()
+    {
+    }
+    
+    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 category name not allowed");
+            result.SetStatus(eReturnStatusFailed);
+            return false;
+        }
+        
+        Debugger::Formatting::Categories::Disable(typeCS);
+        result.SetStatus(eReturnStatusSuccessFinishResult);
+        return result.Succeeded();
+    }
+    
+};
+
+//-------------------------------------------------------------------------
+// CommandObjectTypeCategoryList
+//-------------------------------------------------------------------------
+
+class CommandObjectTypeCategoryList : public CommandObject
+{
+private:
+    static bool
+    PerCategoryCallback(void* param,
+                        const char* cate_name,
+                        const FormatCategory::SharedPointer& cate)
+    {
+        CommandReturnObject* result = (CommandReturnObject*)param;
+        result->GetOutputStream().Printf("Category %s is%s enabled\n",
+                                       cate_name,
+                                       (cate->IsEnabled() ? "" : " not"));
+        return true;
+    }
+public:
+    CommandObjectTypeCategoryList (CommandInterpreter &interpreter) :
+    CommandObject (interpreter,
+                   "type category list",
+                   "Provide a list of all existing categories.",
+                   NULL)
+    {
+    }
+    
+    ~CommandObjectTypeCategoryList ()
+    {
+    }
+    
+    bool
+    Execute (Args& command, CommandReturnObject &result)
+    {
+        Debugger::Formatting::Categories::LoopThrough(PerCategoryCallback, (void*)&result);
+        result.SetStatus(eReturnStatusSuccessFinishResult);
+        return result.Succeeded();
+    }
+    
+};
+
 class CommandObjectTypeFormat : public CommandObjectMultiword
 {
 public:
@@ -1504,6 +1750,27 @@
     }
 };
 
+class CommandObjectTypeCategory : public CommandObjectMultiword
+{
+public:
+    CommandObjectTypeCategory (CommandInterpreter &interpreter) :
+    CommandObjectMultiword (interpreter,
+                            "type category",
+                            "A set of commands for operating on categories",
+                            "type category [<sub-command-options>] ")
+    {
+        LoadSubCommand ("enable",        CommandObjectSP (new CommandObjectTypeCategoryEnable (interpreter)));
+        LoadSubCommand ("disable",       CommandObjectSP (new CommandObjectTypeCategoryDisable (interpreter)));
+        LoadSubCommand ("delete",        CommandObjectSP (new CommandObjectTypeCategoryDelete (interpreter)));
+        LoadSubCommand ("list",          CommandObjectSP (new CommandObjectTypeCategoryList (interpreter)));
+    }
+    
+    
+    ~CommandObjectTypeCategory ()
+    {
+    }
+};
+
 class CommandObjectTypeSummary : public CommandObjectMultiword
 {
 public:
@@ -1535,6 +1802,7 @@
                             "A set of commands for operating on the type system",
                             "type [<sub-command-options>]")
 {
+    LoadSubCommand ("category",  CommandObjectSP (new CommandObjectTypeCategory (interpreter)));
     LoadSubCommand ("format",    CommandObjectSP (new CommandObjectTypeFormat (interpreter)));
     LoadSubCommand ("summary",   CommandObjectSP (new CommandObjectTypeSummary (interpreter)));
 }

Modified: lldb/trunk/source/Commands/CommandObjectType.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectType.h?rev=135463&r1=135462&r2=135463&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectType.h (original)
+++ lldb/trunk/source/Commands/CommandObjectType.h Mon Jul 18 21:34:21 2011
@@ -43,6 +43,8 @@
     
     ConstString* m_name;
     
+    const char* m_category;
+    
     ScriptAddOptions(bool sptr,
                      bool sref,
                      bool casc,
@@ -51,7 +53,8 @@
                      bool onel,
                      bool regx,
                      bool syst,
-                     ConstString* name) :
+                     ConstString* name,
+                     const char* catg) :
     m_skip_pointers(sptr),
     m_skip_references(sref),
     m_cascade(casc),
@@ -62,7 +65,8 @@
     m_one_liner(onel),
     m_regex(regx),
     m_is_system(syst),
-    m_name(name)
+    m_name(name),
+    m_category(catg)
     {
     }
     
@@ -127,6 +131,7 @@
         std::string m_python_function;
         bool m_is_add_script;
         bool m_is_system;
+        const char* m_category;
     };
     
     CommandOptions m_options;
@@ -169,7 +174,7 @@
     AddSummary(const ConstString& type_name,
                lldb::SummaryFormatSP entry,
                SummaryFormatType type,
-               bool is_system,
+               const char* category,
                Error* error = NULL);
 };
 

Modified: lldb/trunk/source/Core/Debugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=135463&r1=135462&r2=135463&view=diff
==============================================================================
--- lldb/trunk/source/Core/Debugger.cpp (original)
+++ lldb/trunk/source/Core/Debugger.cpp Mon Jul 18 21:34:21 2011
@@ -1714,253 +1714,175 @@
 }
 
 bool
-Debugger::ValueFormats::Get(ValueObject& vobj, ValueFormat::SharedPointer &entry)
+Debugger::Formatting::ValueFormats::Get(ValueObject& vobj, ValueFormat::SharedPointer &entry)
 {
     return GetFormatManager().Value().Get(vobj,entry);
 }
 
 void
-Debugger::ValueFormats::Add(const ConstString &type, const ValueFormat::SharedPointer &entry)
+Debugger::Formatting::ValueFormats::Add(const ConstString &type, const ValueFormat::SharedPointer &entry)
 {
     GetFormatManager().Value().Add(type.AsCString(),entry);
 }
 
 bool
-Debugger::ValueFormats::Delete(const ConstString &type)
+Debugger::Formatting::ValueFormats::Delete(const ConstString &type)
 {
     return GetFormatManager().Value().Delete(type.AsCString());
 }
 
 void
-Debugger::ValueFormats::Clear()
+Debugger::Formatting::ValueFormats::Clear()
 {
     GetFormatManager().Value().Clear();
 }
 
 void
-Debugger::ValueFormats::LoopThrough(ValueFormat::ValueCallback callback, void* callback_baton)
+Debugger::Formatting::ValueFormats::LoopThrough(ValueFormat::ValueCallback callback, void* callback_baton)
 {
     GetFormatManager().Value().LoopThrough(callback, callback_baton);
 }
 
 uint32_t
-Debugger::ValueFormats::GetCurrentRevision()
+Debugger::Formatting::ValueFormats::GetCurrentRevision()
 {
     return GetFormatManager().GetCurrentRevision();
 }
 
 uint32_t
-Debugger::ValueFormats::GetCount()
+Debugger::Formatting::ValueFormats::GetCount()
 {
     return GetFormatManager().Value().GetCount();
 }
 
-bool
-Debugger::SummaryFormats::Get(ValueObject& vobj, SummaryFormat::SharedPointer &entry)
-{
-    return GetFormatManager().Summary().Get(vobj,entry);
-}
-
-void
-Debugger::SummaryFormats::Add(const ConstString &type, const SummaryFormat::SharedPointer &entry)
-{
-    GetFormatManager().Summary().Add(type.AsCString(),entry);
-}
-
-bool
-Debugger::SummaryFormats::Delete(const ConstString &type)
-{
-    return GetFormatManager().Summary().Delete(type.AsCString());
-}
-
-void
-Debugger::SummaryFormats::Clear()
-{
-    GetFormatManager().Summary().Clear();
-}
-
-void
-Debugger::SummaryFormats::LoopThrough(SummaryFormat::SummaryCallback callback, void* callback_baton)
-{
-    GetFormatManager().Summary().LoopThrough(callback, callback_baton);
-}
-
-uint32_t
-Debugger::SummaryFormats::GetCurrentRevision()
-{
-    return GetFormatManager().GetCurrentRevision();
-}
-
-uint32_t
-Debugger::SummaryFormats::GetCount()
+lldb::FormatCategorySP
+Debugger::Formatting::SummaryFormats(const char* category_name)
 {
-    return GetFormatManager().Summary().GetCount();
+    return GetFormatManager().Category(category_name);
 }
 
 bool
-Debugger::SystemSummaryFormats::Get(ValueObject& vobj, SummaryFormat::SharedPointer &entry)
-{
-    return GetFormatManager().SystemSummary().Get(vobj,entry);
-}
-
-void
-Debugger::SystemSummaryFormats::Add(const ConstString &type, const SummaryFormat::SharedPointer &entry)
-{
-    GetFormatManager().SystemSummary().Add(type.AsCString(),entry);
-}
-
-bool
-Debugger::SystemSummaryFormats::Delete(const ConstString &type)
-{
-    return GetFormatManager().SystemSummary().Delete(type.AsCString());
-}
-
-void
-Debugger::SystemSummaryFormats::Clear()
+Debugger::Formatting::GetSummaryFormat(ValueObject& vobj,
+                                       lldb::SummaryFormatSP& entry)
 {
-    GetFormatManager().SystemSummary().Clear();
-}
-
-void
-Debugger::SystemSummaryFormats::LoopThrough(SummaryFormat::SummaryCallback callback, void* callback_baton)
-{
-    GetFormatManager().SystemSummary().LoopThrough(callback, callback_baton);
-}
-
-uint32_t
-Debugger::SystemSummaryFormats::GetCurrentRevision()
-{
-    return GetFormatManager().GetCurrentRevision();
-}
-
-uint32_t
-Debugger::SystemSummaryFormats::GetCount()
-{
-    return GetFormatManager().SystemSummary().GetCount();
+    return GetFormatManager().Get(vobj, entry);
 }
 
 bool
-Debugger::RegexSummaryFormats::Get(ValueObject& vobj, SummaryFormat::SharedPointer &entry)
+Debugger::Formatting::Categories::Get(const ConstString &category, lldb::FormatCategorySP &entry)
 {
-    return GetFormatManager().RegexSummary().Get(vobj,entry);
+    entry = GetFormatManager().Category(category.GetCString());
+    return true;
 }
 
 void
-Debugger::RegexSummaryFormats::Add(const lldb::RegularExpressionSP &type, const SummaryFormat::SharedPointer &entry)
+Debugger::Formatting::Categories::Add(const ConstString &category)
 {
-    GetFormatManager().RegexSummary().Add(type,entry);
+    GetFormatManager().Category(category.GetCString());
 }
 
 bool
-Debugger::RegexSummaryFormats::Delete(const ConstString &type)
+Debugger::Formatting::Categories::Delete(const ConstString &category)
 {
-    return GetFormatManager().RegexSummary().Delete(type.AsCString());
+    GetFormatManager().DisableCategory(category.GetCString());
+    return GetFormatManager().Categories().Delete(category.GetCString());
 }
 
 void
-Debugger::RegexSummaryFormats::Clear()
+Debugger::Formatting::Categories::Clear()
 {
-    GetFormatManager().RegexSummary().Clear();
+    GetFormatManager().Categories().Clear();
 }
 
 void
-Debugger::RegexSummaryFormats::LoopThrough(SummaryFormat::RegexSummaryCallback callback, void* callback_baton)
-{
-    GetFormatManager().RegexSummary().LoopThrough(callback, callback_baton);
-}
-
-uint32_t
-Debugger::RegexSummaryFormats::GetCurrentRevision()
-{
-    return GetFormatManager().GetCurrentRevision();
-}
-
-uint32_t
-Debugger::RegexSummaryFormats::GetCount()
-{
-    return GetFormatManager().RegexSummary().GetCount();
-}
-
-bool
-Debugger::SystemRegexSummaryFormats::Get(ValueObject& vobj, SummaryFormat::SharedPointer &entry)
+Debugger::Formatting::Categories::Clear(ConstString &category)
 {
-    return GetFormatManager().SystemRegexSummary().Get(vobj,entry);
+    GetFormatManager().Category(category.GetCString())->Clear();
 }
 
 void
-Debugger::SystemRegexSummaryFormats::Add(const lldb::RegularExpressionSP &type, const SummaryFormat::SharedPointer &entry)
+Debugger::Formatting::Categories::Enable(ConstString& category)
 {
-    GetFormatManager().SystemRegexSummary().Add(type,entry);
-}
-
-bool
-Debugger::SystemRegexSummaryFormats::Delete(const ConstString &type)
-{
-    return GetFormatManager().SystemRegexSummary().Delete(type.AsCString());
+    if (GetFormatManager().Category(category.GetCString())->IsEnabled() == false)
+    {
+        //GetFormatManager().Category(category.GetCString())->Enable();
+        GetFormatManager().EnableCategory(category.GetCString());
+    }
+    else
+    {
+        //GetFormatManager().Category(category.GetCString())->Disable();
+        GetFormatManager().DisableCategory(category.GetCString());
+        //GetFormatManager().Category(category.GetCString())->Enable();
+        GetFormatManager().EnableCategory(category.GetCString());
+    }
 }
 
 void
-Debugger::SystemRegexSummaryFormats::Clear()
+Debugger::Formatting::Categories::Disable(ConstString& category)
 {
-    GetFormatManager().SystemRegexSummary().Clear();
+    if (GetFormatManager().Category(category.GetCString())->IsEnabled() == true)
+    {
+        //GetFormatManager().Category(category.GetCString())->Disable();
+        GetFormatManager().DisableCategory(category.GetCString());
+    }
 }
 
 void
-Debugger::SystemRegexSummaryFormats::LoopThrough(SummaryFormat::RegexSummaryCallback callback, void* callback_baton)
+Debugger::Formatting::Categories::LoopThrough(FormatManager::CategoryCallback callback, void* callback_baton)
 {
-    GetFormatManager().SystemRegexSummary().LoopThrough(callback, callback_baton);
+    GetFormatManager().LoopThroughCategories(callback, callback_baton);
 }
 
 uint32_t
-Debugger::SystemRegexSummaryFormats::GetCurrentRevision()
+Debugger::Formatting::Categories::GetCurrentRevision()
 {
     return GetFormatManager().GetCurrentRevision();
 }
 
 uint32_t
-Debugger::SystemRegexSummaryFormats::GetCount()
+Debugger::Formatting::Categories::GetCount()
 {
-    return GetFormatManager().SystemRegexSummary().GetCount();
+    return GetFormatManager().Categories().GetCount();
 }
 
 bool
-Debugger::NamedSummaryFormats::Get(const ConstString &type, SummaryFormat::SharedPointer &entry)
+Debugger::Formatting::NamedSummaryFormats::Get(const ConstString &type, SummaryFormat::SharedPointer &entry)
 {
     return GetFormatManager().NamedSummary().Get(type.AsCString(),entry);
 }
 
 void
-Debugger::NamedSummaryFormats::Add(const ConstString &type, const SummaryFormat::SharedPointer &entry)
+Debugger::Formatting::NamedSummaryFormats::Add(const ConstString &type, const SummaryFormat::SharedPointer &entry)
 {
     GetFormatManager().NamedSummary().Add(type.AsCString(),entry);
 }
 
 bool
-Debugger::NamedSummaryFormats::Delete(const ConstString &type)
+Debugger::Formatting::NamedSummaryFormats::Delete(const ConstString &type)
 {
     return GetFormatManager().NamedSummary().Delete(type.AsCString());
 }
 
 void
-Debugger::NamedSummaryFormats::Clear()
+Debugger::Formatting::NamedSummaryFormats::Clear()
 {
     GetFormatManager().NamedSummary().Clear();
 }
 
 void
-Debugger::NamedSummaryFormats::LoopThrough(SummaryFormat::SummaryCallback callback, void* callback_baton)
+Debugger::Formatting::NamedSummaryFormats::LoopThrough(SummaryFormat::SummaryCallback callback, void* callback_baton)
 {
     GetFormatManager().NamedSummary().LoopThrough(callback, callback_baton);
 }
 
 uint32_t
-Debugger::NamedSummaryFormats::GetCurrentRevision()
+Debugger::Formatting::NamedSummaryFormats::GetCurrentRevision()
 {
     return GetFormatManager().GetCurrentRevision();
 }
 
 uint32_t
-Debugger::NamedSummaryFormats::GetCount()
+Debugger::Formatting::NamedSummaryFormats::GetCount()
 {
     return GetFormatManager().NamedSummary().GetCount();
 }

Modified: lldb/trunk/source/Core/FormatManager.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FormatManager.cpp?rev=135463&r1=135462&r2=135463&view=diff
==============================================================================
--- lldb/trunk/source/Core/FormatManager.cpp (original)
+++ lldb/trunk/source/Core/FormatManager.cpp Mon Jul 18 21:34:21 2011
@@ -184,6 +184,8 @@
         if ( ::strcmp(type,regex->GetText()) == 0)
         {
             m_format_map.map().erase(pos);
+            if(m_format_map.listener)
+                m_format_map.listener->Changed();
             return true;
         }
     }
@@ -270,3 +272,23 @@
     }
 }
 
+void
+FormatCategory::ChooseAsPreferential(const char* name)
+{
+    Mutex::Locker(m_mutex);
+    lldb::SummaryFormatSP format;
+    
+    uint32_t revision = Debugger::Formatting::ValueFormats::GetCurrentRevision();
+    
+    if ( Summary()->Get(name, format) )
+        format->SetPriority(revision);
+    
+    format.reset();
+    
+    if ( RegexSummary()->Get(name, format) )
+        format->SetPriority(revision);
+    
+    if(m_change_listener)
+        m_change_listener->Changed();
+    
+}

Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=135463&r1=135462&r2=135463&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Mon Jul 18 21:34:21 2011
@@ -202,22 +202,21 @@
         ClearCustomSummaryFormat();
         m_summary_str.clear();
     }
-    if (m_last_format_mgr_revision != Debugger::ValueFormats::GetCurrentRevision())
+    if (m_last_format_mgr_revision != Debugger::Formatting::ValueFormats::GetCurrentRevision())
     {
         if (m_last_summary_format.get())
             m_last_summary_format.reset((StringSummaryFormat*)NULL);
         if (m_last_value_format.get())
             m_last_value_format.reset((ValueFormat*)NULL);
-        Debugger::ValueFormats::Get(*this, m_last_value_format);
+        Debugger::Formatting::ValueFormats::Get(*this, m_last_value_format);
         // to find a summary we look for a direct summary, then if there is none
         // we look for a regex summary. if there is none we look for a system
         // summary (direct), and if also that fails, we look for a system
         // regex summary
-        if (!Debugger::SummaryFormats::Get(*this, m_last_summary_format))
-            if (!Debugger::RegexSummaryFormats::Get(*this, m_last_summary_format))
-                if (!Debugger::SystemSummaryFormats::Get(*this, m_last_summary_format))
-                    Debugger::SystemRegexSummaryFormats::Get(*this, m_last_summary_format);
-        m_last_format_mgr_revision = Debugger::ValueFormats::GetCurrentRevision();
+        
+        Debugger::Formatting::GetSummaryFormat(*this, m_last_summary_format);
+
+        m_last_format_mgr_revision = Debugger::Formatting::ValueFormats::GetCurrentRevision();
 
         ClearUserVisibleData();
     }

Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-categories/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-categories/Makefile?rev=135463&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-categories/Makefile (added)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-categories/Makefile Mon Jul 18 21:34:21 2011
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules

Added: 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=135463&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py (added)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py Mon Jul 18 21:34:21 2011
@@ -0,0 +1,252 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+
+class DataFormatterTestCase(TestBase):
+
+    mydir = os.path.join("functionalities", "data-formatter", "data-formatter-categories")
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    def test_with_dsym_and_run_command(self):
+        """Test data formatter commands."""
+        self.buildDsym()
+        self.data_formatter_commands()
+
+    def test_with_dwarf_and_run_command(self):
+        """Test data formatter commands."""
+        self.buildDwarf()
+        self.data_formatter_commands()
+
+    def setUp(self):
+        # Call super's setUp().
+        TestBase.setUp(self)
+        # Find the line number to break at.
+        self.line = line_number('main.cpp', '// Set break point at this line.')
+
+    def data_formatter_commands(self):
+        """Test that that file and class static variables display correctly."""
+        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
+                    BREAKPOINT_CREATED,
+            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" %
+                        self.line)
+
+        self.runCmd("run", RUN_SUCCEEDED)
+
+        # The stop reason of the thread should be breakpoint.
+        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+            substrs = ['stopped',
+                       'stop reason = breakpoint'])
+
+        # This is the function to remove the custom formats in order to have a
+        # clean slate for the next test case.
+        def cleanup():
+            self.runCmd('type format clear', check=False)
+            self.runCmd('type summary clear', check=False)
+            self.runCmd('type category delete Category1', check=False)
+            self.runCmd('type category delete Category2', check=False)
+            self.runCmd('type category delete NewCategory', check=False)
+
+        # Execute the cleanup function during test case tear down.
+        self.addTearDownHook(cleanup)
+
+        # Add a summary to a new category and check that it works
+        self.runCmd("type summary add Rectangle -f \"ARectangle\" -w NewCategory")
+
+        self.expect("frame variable r1 r2 r3", matching=False,
+            substrs = ['r1 = ARectangle',
+                       'r2 = ARectangle',
+                       'r3 = ARectangle'])
+        
+        self.runCmd("type category enable NewCategory")
+
+        self.expect("frame variable r1 r2 r3", matching=True,
+                    substrs = ['r1 = ARectangle',
+                               'r2 = ARectangle',
+                               'r3 = ARectangle'])
+        
+        # Disable the category and check that the old stuff is there
+        self.runCmd("type category disable NewCategory")
+
+        self.expect("frame variable r1 r2 r3",
+                    substrs = ['r1 = {',
+                               'r2 = {',
+                               'r3 = {'])
+
+        # Re-enable the category and check that it works
+        self.runCmd("type category enable NewCategory")
+
+        self.expect("frame variable r1 r2 r3",
+                    substrs = ['r1 = ARectangle',
+                               'r2 = ARectangle',
+                               'r3 = ARectangle'])
+
+        # Delete the category and the old stuff should be there
+        self.runCmd("type category delete NewCategory")
+
+        self.expect("frame variable r1 r2 r3",
+                    substrs = ['r1 = {',
+                               'r2 = {',
+                               'r3 = {'])
+
+        # Add summaries to two different categories and check that we can switch
+        self.runCmd("type summary add -f \"Width = ${var.w}, Height = ${var.h}\" Rectangle -w Category1")
+        self.runCmd("type summary add -s \"return 'Area = ' + str( int(valobj.GetChildMemberWithName('w').GetValue()) * int(valobj.GetChildMemberWithName('h').GetValue()) );\" Rectangle -w Category2")
+
+        self.runCmd("type category enable Category2")
+        self.runCmd("type category enable Category1")
+        
+        self.expect("frame variable r1 r2 r3",
+                    substrs = ['r1 = Width = ',
+                               'r2 = Width = ',
+                               'r3 = Width = '])
+
+        self.runCmd("type category disable Category1")
+
+        self.expect("frame variable r1 r2 r3",
+                    substrs = ['r1 = Area = ',
+                               'r2 = Area = ',
+                               'r3 = Area = '])
+
+        # switch again
+
+        self.runCmd("type category enable Category1")
+
+        self.expect("frame variable r1 r2 r3",
+                    substrs = ['r1 = Width = ',
+                               'r2 = Width = ',
+                               'r3 = Width = '])
+
+        # Re-enable the category and show that the preference is persisted
+        self.runCmd("type category disable Category2")
+        self.runCmd("type category enable Category2")
+        
+        self.expect("frame variable r1 r2 r3",
+                    substrs = ['r1 = Area = ',
+                               'r2 = Area = ',
+                               'r3 = Area = '])
+
+        # Now delete the favorite summary
+        self.runCmd("type summary delete Rectangle -w Category2")
+
+        self.expect("frame variable r1 r2 r3",
+                    substrs = ['r1 = Width = ',
+                               'r2 = Width = ',
+                               'r3 = Width = '])
+
+        # Delete the summary from the default category (that does not have it)
+        self.runCmd("type summary delete Rectangle", check=False)
+
+        self.expect("frame variable r1 r2 r3",
+                    substrs = ['r1 = Width = ',
+                               'r2 = Width = ',
+                               'r3 = Width = '])
+
+        # Now add another summary to another category and switch back and forth
+        self.runCmd("type category delete Category1")
+        self.runCmd("type category delete Category2")
+
+        self.runCmd("type summary add Rectangle -f \"Category1\" -w Category1")
+        self.runCmd("type summary add Rectangle -f \"Category2\" -w Category2")
+
+        self.runCmd("type category enable Category2")
+        self.runCmd("type category enable Category1")
+        
+        self.expect("frame variable r1 r2 r3",
+                substrs = ['r1 = Category1',
+                           'r2 = Category1',
+                           'r3 = Category1'])
+
+        self.runCmd("type category disable Category1")
+
+        self.expect("frame variable r1 r2 r3",
+                    substrs = ['r1 = Category2',
+                               'r2 = Category2',
+                               'r3 = Category2'])
+
+        self.runCmd("type category disable Category1")
+        self.runCmd("type category enable Category1")
+
+        self.expect("frame variable r1 r2 r3",
+                    substrs = ['r1 = Category1',
+                               'r2 = Category1',
+                               'r3 = Category1'])
+
+        self.runCmd("type category delete Category1")
+        self.runCmd("type category delete Category2")
+
+        self.expect("frame variable r1 r2 r3",
+                    substrs = ['r1 = {',
+                               'r2 = {',
+                               'r3 = {'])
+
+        # Check that multiple summaries can go into one category 
+        self.runCmd("type summary add -f \"Width = ${var.w}, Height = ${var.h}\" Rectangle -w Category1")
+        self.runCmd("type summary add -f \"Radius = ${var.r}\" Circle -w Category1")
+        
+        self.runCmd("type category enable Category1")
+
+        self.expect("frame variable r1 r2 r3",
+                    substrs = ['r1 = Width = ',
+                               'r2 = Width = ',
+                               'r3 = Width = '])
+
+        self.expect("frame variable c1 c2 c3",
+                    substrs = ['c1 = Radius = ',
+                               'c2 = Radius = ',
+                               'c3 = Radius = '])
+
+        self.runCmd("type summary delete Circle -w Category1")
+            
+        self.expect("frame variable c1 c2 c3",
+                    substrs = ['c1 = {',
+                               'c2 = {',
+                               'c3 = {'])
+
+        # Add a regex based summary to a category
+        self.runCmd("type summary add -f \"Radius = ${var.r}\" -x Circle -w Category1")
+
+        self.expect("frame variable r1 r2 r3",
+                    substrs = ['r1 = Width = ',
+                               'r2 = Width = ',
+                               'r3 = Width = '])
+
+        self.expect("frame variable c1 c2 c3",
+                    substrs = ['c1 = Radius = ',
+                               'c2 = Radius = ',
+                               'c3 = Radius = '])
+
+        # Delete it
+        self.runCmd("type summary delete Circle -w Category1")
+
+        self.expect("frame variable c1 c2 c3",
+                    substrs = ['c1 = {',
+                               'c2 = {',
+                               'c3 = {'])
+        
+        # Change a summary inside a category and check that the change is reflected
+        self.runCmd("type summary add Circle -w Category1 -f \"summary1\"")
+
+        self.expect("frame variable c1 c2 c3",
+                    substrs = ['c1 = summary1',
+                               'c2 = summary1',
+                               'c3 = summary1'])
+
+        self.runCmd("type summary add Circle -w Category1 -f \"summary2\"")
+        
+        self.expect("frame variable c1 c2 c3",
+                    substrs = ['c1 = summary2',
+                               'c2 = summary2',
+                               'c3 = summary2'])
+
+if __name__ == '__main__':
+    import atexit
+    lldb.SBDebugger.Initialize()
+    atexit.register(lambda: lldb.SBDebugger.Terminate())
+    unittest2.main()

Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-categories/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-categories/main.cpp?rev=135463&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-categories/main.cpp (added)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-categories/main.cpp Mon Jul 18 21:34:21 2011
@@ -0,0 +1,37 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+struct Rectangle {
+    int w;
+    int h;
+    Rectangle(int W = 3, int H = 5) : w(W), h(H) {}
+};
+
+struct Circle {
+    int r;
+    Circle(int R = 6) : r(R) {}
+};
+
+int main (int argc, const char * argv[])
+{
+    Rectangle r1(5,6);
+    Rectangle r2(9,16);
+    Rectangle r3(4,4);
+    
+    Circle c1(5);
+    Circle c2(6);
+    Circle c3(7);
+    
+    return 0; // Set break point at this line.
+}
+

Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-globals/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-globals/Makefile?rev=135463&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-globals/Makefile (added)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-globals/Makefile Mon Jul 18 21:34:21 2011
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-globals/TestDataFormatterGlobals.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-globals/TestDataFormatterGlobals.py?rev=135463&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-globals/TestDataFormatterGlobals.py (added)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-globals/TestDataFormatterGlobals.py Mon Jul 18 21:34:21 2011
@@ -0,0 +1,83 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+
+class DataFormatterTestCase(TestBase):
+
+    mydir = os.path.join("functionalities", "data-formatter", "data-formatter-globals")
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    def test_with_dsym_and_run_command(self):
+        """Test data formatter commands."""
+        self.buildDsym()
+        self.data_formatter_commands()
+
+    def test_with_dwarf_and_run_command(self):
+        """Test data formatter commands."""
+        self.buildDwarf()
+        self.data_formatter_commands()
+
+    def setUp(self):
+        # Call super's setUp().
+        TestBase.setUp(self)
+        # Find the line number to break at.
+        self.line = line_number('main.cpp', '// Set break point at this line.')
+
+    def data_formatter_commands(self):
+        """Test that that file and class static variables display correctly."""
+        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
+                    BREAKPOINT_CREATED,
+            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d, locations = 1" %
+                        self.line)
+
+        # This is the function to remove the custom formats in order to have a
+        # clean slate for the next test case.
+        def cleanup():
+            self.runCmd('type format clear', check=False)
+            self.runCmd('type summary clear', check=False)
+
+        # Execute the cleanup function during test case tear down.
+        self.addTearDownHook(cleanup)
+
+        self.runCmd("type summary add -f \"JustATest\" Point")
+
+        # Simply check we can get at global variables
+        self.expect("target variable g_point",
+            substrs = ['JustATest'])
+
+        self.expect("target variable g_point_pointer",
+            substrs = ['(Point *) g_point_pointer ='])
+
+        # Print some information about the variables
+        # (we ignore the actual values)
+        self.runCmd("type summary add -f \"(x=${var.x},y=${var.y})\" Point")
+
+        self.expect("target variable g_point",
+                    substrs = ['x=',
+                               'y='])
+        
+        self.expect("target variable g_point_pointer",
+                    substrs = ['(Point *) g_point_pointer ='])
+
+        # Test Python code on resulting SBValue
+        self.runCmd("type summary add -s \"return 'x=' + str(valobj.GetChildMemberWithName('x').GetValue());\" Point")
+
+        self.expect("target variable g_point",
+                    substrs = ['x='])
+        
+        self.expect("target variable g_point_pointer",
+                    substrs = ['(Point *) g_point_pointer ='])
+
+
+if __name__ == '__main__':
+    import atexit
+    lldb.SBDebugger.Initialize()
+    atexit.register(lambda: lldb.SBDebugger.Terminate())
+    unittest2.main()

Added: lldb/trunk/test/functionalities/data-formatter/data-formatter-globals/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-globals/main.cpp?rev=135463&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-globals/main.cpp (added)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-globals/main.cpp Mon Jul 18 21:34:21 2011
@@ -0,0 +1,27 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+struct Point {
+    int x;
+    int y;
+    Point(int X = 3, int Y = 2) : x(X), y(Y) {}
+};
+
+Point g_point(3,4);
+Point* g_point_pointer = new Point(7,5);
+
+int main (int argc, const char * argv[])
+{
+    return 0; // Set break point at this line.
+}
+

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-skip-summary/TestDataFormatterSkipSummary.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-skip-summary/TestDataFormatterSkipSummary.py?rev=135463&r1=135462&r2=135463&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-skip-summary/TestDataFormatterSkipSummary.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-skip-summary/TestDataFormatterSkipSummary.py Mon Jul 18 21:34:21 2011
@@ -130,7 +130,7 @@
                                '}'])
 
         # Expand same expression, skipping 3 layers of summaries
-        self.expect('frame variable data1.m_child1->m_child2 -Y3',
+        self.expect('frame variable data1.m_child1->m_child2 -T -Y3',
                     substrs = ['(DeepData_3) data1.m_child1->m_child2 = {',
                                'm_some_text = "Just a test"',
                                'm_child2 = {',

Modified: lldb/trunk/www/varformats.html
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/www/varformats.html?rev=135463&r1=135462&r2=135463&view=diff
==============================================================================
--- lldb/trunk/www/varformats.html (original)
+++ lldb/trunk/www/varformats.html Mon Jul 18 21:34:21 2011
@@ -401,8 +401,10 @@
                 <code> <b>(lldb)</b> fr var one<br>
                   (i_am_cool) one = int = 3, float = 3.14159, char = 69<br>
                 </code> </p>
-              <p>The way to obtain this effect is to bind a <i>summary string</i> to
-                the datatype using the <code>type summary add</code>
+                
+            <p>There are two ways to use type summaries: the first one is to bind a <i>
+            summary string</i> to the datatype; the second is to bind a Python script to the
+            datatype. Both options are enabled by the <code>type summary add</code>
                 command.</p>
               <p>In the example, the command we type was:</p>
                 <table class="stats" width="620" cellspacing="0">
@@ -410,6 +412,10 @@
                             <b>(lldb)</b> type summary add -f "int = ${var.integer}, float = ${var.floating}, char = ${var.character%u}" i_am_cool
                         </td>
                 <table>
+                
+            <p>Initially, we will focus on summary strings, and then describe the Python binding
+            mechanism.</p>
+            
             </div>
           </div>
           <div class="post">
@@ -717,11 +723,128 @@
           </div>
           
         <div class="post">
-            <h1 class="postheader">Regular expression typenames</h1>
+            <h1 class="postheader">Python scripting</h1>
             <div class="postcontent">
+            
+            <p>Most of the times, summary strings prove good enough for the job of summarizing
+            the contents of a variable. However, as soon as you need to do more than picking
+            some values and rearranging them for display, summary strings stop being an
+            effective tool. This is because summary strings lack the power to actually perform
+            some computation on the value of variables.</p>
+            <p>To solve this issue, you can bind some Python scripting code as a summary for
+            your datatype, and that script has the ability to both extract children variables
+            as the summary strings do and to perform active computation on the extracted
+            values. As a small example, let's say we have a Rectangle class:</p>
+            
+            <code>
+class Rectangle<br/>
+{<br/>
+private:<br/>
+        int height;<br/>
+        int width;<br/>
+public:<br/>
+        Rectangle() : height(3), width(5) {}<br/>
+        Rectangle(int H) : height(H), width(H*2-1) {}<br/>
+        Rectangle(int H, int W) : height(H), width(W) {}<br/>
+    
+        int GetHeight() { return height; }<br/>
+        int GetWidth() { return width; }<br/>
+    
+};<br/>
+</code>
+            
+            <p>Summary strings are effective to reduce the screen real estate used by
+            the default viewing mode, but are not effective if we want to display the
+            area, perimeter and length of diagonal of <code>Rectangle</code> objects</p>
+            
+            <p>To obtain this, we can simply attach a small Python script to the <code>Rectangle</code>
+            class, as shown in this example:</p>
+            
+            	<table class="stats" width="620" cellspacing="0">
+                        <td class="content">
+                            <b>(lldb)</b> type summary add -P Rectangle<br/>
+                            Enter your Python command(s). Type 'DONE' to end.<br/>
+def function (valobj,dict):<br/>
+         height_val = valobj.GetChildMemberWithName('height')<br/>
+         width_val = valobj.GetChildMemberWithName('width')<br/>
+         height_str = height_val.GetValue()<br/>
+         width_str = width_val.GetValue()<br/>
+         height = int(height_str)<br/>
+         width = int(width_str)<br/>
+         area = height*width<br/>
+         perimeter = 2*height + 2*width<br/>
+         diag = sqrt(height*height+width*width)<br/>
+         return 'Area: ' + str(area) + ', Perimeter: ' + str(perimeter) + ', Diagonal: ' + str(diag)<br/>
+         DONE<br/>
+<b>(lldb)</b> script<br/>
+Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.<br/>
+>>> from math import sqrt<br/>
+>>> quit()<br/>
+<b>(lldb)</b> frame variable<br/>
+(Rectangle) r1 = Area: 20, Perimeter: 18, Diagonal: 6.40312423743<br/>
+(Rectangle) r2 = Area: 72, Perimeter: 36, Diagonal: 13.416407865<br/>
+(Rectangle) r3 = Area: 16, Perimeter: 16, Diagonal: 5.65685424949<br/>
+                        </td>
+                </table>
+            
+            <p>In this scenario, you need to enter the interactive interpreter to import the
+            function sqrt() from the math library. As the example shows, everything you enter
+            into the interactive interpreter is saved for you to use it in scripts. This way
+            you can define your own utility functions and use them in your summary scripts if
+            necessary.</p>
+            
+            <p>In order to write effective summary scripts, you need to know the LLDB public
+            API, which is the way Python code can access the LLDB object model. For further
+            details on the API you should look at <a href="scripting.html">this page</a>, or at
+            the LLDB <a href="docs.html">doxygen documentation</a> when it becomes available.</p>
+            
+            <p>As a brief introduction, your script is encapsulated into a function that is
+            passed two parameters: <code>valobj</code> and <code>dict</code>.</p>
+            
+            <p><code>dict</code> is an internal support parameter used by LLDB and you should
+            not use it.<br/><code>valobj</code> is the object encapsulating the actual
+            variable being displayed, and its type is SBValue. The most important thing you can
+            do with an SBValue is retrieve its children objects, by calling
+            <code>GetChildMemberWithName()</code>, passing it the child's name as a string, or ask
+            it for its value, by calling <code>GetValue()</code>, which returns a Python string.
+            </p>
+            
+            <p>If you need to delve into several levels of hierarchy, as you can do with summary
+            strings, you must use the method <code>GetValueForExpressionPath()</code>, passing it
+            an expression path just like those you could use for summary strings. However, if you need
+            to access array slices, you cannot do that (yet) via this method call, and you must
+            use <code>GetChildMemberWithName()</code> querying it for the array items one by one.
+            
+            <p>Other than interactively typing a Python script there are two other ways for you
+            to input a Python script as a summary:
+            
+            <ul>
+            <li> using the -s option to <code>type summary add </code> and typing the script
+            code as an option argument; as in:            </ul>
+
+                <table class="stats" width="620" cellspacing="0">
+                        <td class="content">
+                            <b>(lldb)</b> type summary add -s "height = 
+                            int(valobj.GetChildMemberWithName('height').GetValue());width = 
+                            int(valobj.GetChildMemberWithName('width').GetValue());
+                            return 'Area: ' + str(height*width)" Rectangle<br/>
+                        </td>
+                </table>
+            <ul>
+            <li> using the -F option to <code>type summary add </code> and giving the name of a 
+            Python function with the correct prototype. Most probably, you will define (or have
+            already defined) the function in the interactive interpreter, or somehow
+            loaded it from a file.
+            </ul>
+            
+            </p>
+            
             </div>
         </div>
 
+        <div class="post">
+            <h1 class="postheader">Regular expression typenames</h1>
+            <div class="postcontent">
               <p>As you noticed, in order to associate the custom
                 summary string to the array types, one must give the
                 array size as part of the typename. This can long become
@@ -845,12 +968,10 @@
                 <li>There's no way to do multiple dereferencing, and you
                   need to be careful what the dereferencing operation is
                   binding to in complicated scenarios</li>
-                <li>There is no way to call functions inside summary
-                  strings, not even <code>const</code> ones</li>
                 <li><code>type format add</code> does not support the <code>-x</code>
                   option</li>
-                <li>Object location cannot be printed in the summary
-                  string</li>
+                <strike><li>Object location cannot be printed in the summary
+                  string</li></strike>
               </ul>
             </div>
           </div>





More information about the lldb-commits mailing list