<rdar://problem/10062621>
New public API for handling formatters: creating, deleting, modifying categories, and formatters, and managing type/formatter association.
This provides SB classes for each of the main object types involved in providing formatter support:
 SBTypeCategory
 SBTypeFilter
 SBTypeFormat
 SBTypeSummary
 SBTypeSynthetic
plus, an SBTypeNameSpecifier class that is used on the public API layer to abstract the notion that formatters can be applied to plain type-names as well as to regular expressions
For naming consistency, this patch also renames a lot of formatters-related classes.
Plus, the changes in how flags are handled that started with summaries is now extended to other classes as well. A new enum (lldb::eTypeOption) is meant to support this on the public side.
The patch also adds several new calls to the formatter infrastructure that are used to implement by-index accessing and several other design changes required to accommodate the new API layer.
An architectural change is introduced in that backing objects for formatters now become writable. On the public API layer, CoW is implemented to prevent unwanted propagation of changes.
Lastly, there are some modifications in how the "default" category is constructed and managed in relation to other categories.


git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@150558 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/scripts/Python/build-swig-Python.sh b/scripts/Python/build-swig-Python.sh
index 6ccea31..5fcbe7a 100755
--- a/scripts/Python/build-swig-Python.sh
+++ b/scripts/Python/build-swig-Python.sh
@@ -73,6 +73,12 @@
 " ${SRC_ROOT}/include/lldb/API/SBTarget.h"\
 " ${SRC_ROOT}/include/lldb/API/SBThread.h"\
 " ${SRC_ROOT}/include/lldb/API/SBType.h"\
+" ${SRC_ROOT}/include/lldb/API/SBTypeCategory.h"\
+" ${SRC_ROOT}/include/lldb/API/SBTypeFilter.h"\
+" ${SRC_ROOT}/include/lldb/API/SBTypeFormat.h"\
+" ${SRC_ROOT}/include/lldb/API/SBTypeNameSpecifier.h"\
+" ${SRC_ROOT}/include/lldb/API/SBTypeSummary.h"\
+" ${SRC_ROOT}/include/lldb/API/SBTypeSynthetic.h"\
 " ${SRC_ROOT}/include/lldb/API/SBValue.h"\
 " ${SRC_ROOT}/include/lldb/API/SBValueList.h"\
 " ${SRC_ROOT}/include/lldb/API/SBWatchpoint.h"\
@@ -109,6 +115,12 @@
 " ${SRC_ROOT}/scripts/Python/interface/SBTarget.i"\
 " ${SRC_ROOT}/scripts/Python/interface/SBThread.i"\
 " ${SRC_ROOT}/scripts/Python/interface/SBType.i"\
+" ${SRC_ROOT}/scripts/Python/interface/SBTypeCategory.i"\
+" ${SRC_ROOT}/scripts/Python/interface/SBTypeFilter.i"\
+" ${SRC_ROOT}/scripts/Python/interface/SBTypeFormat.i"\
+" ${SRC_ROOT}/scripts/Python/interface/SBTypeNameSpecifier.i"\
+" ${SRC_ROOT}/scripts/Python/interface/SBTypeSummary.i"\
+" ${SRC_ROOT}/scripts/Python/interface/SBTypeSynthetic.i"\
 " ${SRC_ROOT}/scripts/Python/interface/SBValue.i"\
 " ${SRC_ROOT}/scripts/Python/interface/SBValueList.i"\
 " ${SRC_ROOT}/scripts/Python/interface/SBWatchpoint.i"
diff --git a/scripts/Python/interface/SBDebugger.i b/scripts/Python/interface/SBDebugger.i
index 1882021..5048a83 100644
--- a/scripts/Python/interface/SBDebugger.i
+++ b/scripts/Python/interface/SBDebugger.i
@@ -321,6 +321,37 @@
     
     void
     SetCloseInputOnEOF (bool b);
+    
+    lldb::SBTypeCategory
+    GetCategory (const char* category_name);
+    
+    lldb::SBTypeCategory
+    CreateCategory (const char* category_name);
+    
+    bool
+    DeleteCategory (const char* category_name);
+    
+    uint32_t
+    GetNumCategories ();
+    
+    lldb::SBTypeCategory
+    GetCategoryAtIndex (uint32_t);
+    
+    lldb::SBTypeCategory
+    GetDefaultCategory();
+    
+    lldb::SBTypeFormat
+    GetFormatForType (lldb::SBTypeNameSpecifier);
+
+    lldb::SBTypeSummary
+    GetSummaryForType (lldb::SBTypeNameSpecifier);
+
+    lldb::SBTypeFilter
+    GetFilterForType (lldb::SBTypeNameSpecifier);
+
+    lldb::SBTypeSynthetic
+    GetSyntheticForType (lldb::SBTypeNameSpecifier);
+                
 }; // class SBDebugger
 
 } // namespace lldb
