when typing a summary string you can use the %S symbol to explicitly indicate that you want the summary to be used to print the target object
 (e.g. ${var%S}). this might already be the default if your variable is of an aggregate type
new feature: synthetic filters. you can restrict the number of children for your variables to only a meaningful subset
 - the restricted list of children obeys the typical rules (e.g. summaries prevail over children)
 - one-line summaries show only the filtered (synthetic) children, if you type an expanded summary string, or you use Python scripts, all the real children are accessible
 - to provide a synthetic children list use the "type synth add" command, as in:
   type synth add foo_type --child varA --child varB[0] --child varC->packet->flags[1-4]
   (you can use ., ->, single-item array operator [N] and bitfield operator [N-M]; array slice access is not supported, giving simplified names to expression paths is not supported)
 - a new -S option to frame variable and target variable lets you override synthetic children and instead show real ones

git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@135731 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Commands/CommandObjectExpression.cpp b/source/Commands/CommandObjectExpression.cpp
index cab8ed5..6109b64 100644
--- a/source/Commands/CommandObjectExpression.cpp
+++ b/source/Commands/CommandObjectExpression.cpp
@@ -334,6 +334,7 @@
                                               false,                    // Show locations of variables, no since this is a host address which we don't care to see
                                               m_options.print_object,   // Print the objective C object?
                                               use_dynamic,
+                                              true,                     // Use synthetic children if available
                                               true,                     // Scope is already checked. Const results are always in scope.
                                               false,                    // Don't flatten output
                                               0);                       // Always use summaries (you might want an option --no-summary like there is for frame variable)
diff --git a/source/Commands/CommandObjectFrame.cpp b/source/Commands/CommandObjectFrame.cpp
index 12670a1..eedc0cc 100644
--- a/source/Commands/CommandObjectFrame.cpp
+++ b/source/Commands/CommandObjectFrame.cpp
@@ -499,7 +499,8 @@
                                                                               m_varobj_options.show_types,
                                                                               m_varobj_options.show_location,
                                                                               m_varobj_options.use_objc,
-                                                                              m_varobj_options.use_dynamic, 
+                                                                              m_varobj_options.use_dynamic,
+                                                                              m_varobj_options.use_synth,
                                                                               false,
                                                                               m_varobj_options.flat_output,
                                                                               m_varobj_options.no_summary_depth);                                        
@@ -552,6 +553,7 @@
                                                               m_varobj_options.show_location,
                                                               m_varobj_options.use_objc,
                                                               m_varobj_options.use_dynamic,
+                                                              m_varobj_options.use_synth,
                                                               false,
                                                               m_varobj_options.flat_output,
                                                               m_varobj_options.no_summary_depth);
@@ -643,6 +645,7 @@
                                                                       m_varobj_options.show_location,
                                                                       m_varobj_options.use_objc,
                                                                       m_varobj_options.use_dynamic, 
+                                                                      m_varobj_options.use_synth,
                                                                       false,
                                                                       m_varobj_options.flat_output,
                                                                       m_varobj_options.no_summary_depth);                                        
diff --git a/source/Commands/CommandObjectMemory.cpp b/source/Commands/CommandObjectMemory.cpp
index e91490c..2a2c936 100644
--- a/source/Commands/CommandObjectMemory.cpp
+++ b/source/Commands/CommandObjectMemory.cpp
@@ -657,6 +657,7 @@
                                                   m_varobj_options.show_location,
                                                   m_varobj_options.use_objc,
                                                   m_varobj_options.use_dynamic,
+                                                  m_varobj_options.use_synth,
                                                   scope_already_checked,
                                                   m_varobj_options.flat_output,
                                                   0);
diff --git a/source/Commands/CommandObjectTarget.cpp b/source/Commands/CommandObjectTarget.cpp
index 1af50f0..814a2ad 100644
--- a/source/Commands/CommandObjectTarget.cpp
+++ b/source/Commands/CommandObjectTarget.cpp
@@ -488,6 +488,7 @@
                                       m_varobj_options.show_location,
                                       m_varobj_options.use_objc,
                                       m_varobj_options.use_dynamic,
+                                      m_varobj_options.use_synth,
                                       false,
                                       m_varobj_options.flat_output,
                                       m_varobj_options.no_summary_depth);                                        
