Move Objective-C data formatters to the Objective-C language plugin where they belong

llvm-svn: 247627
diff --git a/lldb/source/Plugins/Language/ObjC/NSSet.cpp b/lldb/source/Plugins/Language/ObjC/NSSet.cpp
new file mode 100644
index 0000000..113e05d
--- /dev/null
+++ b/lldb/source/Plugins/Language/ObjC/NSSet.cpp
@@ -0,0 +1,718 @@
+//===-- NSSet.cpp ------------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Cocoa.h"
+
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/DataFormatters/FormattersHelpers.h"
+#include "lldb/Host/Endian.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+namespace lldb_private {
+    namespace formatters {
+        class NSSetISyntheticFrontEnd : public SyntheticChildrenFrontEnd
+        {
+        private:
+            struct DataDescriptor_32
+            {
+                uint32_t _used : 26;
+                uint32_t _szidx : 6;
+            };
+            struct DataDescriptor_64
+            {
+                uint64_t _used : 58;
+                uint32_t _szidx : 6;
+            };
+            
+            struct SetItemDescriptor
+            {
+                lldb::addr_t item_ptr;
+                lldb::ValueObjectSP valobj_sp;
+            };
+            
+        public:
+            NSSetISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+            
+            virtual size_t
+            CalculateNumChildren ();
+            
+            virtual lldb::ValueObjectSP
+            GetChildAtIndex (size_t idx);
+            
+            virtual bool
+            Update();
+            
+            virtual bool
+            MightHaveChildren ();
+            
+            virtual size_t
+            GetIndexOfChildWithName (const ConstString &name);
+            
+            virtual
+            ~NSSetISyntheticFrontEnd ();
+        private:
+            ExecutionContextRef m_exe_ctx_ref;
+            uint8_t m_ptr_size;
+            DataDescriptor_32 *m_data_32;
+            DataDescriptor_64 *m_data_64;
+            lldb::addr_t m_data_ptr;
+            std::vector<SetItemDescriptor> m_children;
+        };
+        
+        class NSOrderedSetSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+        {
+        private:
+            
+        public:
+            NSOrderedSetSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+            
+            virtual size_t
+            CalculateNumChildren ();
+            
+            virtual lldb::ValueObjectSP
+            GetChildAtIndex (size_t idx);
+            
+            virtual bool
+            Update();
+            
+            virtual bool
+            MightHaveChildren ();
+            
+            virtual size_t
+            GetIndexOfChildWithName (const ConstString &name);
+            
+            virtual
+            ~NSOrderedSetSyntheticFrontEnd ();
+        private:
+            uint32_t m_count;
+            std::map<uint32_t,lldb::ValueObjectSP> m_children;
+        };
+        
+        class NSSetMSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+        {
+        private:
+            struct DataDescriptor_32
+            {
+                uint32_t _used : 26;
+                uint32_t _size;
+                uint32_t _mutations;
+                uint32_t _objs_addr;
+            };
+            struct DataDescriptor_64
+            {
+                uint64_t _used : 58;
+                uint64_t _size;
+                uint64_t _mutations;
+                uint64_t _objs_addr;
+            };
+            struct SetItemDescriptor
+            {
+                lldb::addr_t item_ptr;
+                lldb::ValueObjectSP valobj_sp;
+            };
+        public:
+            NSSetMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+            
+            virtual size_t
+            CalculateNumChildren ();
+            
+            virtual lldb::ValueObjectSP
+            GetChildAtIndex (size_t idx);
+            
+            virtual bool
+            Update();
+            
+            virtual bool
+            MightHaveChildren ();
+            
+            virtual size_t
+            GetIndexOfChildWithName (const ConstString &name);
+            
+            virtual
+            ~NSSetMSyntheticFrontEnd ();
+        private:
+            ExecutionContextRef m_exe_ctx_ref;
+            uint8_t m_ptr_size;
+            DataDescriptor_32 *m_data_32;
+            DataDescriptor_64 *m_data_64;
+            std::vector<SetItemDescriptor> m_children;
+        };
+        
+        class NSSetCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+        {
+        public:
+            NSSetCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+            
+            virtual size_t
+            CalculateNumChildren ();
+            
+            virtual lldb::ValueObjectSP
+            GetChildAtIndex (size_t idx);
+            
+            virtual bool
+            Update();
+            
+            virtual bool
+            MightHaveChildren ();
+            
+            virtual size_t
+            GetIndexOfChildWithName (const ConstString &name);
+            
+            virtual
+            ~NSSetCodeRunningSyntheticFrontEnd ();
+        };
+    }
+}
+
+template<bool cf_style>
+bool
+lldb_private::formatters::NSSetSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
+{
+    ProcessSP process_sp = valobj.GetProcessSP();
+    if (!process_sp)
+        return false;
+    
+    ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+    
+    if (!runtime)
+        return false;
+    
+    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+    
+    if (!descriptor.get() || !descriptor->IsValid())
+        return false;
+    
+    uint32_t ptr_size = process_sp->GetAddressByteSize();
+    bool is_64bit = (ptr_size == 8);
+    
+    lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+    
+    if (!valobj_addr)
+        return false;
+    
+    uint64_t value = 0;
+    
+    const char* class_name = descriptor->GetClassName().GetCString();
+    
+    if (!class_name || !*class_name)
+        return false;
+    
+    if (!strcmp(class_name,"__NSSetI"))
+    {
+        Error error;
+        value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
+        if (error.Fail())
+            return false;
+        value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
+    }
+    else if (!strcmp(class_name,"__NSSetM"))
+    {
+        Error error;
+        value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
+        if (error.Fail())
+            return false;
+        value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
+    }
+    /*else if (!strcmp(class_name,"__NSCFSet"))
+    {
+        Error error;
+        value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + (is_64bit ? 20 : 12), 4, 0, error);
+        if (error.Fail())
+            return false;
+        if (is_64bit)
+            value &= ~0x1fff000000000000UL;
+    }
+    else if (!strcmp(class_name,"NSCountedSet"))
+    {
+        Error error;
+        value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
+        if (error.Fail())
+            return false;
+        value = process_sp->ReadUnsignedIntegerFromMemory(value + (is_64bit ? 20 : 12), 4, 0, error);
+        if (error.Fail())
+            return false;
+        if (is_64bit)
+            value &= ~0x1fff000000000000UL;
+    }*/
+    else
+    {
+        if (!ExtractValueFromObjCExpression(valobj, "int", "count", value))
+            return false;
+    }
+    
+    stream.Printf("%s%" PRIu64 " %s%s",
+                  (cf_style ? "@\"" : ""),
+                  value,
+                  (cf_style ? (value == 1 ? "value" : "values") : (value == 1 ? "object" : "objects")),
+                  (cf_style ? "\"" : ""));
+    return true;
+}
+
+SyntheticChildrenFrontEnd* lldb_private::formatters::NSSetSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
+{
+    lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
+    if (!process_sp)
+        return NULL;
+    ObjCLanguageRuntime *runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+    if (!runtime)
+        return NULL;
+    
+    if (!valobj_sp->IsPointerType())
+    {
+        Error error;
+        valobj_sp = valobj_sp->AddressOf(error);
+        if (error.Fail() || !valobj_sp)
+            return NULL;
+    }
+    
+    ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp.get()));
+    
+    if (!descriptor.get() || !descriptor->IsValid())
+        return NULL;
+    
+    const char* class_name = descriptor->GetClassName().GetCString();
+    
+    if (!class_name || !*class_name)
+        return NULL;
+    
+    if (!strcmp(class_name,"__NSSetI"))
+    {
+        return (new NSSetISyntheticFrontEnd(valobj_sp));
+    }
+    else if (!strcmp(class_name,"__NSSetM"))
+    {
+        return (new NSSetMSyntheticFrontEnd(valobj_sp));
+    }
+    else if ((!strcmp(class_name,"__NSOrderedSetI")) || (!strcmp(class_name,"__NSOrderedSetM")))
+    {
+        return new NSOrderedSetSyntheticFrontEnd(valobj_sp); // this runs code
+    }
+    else
+    {
+        return /*(new NSSetCodeRunningSyntheticFrontEnd(valobj_sp))*/ NULL;
+    }
+}
+
+lldb_private::formatters::NSSetISyntheticFrontEnd::NSSetISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+SyntheticChildrenFrontEnd(*valobj_sp.get()),
+m_exe_ctx_ref(),
+m_ptr_size(8),
+m_data_32(NULL),
+m_data_64(NULL)
+{
+    if (valobj_sp)
+        Update();
+}
+
+lldb_private::formatters::NSSetISyntheticFrontEnd::~NSSetISyntheticFrontEnd ()
+{
+    delete m_data_32;
+    m_data_32 = NULL;
+    delete m_data_64;
+    m_data_64 = NULL;
+}
+
+size_t
+lldb_private::formatters::NSSetISyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+    const char* item_name = name.GetCString();
+    uint32_t idx = ExtractIndexFromString(item_name);
+    if (idx < UINT32_MAX && idx >= CalculateNumChildren())
+        return UINT32_MAX;
+    return idx;
+}
+
+size_t
+lldb_private::formatters::NSSetISyntheticFrontEnd::CalculateNumChildren ()
+{
+    if (!m_data_32 && !m_data_64)
+        return 0;
+    return (m_data_32 ? m_data_32->_used : m_data_64->_used);
+}
+
+bool
+lldb_private::formatters::NSSetISyntheticFrontEnd::Update()
+{
+    m_children.clear();
+    delete m_data_32;
+    m_data_32 = NULL;
+    delete m_data_64;
+    m_data_64 = NULL;
+    m_ptr_size = 0;
+    ValueObjectSP valobj_sp = m_backend.GetSP();
+    if (!valobj_sp)
+        return false;
+    if (!valobj_sp)
+        return false;
+    m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+    Error error;
+    if (valobj_sp->IsPointerType())
+    {
+        valobj_sp = valobj_sp->Dereference(error);
+        if (error.Fail() || !valobj_sp)
+            return false;
+    }
+    error.Clear();
+    lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+    if (!process_sp)
+        return false;
+    m_ptr_size = process_sp->GetAddressByteSize();
+    uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
+    if (m_ptr_size == 4)
+    {
+        m_data_32 = new DataDescriptor_32();
+        process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
+    }
+    else
+    {
+        m_data_64 = new DataDescriptor_64();
+        process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
+    }
+    if (error.Fail())
+        return false;
+    m_data_ptr = data_location + m_ptr_size;
+    return false;
+}
+
+bool
+lldb_private::formatters::NSSetISyntheticFrontEnd::MightHaveChildren ()
+{
+    return true;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::NSSetISyntheticFrontEnd::GetChildAtIndex (size_t idx)
+{
+    uint32_t num_children = CalculateNumChildren();
+    
+    if (idx >= num_children)
+        return lldb::ValueObjectSP();
+    
+    ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
+    if (!process_sp)
+        return lldb::ValueObjectSP();
+    
+    if (m_children.empty())
+    {
+        // do the scan phase
+        lldb::addr_t obj_at_idx = 0;
+        
+        uint32_t tries = 0;
+        uint32_t test_idx = 0;
+        
+        while(tries < num_children)
+        {
+            obj_at_idx = m_data_ptr + (test_idx * m_ptr_size);
+            if (!process_sp)
+                return lldb::ValueObjectSP();
+            Error error;
+            obj_at_idx = process_sp->ReadPointerFromMemory(obj_at_idx, error);
+            if (error.Fail())
+                return lldb::ValueObjectSP();
+            
+            test_idx++;
+            
+            if (!obj_at_idx)
+                continue;
+            tries++;
+            
+            SetItemDescriptor descriptor = {obj_at_idx,lldb::ValueObjectSP()};
+            
+            m_children.push_back(descriptor);
+        }
+    }
+    
+    if (idx >= m_children.size()) // should never happen
+        return lldb::ValueObjectSP();
+    
+    SetItemDescriptor &set_item = m_children[idx];
+    if (!set_item.valobj_sp)
+    {
+        auto ptr_size = process_sp->GetAddressByteSize();
+        DataBufferHeap buffer(ptr_size,0);
+        switch (ptr_size)
+        {
+            case 0: // architecture has no clue?? - fail
+                return lldb::ValueObjectSP();
+            case 4:
+                *((uint32_t*)buffer.GetBytes()) = (uint32_t)set_item.item_ptr;
+                break;
+            case 8:
+                *((uint64_t*)buffer.GetBytes()) = (uint64_t)set_item.item_ptr;
+                break;
+            default:
+                assert(false && "pointer size is not 4 nor 8 - get out of here ASAP");
+        }
+        StreamString idx_name;
+        idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+        
+        DataExtractor data(buffer.GetBytes(),
+                           buffer.GetByteSize(),
+                           process_sp->GetByteOrder(),
+                           process_sp->GetAddressByteSize());
+        
+        set_item.valobj_sp =
+            CreateValueObjectFromData(idx_name.GetData(),
+                                      data,
+                                      m_exe_ctx_ref,
+                                      m_backend.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeObjCID));
+    }
+    return set_item.valobj_sp;
+}
+
+lldb_private::formatters::NSSetMSyntheticFrontEnd::NSSetMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+SyntheticChildrenFrontEnd(*valobj_sp.get()),
+m_exe_ctx_ref(),
+m_ptr_size(8),
+m_data_32(NULL),
+m_data_64(NULL)
+{
+    if (valobj_sp)
+        Update ();
+}
+
+lldb_private::formatters::NSSetMSyntheticFrontEnd::~NSSetMSyntheticFrontEnd ()
+{
+    delete m_data_32;
+    m_data_32 = NULL;
+    delete m_data_64;
+    m_data_64 = NULL;
+}
+
+size_t
+lldb_private::formatters::NSSetMSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+    const char* item_name = name.GetCString();
+    uint32_t idx = ExtractIndexFromString(item_name);
+    if (idx < UINT32_MAX && idx >= CalculateNumChildren())
+        return UINT32_MAX;
+    return idx;
+}
+
+size_t
+lldb_private::formatters::NSSetMSyntheticFrontEnd::CalculateNumChildren ()
+{
+    if (!m_data_32 && !m_data_64)
+        return 0;
+    return (m_data_32 ? m_data_32->_used : m_data_64->_used);
+}
+
+bool
+lldb_private::formatters::NSSetMSyntheticFrontEnd::Update()
+{
+    m_children.clear();
+    ValueObjectSP valobj_sp = m_backend.GetSP();
+    m_ptr_size = 0;
+    delete m_data_32;
+    m_data_32 = NULL;
+    delete m_data_64;
+    m_data_64 = NULL;
+    if (!valobj_sp)
+        return false;
+    if (!valobj_sp)
+        return false;
+    m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+    Error error;
+    if (valobj_sp->IsPointerType())
+    {
+        valobj_sp = valobj_sp->Dereference(error);
+        if (error.Fail() || !valobj_sp)
+            return false;
+    }
+    error.Clear();
+    lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+    if (!process_sp)
+        return false;
+    m_ptr_size = process_sp->GetAddressByteSize();
+    uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
+    if (m_ptr_size == 4)
+    {
+        m_data_32 = new DataDescriptor_32();
+        process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
+    }
+    else
+    {
+        m_data_64 = new DataDescriptor_64();
+        process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
+    }
+    if (error.Fail())
+        return false;
+    return false;
+}
+
+bool
+lldb_private::formatters::NSSetMSyntheticFrontEnd::MightHaveChildren ()
+{
+    return true;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::NSSetMSyntheticFrontEnd::GetChildAtIndex (size_t idx)
+{
+    lldb::addr_t m_objs_addr = (m_data_32 ? m_data_32->_objs_addr : m_data_64->_objs_addr);
+
+    uint32_t num_children = CalculateNumChildren();
+    
+    if (idx >= num_children)
+        return lldb::ValueObjectSP();
+    
+    ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
+    if (!process_sp)
+        return lldb::ValueObjectSP();
+    
+    if (m_children.empty())
+    {
+        // do the scan phase
+        lldb::addr_t obj_at_idx = 0;
+        
+        uint32_t tries = 0;
+        uint32_t test_idx = 0;
+        
+        while(tries < num_children)
+        {
+            obj_at_idx = m_objs_addr + (test_idx * m_ptr_size);
+            if (!process_sp)
+                return lldb::ValueObjectSP();
+            Error error;
+            obj_at_idx = process_sp->ReadPointerFromMemory(obj_at_idx, error);
+            if (error.Fail())
+                return lldb::ValueObjectSP();
+            
+            test_idx++;
+            
+            if (!obj_at_idx)
+                continue;
+            tries++;
+            
+            SetItemDescriptor descriptor = {obj_at_idx,lldb::ValueObjectSP()};
+            
+            m_children.push_back(descriptor);
+        }
+    }
+    
+    if (idx >= m_children.size()) // should never happen
+        return lldb::ValueObjectSP();
+    
+    SetItemDescriptor &set_item = m_children[idx];
+    if (!set_item.valobj_sp)
+    {
+        auto ptr_size = process_sp->GetAddressByteSize();
+        DataBufferHeap buffer(ptr_size,0);
+        switch (ptr_size)
+        {
+            case 0: // architecture has no clue?? - fail
+                return lldb::ValueObjectSP();
+            case 4:
+                *((uint32_t*)buffer.GetBytes()) = (uint32_t)set_item.item_ptr;
+                break;
+            case 8:
+                *((uint64_t*)buffer.GetBytes()) = (uint64_t)set_item.item_ptr;
+                break;
+            default:
+                assert(false && "pointer size is not 4 nor 8 - get out of here ASAP");
+        }
+        StreamString idx_name;
+        idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+        
+        DataExtractor data(buffer.GetBytes(),
+                           buffer.GetByteSize(),
+                           process_sp->GetByteOrder(),
+                           process_sp->GetAddressByteSize());
+        
+        set_item.valobj_sp =
+            CreateValueObjectFromData(idx_name.GetData(),
+                                      data,
+                                      m_exe_ctx_ref,
+                                      m_backend.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeObjCID));
+    }
+    return set_item.valobj_sp;
+}
+
+lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::NSOrderedSetSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+SyntheticChildrenFrontEnd(*valobj_sp.get()),
+m_count(UINT32_MAX),
+m_children()
+{}
+
+size_t
+lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::CalculateNumChildren ()
+{
+    if (m_count != UINT32_MAX)
+        return m_count;
+    uint64_t count_temp;
+    if (ExtractValueFromObjCExpression(m_backend,"unsigned int","count",count_temp))
+        return (m_count = count_temp);
+    return (m_count = 0);
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::GetChildAtIndex (size_t idx)
+{
+    auto iter = m_children.find(idx);
+    if (iter == m_children.end())
+    {
+        lldb::ValueObjectSP retval_sp;
+        if (idx <= m_count)
+        {
+            retval_sp = CallSelectorOnObject(m_backend, "id", "objectAtIndex", idx);
+            if (retval_sp)
+            {
+                StreamString idx_name;
+                idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+                retval_sp->SetName(ConstString(idx_name.GetData()));
+            }
+            m_children[idx] = retval_sp;
+        }
+        return retval_sp;
+    }
+    else
+        return iter->second;
+}
+
+bool
+lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::Update()
+{
+    return false;
+}
+
+bool
+lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::MightHaveChildren ()
+{
+    return true;
+}
+
+size_t
+lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+    const char* item_name = name.GetCString();
+    uint32_t idx = ExtractIndexFromString(item_name);
+    if (idx < UINT32_MAX && idx >= CalculateNumChildren())
+        return UINT32_MAX;
+    return idx;
+}
+
+lldb_private::formatters::NSOrderedSetSyntheticFrontEnd::~NSOrderedSetSyntheticFrontEnd ()
+{
+}
+
+template bool
+lldb_private::formatters::NSSetSummaryProvider<true> (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);
+
+template bool
+lldb_private::formatters::NSSetSummaryProvider<false> (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options);