diff --git a/scripts/Python/interface/SBTypeCategory.i b/scripts/Python/interface/SBTypeCategory.i
new file mode 100644
index 0000000..fa1a63c
--- /dev/null
+++ b/scripts/Python/interface/SBTypeCategory.i
@@ -0,0 +1,140 @@
+//===-- SWIG Interface for SBTypeCategory---------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+namespace lldb {
+    
+    %feature("docstring",
+    "Represents a category that can contain formatters for types.
+    ") SBTypeCategory;
+    
+    class SBTypeCategory
+    {
+    public:
+        
+        SBTypeCategory();
+        
+        SBTypeCategory (const lldb::SBTypeCategory &rhs);
+        
+        ~SBTypeCategory ();
+        
+        bool
+        IsValid() const;
+        
+        bool
+        GetEnabled ();
+        
+        void
+        SetEnabled (bool);
+        
+        const char*
+        GetName();
+        
+        bool
+        GetDescription (lldb::SBStream &description, 
+                        lldb::DescriptionLevel description_level);
+        
+        uint32_t
+        GetNumFormats ();
+        
+        uint32_t
+        GetNumSummaries ();
+        
+        uint32_t
+        GetNumFilters ();
+        
+        uint32_t
+        GetNumSynthetics ();
+        
+        lldb::SBTypeNameSpecifier
+        GetTypeNameSpecifierForFilterAtIndex (uint32_t);
+        
+        lldb::SBTypeNameSpecifier
+        GetTypeNameSpecifierForFormatAtIndex (uint32_t);
+        
+        lldb::SBTypeNameSpecifier
+        GetTypeNameSpecifierForSummaryAtIndex (uint32_t);
+
+        lldb::SBTypeNameSpecifier
+        GetTypeNameSpecifierForSyntheticAtIndex (uint32_t);
+        
+        lldb::SBTypeFilter
+        GetFilterForType (lldb::SBTypeNameSpecifier);
+
+        lldb::SBTypeFormat
+        GetFormatForType (lldb::SBTypeNameSpecifier);
+        
+        lldb::SBTypeSummary
+        GetSummaryForType (lldb::SBTypeNameSpecifier);
+
+        lldb::SBTypeSynthetic
+        GetSyntheticForType (lldb::SBTypeNameSpecifier);
+        
+        lldb::SBTypeFilter
+        GetFilterAtIndex (uint32_t);
+        
+        lldb::SBTypeFormat
+        GetFormatAtIndex (uint32_t);
+        
+        lldb::SBTypeSummary
+        GetSummaryAtIndex (uint32_t);
+        
+        lldb::SBTypeSynthetic
+        GetSyntheticAtIndex (uint32_t);
+        
+        bool
+        AddTypeFormat (lldb::SBTypeNameSpecifier,
+                       lldb::SBTypeFormat);
+        
+        bool
+        DeleteTypeFormat (lldb::SBTypeNameSpecifier);
+        
+        bool
+        AddTypeSummary (lldb::SBTypeNameSpecifier,
+                        lldb::SBTypeSummary);
+        
+        bool
+        DeleteTypeSummary (lldb::SBTypeNameSpecifier);
+        
+        bool
+        AddTypeFilter (lldb::SBTypeNameSpecifier,
+                       lldb::SBTypeFilter);
+        
+        bool
+        DeleteTypeFilter (lldb::SBTypeNameSpecifier);
+        
+        bool
+        AddTypeSynthetic (lldb::SBTypeNameSpecifier,
+                          lldb::SBTypeSynthetic);
+        
+        bool
+        DeleteTypeSynthetic (lldb::SBTypeNameSpecifier);
+        
+        %pythoncode %{
+            __swig_getmethods__["num_formats"] = GetNumFormats
+            if _newclass: x = property(GetNumFormats, None)
+            __swig_getmethods__["num_summaries"] = GetNumSummaries
+            if _newclass: x = property(GetNumSummaries, None)
+            __swig_getmethods__["num_filters"] = GetNumFilters
+            if _newclass: x = property(GetNumFilters, None)
+            __swig_getmethods__["num_synthetics"] = GetNumSynthetics
+            if _newclass: x = property(GetNumSynthetics, None)
+            
+            __swig_getmethods__["name"] = GetName
+            if _newclass: x = property(GetName, None)
+            
+            __swig_getmethods__["enabled"] = GetEnabled
+            __swig_setmethods__["enabled"] = SetEnabled
+            if _newclass: x = property(GetEnabled, SetEnabled)
+        %}
+
+    };
+
+    
+} // namespace lldb
+
diff --git a/scripts/Python/interface/SBTypeFilter.i b/scripts/Python/interface/SBTypeFilter.i
new file mode 100644
index 0000000..046859a
--- /dev/null
+++ b/scripts/Python/interface/SBTypeFilter.i
@@ -0,0 +1,69 @@
+//===-- SWIG Interface for SBTypeFilter----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+namespace lldb {
+    
+    %feature("docstring",
+    "Represents a filter that can be associated to one or more types.
+    ") SBTypeFilter;
+    
+    class SBTypeFilter
+    {
+        public:
+        
+        SBTypeFilter();
+        
+        SBTypeFilter (uint32_t options);
+        
+        SBTypeFilter (const lldb::SBTypeFilter &rhs);
+        
+        ~SBTypeFilter ();
+        
+        bool
+        IsValid() const;
+        
+        bool
+        IsEqualTo (lldb::SBTypeFilter &rhs);
+        
+        uint32_t
+        GetNumberOfExpressionPaths ();
+        
+        const char*
+        GetExpressionPathAtIndex (uint32_t i);
+        
+        bool
+        ReplaceExpressionPathAtIndex (uint32_t i, const char* item);
+        
+        void
+        AppendExpressionPath (const char* item);
+        
+        void
+        Clear();
+        
+        uint32_t
+        GetOptions();
+        
+        void
+        SetOptions (uint32_t);
+        
+        bool
+        GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level);
+        
+        %pythoncode %{
+            __swig_getmethods__["options"] = GetOptions
+            __swig_setmethods__["options"] = SetOptions
+            if _newclass: x = property(GetOptions, SetOptions)        
+            
+            __swig_getmethods__["count"] = GetNumberOfExpressionPaths
+            if _newclass: x = property(GetNumberOfExpressionPaths, None)
+        %}
+                
+    };
+
+} // namespace lldb
diff --git a/scripts/Python/interface/SBTypeFormat.i b/scripts/Python/interface/SBTypeFormat.i
new file mode 100644
index 0000000..2116a02
--- /dev/null
+++ b/scripts/Python/interface/SBTypeFormat.i
@@ -0,0 +1,64 @@
+//===-- SWIG Interface for SBTypeFormat----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+namespace lldb {
+    
+    %feature("docstring",
+             "Represents a format that can be associated to one or more types.
+             ") SBTypeFormat;
+    
+    class SBTypeFormat
+    {
+    public:
+        
+        SBTypeFormat();
+        
+        SBTypeFormat (lldb::Format format, uint32_t options = 0);
+        
+        SBTypeFormat (const lldb::SBTypeFormat &rhs);
+        
+        ~SBTypeFormat ();
+        
+        bool
+        IsValid() const;
+        
+        bool
+        IsEqualTo (lldb::SBTypeFormat &rhs);
+        
+        lldb::Format
+        GetFormat ();
+        
+        uint32_t
+        GetOptions();
+        
+        void
+        SetFormat (lldb::Format);
+        
+        void
+        SetOptions (uint32_t);        
+        
+        bool
+        GetDescription (lldb::SBStream &description, 
+                        lldb::DescriptionLevel description_level);
+                
+        %pythoncode %{
+            __swig_getmethods__["format"] = GetFormat
+            __swig_setmethods__["format"] = SetFormat
+            if _newclass: x = property(GetFormat, SetFormat)
+            
+            __swig_getmethods__["options"] = GetOptions
+            __swig_setmethods__["options"] = SetOptions
+            if _newclass: x = property(GetOptions, SetOptions)            
+        %}
+
+    };
+    
+    
+} // namespace lldb
+
diff --git a/scripts/Python/interface/SBTypeNameSpecifier.i b/scripts/Python/interface/SBTypeNameSpecifier.i
new file mode 100644
index 0000000..f50761c
--- /dev/null
+++ b/scripts/Python/interface/SBTypeNameSpecifier.i
@@ -0,0 +1,57 @@
+//===-- SWIG Interface for SBTypeNameSpecifier---------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+namespace lldb {
+    
+    %feature("docstring",
+    "Represents a general way to provide a type name to LLDB APIs.
+    ") SBTypeNameSpecifier;
+    
+    class SBTypeNameSpecifier
+    {
+    public:
+        
+        SBTypeNameSpecifier();
+        
+        SBTypeNameSpecifier (const char* name,
+                             bool is_regex = false);
+        
+        SBTypeNameSpecifier (const lldb::SBTypeNameSpecifier &rhs);
+        
+        ~SBTypeNameSpecifier ();
+        
+        bool
+        IsValid() const;
+        
+        bool
+        IsEqualTo (lldb::SBTypeNameSpecifier &rhs);
+        
+        const char*
+        GetName();
+        
+        bool
+        IsRegex();
+        
+        bool
+        GetDescription (lldb::SBStream &description, 
+                        lldb::DescriptionLevel description_level);
+                        
+        %pythoncode %{
+            __swig_getmethods__["name"] = GetName
+            if _newclass: x = property(GetName, None)
+            
+            __swig_getmethods__["is_regex"] = IsRegex
+            if _newclass: x = property(IsRegex, None)
+        %}
+
+        
+    };
+    
+} // namespace lldb
+
diff --git a/scripts/Python/interface/SBTypeSummary.i b/scripts/Python/interface/SBTypeSummary.i
new file mode 100644
index 0000000..f968977
--- /dev/null
+++ b/scripts/Python/interface/SBTypeSummary.i
@@ -0,0 +1,93 @@
+//===-- SWIG Interface for SBTypeSummary---------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+namespace lldb {
+    
+    %feature("docstring",
+    "Represents a summary that can be associated to one or more types.
+    ") SBTypeSummary;
+    
+    class SBTypeSummary
+    {
+    public:
+        
+        SBTypeSummary();
+        
+        static SBTypeSummary
+        CreateWithSummaryString (const char* data, uint32_t options = 0);
+        
+        static SBTypeSummary
+        CreateWithFunctionName (const char* data, uint32_t options = 0);
+        
+        static SBTypeSummary
+        CreateWithScriptCode (const char* data, uint32_t options = 0);
+        
+        SBTypeSummary (const lldb::SBTypeSummary &rhs);
+        
+        ~SBTypeSummary ();
+        
+        bool
+        IsValid() const;
+        
+        bool
+        IsEqualTo (lldb::SBTypeSummary &rhs);
+        
+        bool
+        IsFunctionCode();
+        
+        bool
+        IsFunctionName();
+        
+        bool
+        IsSummaryString();
+        
+        const char*
+        GetData ();
+        
+        void
+        SetSummaryString (const char* data);
+        
+        void
+        SetFunctionName (const char* data);
+        
+        void
+        SetFunctionCode (const char* data);
+        
+        uint32_t
+        GetOptions ();
+
+        void
+        SetOptions (uint32_t);
+        
+        bool
+        GetDescription (lldb::SBStream &description, 
+                        lldb::DescriptionLevel description_level);
+        
+        %pythoncode %{
+            __swig_getmethods__["options"] = GetOptions
+            __swig_setmethods__["options"] = SetOptions
+            if _newclass: x = property(GetOptions, SetOptions)        
+            
+            __swig_getmethods__["is_summary_string"] = IsSummaryString
+            if _newclass: x = property(IsSummaryString, None)        
+
+            __swig_getmethods__["is_function_name"] = IsFunctionName
+            if _newclass: x = property(IsFunctionName, None)        
+
+            __swig_getmethods__["is_function_code"] = IsFunctionCode
+            if _newclass: x = property(IsFunctionCode, None)        
+
+            __swig_getmethods__["summary_data"] = GetData
+            if _newclass: x = property(GetData, None)
+        %}
+        
+    };
+
+} // namespace lldb
+
diff --git a/scripts/Python/interface/SBTypeSynthetic.i b/scripts/Python/interface/SBTypeSynthetic.i
new file mode 100644
index 0000000..3e785ff
--- /dev/null
+++ b/scripts/Python/interface/SBTypeSynthetic.i
@@ -0,0 +1,74 @@
+//===-- SWIG Interface for SBTypeSynthetic-------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+namespace lldb {
+    
+    %feature("docstring",
+    "Represents a summary that can be associated to one or more types.
+    ") SBTypeSynthetic;
+    
+    class SBTypeSynthetic
+    {
+    public:
+        
+        SBTypeSynthetic();
+        
+        static lldb::SBTypeSynthetic
+        CreateWithClassName (const char* data, uint32_t options = 0);
+        
+        static lldb::SBTypeSynthetic
+        CreateWithScriptCode (const char* data, uint32_t options = 0);
+        
+        SBTypeSynthetic (const lldb::SBTypeSynthetic &rhs);
+        
+        ~SBTypeSynthetic ();
+        
+        bool
+        IsValid() const;
+        
+        bool
+        IsEqualTo (lldb::SBTypeSynthetic &rhs);
+        
+        bool
+        IsClassCode();
+        
+        const char*
+        GetData ();
+        
+        void
+        SetClassName (const char* data);
+        
+        void
+        SetClassCode (const char* data);
+
+        uint32_t
+        GetOptions ();
+        
+        void
+        SetOptions (uint32_t);
+        
+        bool
+        GetDescription (lldb::SBStream &description, 
+                        lldb::DescriptionLevel description_level);
+        
+        %pythoncode %{
+            __swig_getmethods__["options"] = GetOptions
+            __swig_setmethods__["options"] = SetOptions
+            if _newclass: x = property(GetOptions, SetOptions)        
+            
+            __swig_getmethods__["contains_code"] = IsClassCode
+            if _newclass: x = property(IsClassCode, None)        
+            
+            __swig_getmethods__["synthetic_data"] = GetData
+            if _newclass: x = property(GetData, None)
+        %}
+        
+    };
+    
+} // namespace lldb
diff --git a/scripts/Python/python-extensions.swig b/scripts/Python/python-extensions.swig
index 29e39e5..cd8f1cf 100644
--- a/scripts/Python/python-extensions.swig
+++ b/scripts/Python/python-extensions.swig
@@ -322,6 +322,48 @@
                     return PyString_FromString("");
         }
 }