diff --git a/source/Commands/CommandObjectType.cpp b/source/Commands/CommandObjectType.cpp
index c7b74d7..3a8b16c 100644
--- a/source/Commands/CommandObjectType.cpp
+++ b/source/Commands/CommandObjectType.cpp
@@ -1226,7 +1226,7 @@
         lldb::FormatCategorySP category;
         Debugger::Formatting::Categories::Get(ConstString(m_options.m_category), category);
         
-        bool delete_category = category->Delete(typeCS.GetCString());
+        bool delete_category = category->DeleteSummaries(typeCS.GetCString());
         bool delete_named = Debugger::Formatting::NamedSummaryFormats::Delete(typeCS);
         
         if (delete_category || delete_named)
@@ -1359,7 +1359,7 @@
             }
             else
                 Debugger::Formatting::Categories::Get(ConstString(NULL), category);
-            category->Clear();
+            category->ClearSummaries();
         }
         
         Debugger::Formatting::NamedSummaryFormats::Clear();
@@ -1885,6 +1885,670 @@
     
 };
 
+//-------------------------------------------------------------------------
+// CommandObjectTypeSynthList
+//-------------------------------------------------------------------------
+
+bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, const char* type, const SyntheticFilter::SharedPointer& entry);
+
+class CommandObjectTypeSynthList;
+
+struct CommandObjectTypeSynthList_LoopCallbackParam {
+    CommandObjectTypeSynthList* self;
+    CommandReturnObject* result;
+    RegularExpression* regex;
+    RegularExpression* cate_regex;
+    CommandObjectTypeSynthList_LoopCallbackParam(CommandObjectTypeSynthList* S, CommandReturnObject* R,
+                                                 RegularExpression* X = NULL,
+                                                 RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {}
+};
+
+class CommandObjectTypeSynthList : public CommandObject
+{
+    
+    class CommandOptions : public Options
+    {
+    public:
+        
+        CommandOptions (CommandInterpreter &interpreter) :
+        Options (interpreter)
+        {
+        }
+        
+        virtual
+        ~CommandOptions (){}
+        
+        virtual Error
+        SetOptionValue (uint32_t option_idx, const char *option_arg)
+        {
+            Error error;
+            char short_option = (char) m_getopt_table[option_idx].val;
+            
+            switch (short_option)
+            {
+                case 'w':
+                    m_category_regex = std::string(option_arg);
+                    break;
+                default:
+                    error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
+                    break;
+            }
+            
+            return error;
+        }
+        
+        void
+        OptionParsingStarting ()
+        {
+            m_category_regex = "";
+        }
+        
+        const OptionDefinition*
+        GetDefinitions ()
+        {
+            return g_option_table;
+        }
+        
+        // Options table: Required for subclasses of Options.
+        
+        static OptionDefinition g_option_table[];
+        
+        // Instance variables to hold the values for command options.
+        
+        std::string m_category_regex;
+        
+    };
+    
+    CommandOptions m_options;
+    
+    virtual Options *
+    GetOptions ()
+    {
+        return &m_options;
+    }
+    
+public:
+    CommandObjectTypeSynthList (CommandInterpreter &interpreter) :
+    CommandObject (interpreter,
+                   "type synth list",
+                   "Show a list of current synthetic providers.",
+                   NULL), m_options(interpreter)
+    {
+        CommandArgumentEntry type_arg;
+        CommandArgumentData type_style_arg;
+        
+        type_style_arg.arg_type = eArgTypeName;
+        type_style_arg.arg_repetition = eArgRepeatOptional;
+        
+        type_arg.push_back (type_style_arg);
+        
+        m_arguments.push_back (type_arg);
+    }
+    
+    ~CommandObjectTypeSynthList ()
+    {
+    }
+    
+    bool
+    Execute (Args& command, CommandReturnObject &result)
+    {
+        const size_t argc = command.GetArgumentCount();
+        
+        CommandObjectTypeSynthList_LoopCallbackParam *param;
+        RegularExpression* cate_regex = 
+        m_options.m_category_regex.empty() ? NULL :
+        new RegularExpression(m_options.m_category_regex.c_str());
+        
+        if (argc == 1) {
+            RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
+            regex->Compile(command.GetArgumentAtIndex(0));
+            param = new CommandObjectTypeSynthList_LoopCallbackParam(this,&result,regex,cate_regex);
+        }
+        else
+            param = new CommandObjectTypeSynthList_LoopCallbackParam(this,&result,NULL,cate_regex);
+        
+        Debugger::Formatting::Categories::LoopThrough(PerCategoryCallback,param);
+                
+        if (cate_regex)
+            delete cate_regex;
+        
+        result.SetStatus(eReturnStatusSuccessFinishResult);
+        return result.Succeeded();
+    }
+    
+private:
+    
+    static bool
+    PerCategoryCallback(void* param_vp,
+                        const char* cate_name,
+                        const FormatCategory::SharedPointer& cate)
+    {
+        
+        CommandObjectTypeSynthList_LoopCallbackParam* param = 
+        (CommandObjectTypeSynthList_LoopCallbackParam*)param_vp;
+        CommandReturnObject* result = param->result;
+        
+        // if the category is disabled or empty and there is no regex, just skip it
+        if ((cate->IsEnabled() == false || cate->Filter()->GetCount() == 0) && param->cate_regex == NULL)
+            return true;
+        
+        // if we have a regex and this category does not match it, just skip it
+        if(param->cate_regex != NULL && param->cate_regex->Execute(cate_name) == false)
+            return true;
+        
+        result->GetOutputStream().Printf("-----------------------\nCategory: %s (%s)\n-----------------------\n",
+                                         cate_name,
+                                         (cate->IsEnabled() ? "enabled" : "disabled"));
+        
+        cate->Filter()->LoopThrough(CommandObjectTypeSynthList_LoopCallback, param_vp);
+        
+        return true;
+    }
+    
+    bool
+    LoopCallback (const char* type,
+                  const SyntheticFilter::SharedPointer& entry,
+                  RegularExpression* regex,
+                  CommandReturnObject *result)
+    {
+        if (regex == NULL || regex->Execute(type)) 
+            result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str());
+        return true;
+    }
+    
+    friend bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, const char* type, const SyntheticFilter::SharedPointer& entry);
+};
+
+bool
+CommandObjectTypeSynthList_LoopCallback (void* pt2self,
+                                         const char* type,
+                                         const SyntheticFilter::SharedPointer& entry)
+{
+    CommandObjectTypeSynthList_LoopCallbackParam* param = (CommandObjectTypeSynthList_LoopCallbackParam*)pt2self;
+    return param->self->LoopCallback(type, entry, param->regex, param->result);
+}
+
+
+OptionDefinition
+CommandObjectTypeSynthList::CommandOptions::g_option_table[] =
+{
+    { LLDB_OPT_SET_ALL, false, "category-regex", 'w', required_argument, NULL, 0, eArgTypeName,  "Only show categories matching this filter."},
+    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
+};
+
+//-------------------------------------------------------------------------
+// CommandObjectTypeSynthDelete
+//-------------------------------------------------------------------------
+
+class CommandObjectTypeSynthDelete : public CommandObject
+{
+private:
+    class CommandOptions : public Options
+    {
+    public:
+        
+        CommandOptions (CommandInterpreter &interpreter) :
+        Options (interpreter)
+        {
+        }
+        
+        virtual
+        ~CommandOptions (){}
+        
+        virtual Error
+        SetOptionValue (uint32_t option_idx, const char *option_arg)
+        {
+            Error error;
+            char short_option = (char) m_getopt_table[option_idx].val;
+            
+            switch (short_option)
+            {
+                case 'a':
+                    m_delete_all = true;
+                    break;
+                case 'w':
+                    m_category = ConstString(option_arg).GetCString();
+                    break;
+                default:
+                    error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
+                    break;
+            }
+            
+            return error;
+        }
+        
+        void
+        OptionParsingStarting ()
+        {
+            m_delete_all = false;
+            m_category = NULL;
+        }
+        
+        const OptionDefinition*
+        GetDefinitions ()
+        {
+            return g_option_table;
+        }
+        
+        // Options table: Required for subclasses of Options.
+        
+        static OptionDefinition g_option_table[];
+        
+        // Instance variables to hold the values for command options.
+        
+        bool m_delete_all;
+        const char* m_category;
+        
+    };
+    
+    CommandOptions m_options;
+    
+    virtual Options *
+    GetOptions ()
+    {
+        return &m_options;
+    }
+    
+    static bool
+    PerCategoryCallback(void* param,
+                        const char* cate_name,
+                        const FormatCategory::SharedPointer& cate)
+    {
+        const char* name = (const char*)param;
+        cate->Filter()->Delete(name);
+        return true;
+    }
+    
+public:
+    CommandObjectTypeSynthDelete (CommandInterpreter &interpreter) :
+    CommandObject (interpreter,
+                   "type synth delete",
+                   "Delete an existing synthetic provider for a type.",
+                   NULL), m_options(interpreter)
+    {
+        CommandArgumentEntry type_arg;
+        CommandArgumentData type_style_arg;
+        
+        type_style_arg.arg_type = eArgTypeName;
+        type_style_arg.arg_repetition = eArgRepeatPlain;
+        
+        type_arg.push_back (type_style_arg);
+        
+        m_arguments.push_back (type_arg);
+        
+    }
+    
+    ~CommandObjectTypeSynthDelete ()
+    {
+    }
+    
+    bool
+    Execute (Args& command, CommandReturnObject &result)
+    {
+        const size_t argc = command.GetArgumentCount();
+        
+        if (argc != 1)
+        {
+            result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str());
+            result.SetStatus(eReturnStatusFailed);
+            return false;
+        }
+        
+        const char* typeA = command.GetArgumentAtIndex(0);
+        ConstString typeCS(typeA);
+        
+        if (!typeCS)
+        {
+            result.AppendError("empty typenames not allowed");
+            result.SetStatus(eReturnStatusFailed);
+            return false;
+        }
+        
+        if (m_options.m_delete_all)
+        {
+            Debugger::Formatting::Categories::LoopThrough(PerCategoryCallback, (void*)typeCS.GetCString());
+            result.SetStatus(eReturnStatusSuccessFinishNoResult);
+            return result.Succeeded();
+        }
+        
+        lldb::FormatCategorySP category;
+        Debugger::Formatting::Categories::Get(ConstString(m_options.m_category), category);
+        
+        bool delete_category = category->Filter()->Delete(typeCS.GetCString());
+        
+        if (delete_category)
+        {
+            result.SetStatus(eReturnStatusSuccessFinishNoResult);
+            return result.Succeeded();
+        }
+        else
+        {
+            result.AppendErrorWithFormat ("no custom synthetic provider for %s.\n", typeA);
+            result.SetStatus(eReturnStatusFailed);
+            return false;
+        }
+        
+    }
+};
+
+OptionDefinition
+CommandObjectTypeSynthDelete::CommandOptions::g_option_table[] =
+{
+    { LLDB_OPT_SET_1, false, "all", 'a', no_argument, NULL, 0, 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 }
+};
+
+//-------------------------------------------------------------------------
+// CommandObjectTypeSynthClear
+//-------------------------------------------------------------------------
+
+class CommandObjectTypeSynthClear : public CommandObject
+{
+private:
+    
+    class CommandOptions : public Options
+    {
+    public:
+        
+        CommandOptions (CommandInterpreter &interpreter) :
+        Options (interpreter)
+        {
+        }
+        
+        virtual
+        ~CommandOptions (){}
+        
+        virtual Error
+        SetOptionValue (uint32_t option_idx, const char *option_arg)
+        {
+            Error error;
+            char short_option = (char) m_getopt_table[option_idx].val;
+            
+            switch (short_option)
+            {
+                case 'a':
+                    m_delete_all = true;
+                    break;
+                default:
+                    error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
+                    break;
+            }
+            
+            return error;
+        }
+        
+        void
+        OptionParsingStarting ()
+        {
+            m_delete_all = false;
+        }
+        
+        const OptionDefinition*
+        GetDefinitions ()
+        {
+            return g_option_table;
+        }
+        
+        // Options table: Required for subclasses of Options.
+        
+        static OptionDefinition g_option_table[];
+        
+        // Instance variables to hold the values for command options.
+        
+        bool m_delete_all;
+        bool m_delete_named;
+    };
+    
+    CommandOptions m_options;
+    
+    virtual Options *
+    GetOptions ()
+    {
+        return &m_options;
+    }
+    
+    static bool
+    PerCategoryCallback(void* param,
+                        const char* cate_name,
+                        const FormatCategory::SharedPointer& cate)
+    {
+        cate->Filter()->Clear();
+        return true;
+        
+    }
+    
+public:
+    CommandObjectTypeSynthClear (CommandInterpreter &interpreter) :
+    CommandObject (interpreter,
+                   "type synth clear",
+                   "Delete all existing synthetic providers.",
+                   NULL), m_options(interpreter)
+    {
+    }
+    
+    ~CommandObjectTypeSynthClear ()
+    {
+    }
+    
+    bool
+    Execute (Args& command, CommandReturnObject &result)
+    {
+        
+        if (m_options.m_delete_all)
+            Debugger::Formatting::Categories::LoopThrough(PerCategoryCallback, NULL);
+        
+        else
+        {        
+            lldb::FormatCategorySP category;
+            if (command.GetArgumentCount() > 0)
+            {
+                const char* cat_name = command.GetArgumentAtIndex(0);
+                ConstString cat_nameCS(cat_name);
+                Debugger::Formatting::Categories::Get(cat_nameCS, category);
+            }
+            else
+                Debugger::Formatting::Categories::Get(ConstString(NULL), category);
+            category->Filter()->Clear();
+        }
+        
+        result.SetStatus(eReturnStatusSuccessFinishResult);
+        return result.Succeeded();
+    }
+    
+};
+
+OptionDefinition
+CommandObjectTypeSynthClear::CommandOptions::g_option_table[] =
+{
+    { LLDB_OPT_SET_ALL, false, "all", 'a', no_argument, NULL, 0, eArgTypeBoolean,  "Clear every category."},
+    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
+};
+
+//-------------------------------------------------------------------------
+// CommandObjectTypeSynthAdd
+//-------------------------------------------------------------------------
+
+class CommandObjectTypeSynthAdd : public CommandObject
+{
+    
+private:
+    
+    class CommandOptions : public Options
+    {
+        typedef std::vector<std::string> option_vector;
+    public:
+        
+        CommandOptions (CommandInterpreter &interpreter) :
+        Options (interpreter)
+        {
+        }
+        
+        virtual
+        ~CommandOptions (){}
+        
+        virtual Error
+        SetOptionValue (uint32_t option_idx, const char *option_arg)
+        {
+            Error error;
+            char short_option = (char) m_getopt_table[option_idx].val;
+            bool success;
+            
+            switch (short_option)
+            {
+                case 'C':
+                    m_cascade = Args::StringToBoolean(option_arg, true, &success);
+                    if (!success)
+                        error.SetErrorStringWithFormat("Invalid value for cascade: %s.\n", option_arg);
+                    break;
+                case 'c':
+                    m_expr_paths.push_back(option_arg);
+                    break;
+                case 'p':
+                    m_skip_pointers = true;
+                    break;
+                case 'r':
+                    m_skip_references = true;
+                    break;
+                case 'w':
+                    m_category = ConstString(option_arg).GetCString();
+                    break;
+                default:
+                    error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
+                    break;
+            }
+            
+            return error;
+        }
+        
+        void
+        OptionParsingStarting ()
+        {
+            m_cascade = true;
+            m_expr_paths.clear();
+            m_skip_pointers = false;
+            m_skip_references = false;
+            m_category = NULL;
+        }
+        
+        const OptionDefinition*
+        GetDefinitions ()
+        {
+            return g_option_table;
+        }
+        
+        // Options table: Required for subclasses of Options.
+        
+        static OptionDefinition g_option_table[];
+        
+        // Instance variables to hold the values for command options.
+        
+        bool m_cascade;
+        bool m_skip_references;
+        bool m_skip_pointers;
+        option_vector m_expr_paths;
+        const char* m_category;
+        
+        typedef option_vector::iterator ExpressionPathsIterator;
+    };
+    
+    CommandOptions m_options;
+    
+    virtual Options *
+    GetOptions ()
+    {
+        return &m_options;
+    }
+    
+public:
+    CommandObjectTypeSynthAdd (CommandInterpreter &interpreter) :
+    CommandObject (interpreter,
+                   "type synth add",
+                   "Add a new synthetic provider for a type.",
+                   NULL), m_options (interpreter)
+    {
+        CommandArgumentEntry type_arg;
+        CommandArgumentData type_style_arg;
+        
+        type_style_arg.arg_type = eArgTypeName;
+        type_style_arg.arg_repetition = eArgRepeatPlus;
+        
+        type_arg.push_back (type_style_arg);
+        
+        m_arguments.push_back (type_arg);
+        
+    }
+    
+    ~CommandObjectTypeSynthAdd ()
+    {
+    }
+    
+    bool
+    Execute (Args& command, CommandReturnObject &result)
+    {
+        const size_t argc = command.GetArgumentCount();
+        
+        if (argc < 1)
+        {
+            result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
+            result.SetStatus(eReturnStatusFailed);
+            return false;
+        }
+        
+        if (m_options.m_expr_paths.size() == 0)
+        {
+            result.AppendErrorWithFormat ("%s needs one or more children.\n", m_cmd_name.c_str());
+            result.SetStatus(eReturnStatusFailed);
+            return false;
+        }
+        
+        SyntheticFilterSP entry;
+        
+        entry.reset(new SyntheticFilter(m_options.m_cascade,
+                                        m_options.m_skip_pointers,
+                                        m_options.m_skip_references));
+        
+        // go through the expression paths
+        CommandOptions::ExpressionPathsIterator begin, end = m_options.m_expr_paths.end();
+        
+        for (begin = m_options.m_expr_paths.begin(); begin != end; begin++)
+            entry->AddExpressionPath(*begin);
+        
+        
+        // now I have a valid provider, let's add it to every type
+        
+        lldb::FormatCategorySP category;
+        Debugger::Formatting::Categories::Get(ConstString(m_options.m_category), category);
+        
+        for (size_t i = 0; i < argc; i++) {
+            const char* typeA = command.GetArgumentAtIndex(i);
+            ConstString typeCS(typeA);
+            if (typeCS)
+                category->Filter()->Add(typeCS.GetCString(), entry);
+            else
+            {
+                result.AppendError("empty typenames not allowed");
+                result.SetStatus(eReturnStatusFailed);
+                return false;
+            }
+        }
+        
+        result.SetStatus(eReturnStatusSuccessFinishNoResult);
+        return result.Succeeded();
+    }
+};
+
+OptionDefinition
+CommandObjectTypeSynthAdd::CommandOptions::g_option_table[] =
+{
+    { LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean,    "If true, cascade to derived typedefs."},
+    { LLDB_OPT_SET_ALL, false, "child", 'c', required_argument, NULL, 0, eArgTypeName,    "Include this expression path in the synthetic view."},
+    { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeBoolean,         "Don't use this format for pointers-to-type objects."},
+    { LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeBoolean,         "Don't use this format for references-to-type objects."},
+    { LLDB_OPT_SET_ALL, false, "category", 'w', required_argument, NULL, 0, eArgTypeName,         "Add this to the given category instead of the default one."},
+    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
+};
+
 class CommandObjectTypeFormat : public CommandObjectMultiword
 {
 public:
@@ -1906,6 +2570,27 @@
     }
 };
 
+class CommandObjectTypeSynth : public CommandObjectMultiword
+{
+public:
+    CommandObjectTypeSynth (CommandInterpreter &interpreter) :
+    CommandObjectMultiword (interpreter,
+                            "type synth",
+                            "A set of commands for operating on synthetic type representations",
+                            "type synth [<sub-command-options>] ")
+    {
+        LoadSubCommand ("add",           CommandObjectSP (new CommandObjectTypeSynthAdd (interpreter)));
+        LoadSubCommand ("clear",         CommandObjectSP (new CommandObjectTypeSynthClear (interpreter)));
+        LoadSubCommand ("delete",        CommandObjectSP (new CommandObjectTypeSynthDelete (interpreter)));
+        LoadSubCommand ("list",          CommandObjectSP (new CommandObjectTypeSynthList (interpreter)));
+    }
+    
+    
+    ~CommandObjectTypeSynth ()
+    {
+    }
+};
+
 class CommandObjectTypeCategory : public CommandObjectMultiword
 {
 public:
@@ -1961,6 +2646,7 @@
     LoadSubCommand ("category",  CommandObjectSP (new CommandObjectTypeCategory (interpreter)));
     LoadSubCommand ("format",    CommandObjectSP (new CommandObjectTypeFormat (interpreter)));
     LoadSubCommand ("summary",   CommandObjectSP (new CommandObjectTypeSummary (interpreter)));
+    LoadSubCommand ("synth",     CommandObjectSP (new CommandObjectTypeSynth (interpreter)));
 }