+%extend lldb::SBTypeCategory {
+        PyObject *lldb::SBTypeCategory::__str__ (){
+                lldb::SBStream description;
+                $self->GetDescription (description, lldb::eDescriptionLevelBrief);
+                const char *desc = description.GetData();
+                size_t desc_len = description.GetSize();
+                if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
+                    --desc_len;
+                if (desc_len > 0)
+                    return PyString_FromStringAndSize (desc, desc_len);
+                else
+                    return PyString_FromString("");
+        }
+}
+%extend lldb::SBTypeFilter {
+        PyObject *lldb::SBTypeFilter::__str__ (){
+                lldb::SBStream description;
+                $self->GetDescription (description, lldb::eDescriptionLevelBrief);
+                const char *desc = description.GetData();
+                size_t desc_len = description.GetSize();
+                if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
+                    --desc_len;
+                if (desc_len > 0)
+                    return PyString_FromStringAndSize (desc, desc_len);
+                else
+                    return PyString_FromString("");
+        }
+}
+%extend lldb::SBTypeFormat {
+        PyObject *lldb::SBTypeFormat::__str__ (){
+                lldb::SBStream description;
+                $self->GetDescription (description, lldb::eDescriptionLevelBrief);
+                const char *desc = description.GetData();
+                size_t desc_len = description.GetSize();
+                if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
+                    --desc_len;
+                if (desc_len > 0)
+                    return PyString_FromStringAndSize (desc, desc_len);
+                else
+                    return PyString_FromString("");
+        }
+}
 %extend lldb::SBTypeMember {
         PyObject *lldb::SBTypeMember::__str__ (){
                 lldb::SBStream description;
@@ -336,6 +378,48 @@
                     return PyString_FromString("");
         }
 }
+%extend lldb::SBTypeNameSpecifier {
+        PyObject *lldb::SBTypeNameSpecifier::__str__ (){
+                lldb::SBStream description;
+                $self->GetDescription (description, lldb::eDescriptionLevelBrief);
+                const char *desc = description.GetData();
+                size_t desc_len = description.GetSize();
+                if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
+                    --desc_len;
+                if (desc_len > 0)
+                    return PyString_FromStringAndSize (desc, desc_len);
+                else
+                    return PyString_FromString("");
+        }
+}
+%extend lldb::SBTypeSummary {
+        PyObject *lldb::SBTypeSummary::__str__ (){
+                lldb::SBStream description;
+                $self->GetDescription (description, lldb::eDescriptionLevelBrief);
+                const char *desc = description.GetData();
+                size_t desc_len = description.GetSize();
+                if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
+                    --desc_len;
+                if (desc_len > 0)
+                    return PyString_FromStringAndSize (desc, desc_len);
+                else
+                    return PyString_FromString("");
+        }
+}
+%extend lldb::SBTypeSynthetic {
+        PyObject *lldb::SBTypeSynthetic::__str__ (){
+                lldb::SBStream description;
+                $self->GetDescription (description, lldb::eDescriptionLevelBrief);
+                const char *desc = description.GetData();
+                size_t desc_len = description.GetSize();
+                if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
+                    --desc_len;
+                if (desc_len > 0)
+                    return PyString_FromStringAndSize (desc, desc_len);
+                else
+                    return PyString_FromString("");
+        }
+}
 %extend lldb::SBThread {
         PyObject *lldb::SBThread::__str__ (){
                 lldb::SBStream description;