[Lldb-commits] [lldb] r164144 - in /lldb/trunk: include/lldb/Core/CXXFormatterFunctions.h source/Core/CXXFormatterFunctions.cpp source/Core/FormatManager.cpp source/Target/Target.cpp test/functionalities/data-formatter/rdar-11988289/ test/functionalities/data-formatter/rdar-11988289/Makefile test/functionalities/data-formatter/rdar-11988289/TestRdar 11988289.py test/functionalities/data-formatter/rdar-11988289/main.m

Enrico Granata egranata at apple.com
Tue Sep 18 10:43:16 PDT 2012


Author: enrico
Date: Tue Sep 18 12:43:16 2012
New Revision: 164144

URL: http://llvm.org/viewvc/llvm-project?rev=164144&view=rev
Log:
<rdar://problem/11988289> Making C++ synthetic children provider for NSDictionary and related classes

Added:
    lldb/trunk/test/functionalities/data-formatter/rdar-11988289/
    lldb/trunk/test/functionalities/data-formatter/rdar-11988289/Makefile
    lldb/trunk/test/functionalities/data-formatter/rdar-11988289/TestRdar 11988289.py
    lldb/trunk/test/functionalities/data-formatter/rdar-11988289/main.m
Modified:
    lldb/trunk/include/lldb/Core/CXXFormatterFunctions.h
    lldb/trunk/source/Core/CXXFormatterFunctions.cpp
    lldb/trunk/source/Core/FormatManager.cpp
    lldb/trunk/source/Target/Target.cpp

Modified: lldb/trunk/include/lldb/Core/CXXFormatterFunctions.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/CXXFormatterFunctions.h?rev=164144&r1=164143&r2=164144&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/CXXFormatterFunctions.h (original)
+++ lldb/trunk/include/lldb/Core/CXXFormatterFunctions.h Tue Sep 18 12:43:16 2012
@@ -169,6 +169,129 @@
         
         SyntheticChildrenFrontEnd* NSArraySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
         
+        class NSDictionaryISyntheticFrontEnd : 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 DictionaryItemDescriptor
+            {
+                lldb::addr_t key_ptr;
+                lldb::addr_t val_ptr;
+                lldb::ValueObjectSP valobj_sp;
+            };
+            
+        public:
+            NSDictionaryISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+            
+            virtual uint32_t
+            CalculateNumChildren ();
+            
+            virtual lldb::ValueObjectSP
+            GetChildAtIndex (uint32_t idx);
+            
+            virtual bool
+            Update();
+            
+            virtual uint32_t
+            GetIndexOfChildWithName (const ConstString &name);
+            
+            virtual
+            ~NSDictionaryISyntheticFrontEnd ();
+        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<DictionaryItemDescriptor> m_children;
+        };
+        
+        class NSDictionaryMSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+        {
+        private:
+            struct DataDescriptor_32
+            {
+                uint32_t _used : 26;
+                uint32_t _kvo : 1;
+                uint32_t _size;
+                uint32_t _mutations;
+                uint32_t _objs_addr;
+                uint32_t _keys_addr;
+            };
+            struct DataDescriptor_64
+            {
+                uint64_t _used : 58;
+                uint32_t _kvo : 1;
+                uint64_t _size;
+                uint64_t _mutations;
+                uint64_t _objs_addr;
+                uint64_t _keys_addr;
+            };
+            struct DictionaryItemDescriptor
+            {
+                lldb::addr_t key_ptr;
+                lldb::addr_t val_ptr;
+                lldb::ValueObjectSP valobj_sp;
+            };
+        public:
+            NSDictionaryMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+            
+            virtual uint32_t
+            CalculateNumChildren ();
+            
+            virtual lldb::ValueObjectSP
+            GetChildAtIndex (uint32_t idx);
+            
+            virtual bool
+            Update();
+            
+            virtual uint32_t
+            GetIndexOfChildWithName (const ConstString &name);
+            
+            virtual
+            ~NSDictionaryMSyntheticFrontEnd ();
+        private:
+            ExecutionContextRef m_exe_ctx_ref;
+            uint8_t m_ptr_size;
+            uint64_t m_items;
+            DataDescriptor_32 *m_data_32;
+            DataDescriptor_64 *m_data_64;
+            std::vector<DictionaryItemDescriptor> m_children;
+        };
+        
+        class NSDictionaryCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+        {
+        public:
+            NSDictionaryCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+            
+            virtual uint32_t
+            CalculateNumChildren ();
+            
+            virtual lldb::ValueObjectSP
+            GetChildAtIndex (uint32_t idx);
+            
+            virtual bool
+            Update();
+            
+            virtual uint32_t
+            GetIndexOfChildWithName (const ConstString &name);
+            
+            virtual
+            ~NSDictionaryCodeRunningSyntheticFrontEnd ();
+        };
+        
+        SyntheticChildrenFrontEnd* NSDictionarySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+        
     }
 }
 

Modified: lldb/trunk/source/Core/CXXFormatterFunctions.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/CXXFormatterFunctions.cpp?rev=164144&r1=164143&r2=164144&view=diff
==============================================================================
--- lldb/trunk/source/Core/CXXFormatterFunctions.cpp (original)
+++ lldb/trunk/source/Core/CXXFormatterFunctions.cpp Tue Sep 18 12:43:16 2012
@@ -1029,6 +1029,362 @@
 lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::~NSArrayCodeRunningSyntheticFrontEnd ()
 {}
 
+SyntheticChildrenFrontEnd* lldb_private::formatters::NSDictionarySyntheticFrontEndCreator (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 (!strcmp(class_name,"__NSDictionaryI"))
+    {
+        return (new NSDictionaryISyntheticFrontEnd(valobj_sp));
+    }
+    else if (!strcmp(class_name,"__NSDictionaryM"))
+    {
+        return (new NSDictionaryMSyntheticFrontEnd(valobj_sp));
+    }
+    else
+    {
+        return (new NSDictionaryCodeRunningSyntheticFrontEnd(valobj_sp));
+    }
+}
+
+lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::NSDictionaryCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+SyntheticChildrenFrontEnd(*valobj_sp.get())
+{}
+
+uint32_t
+lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::CalculateNumChildren ()
+{
+    uint64_t count = 0;
+    if (ExtractValueFromObjCExpression(m_backend, "int", "count", count))
+        return count;
+    return 0;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::GetChildAtIndex (uint32_t idx)
+{
+    StreamString idx_name;
+    idx_name.Printf("[%d]",idx);
+    StreamString valobj_expr_path;
+    m_backend.GetExpressionPath(valobj_expr_path, false);
+    StreamString key_fetcher_expr;
+    key_fetcher_expr.Printf("(id)[(NSArray*)[%s allKeys] objectAtIndex:%d]",valobj_expr_path.GetData(),idx);
+    StreamString value_fetcher_expr;
+    value_fetcher_expr.Printf("(id)[%s objectForKey:%s]",valobj_expr_path.GetData(),key_fetcher_expr.GetData());
+    StreamString object_fetcher_expr;
+    object_fetcher_expr.Printf("struct { id key; id value; } _lldb_valgen_item; _lldb_valgen_item.key = %s; _lldb_valgen_item.value = %s; _lldb_valgen_item;",key_fetcher_expr.GetData(),value_fetcher_expr.GetData());
+    lldb::ValueObjectSP child_sp;
+    m_backend.GetTargetSP()->EvaluateExpression(object_fetcher_expr.GetData(), m_backend.GetFrameSP().get(), child_sp,
+                                                Target::EvaluateExpressionOptions().SetKeepInMemory(true));
+    if (child_sp)
+        child_sp->SetName(ConstString(idx_name.GetData()));
+    return child_sp;
+}
+
+bool
+lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::Update()
+{
+    return false;
+}
+
+uint32_t
+lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+    return 0;
+}
+
+lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::~NSDictionaryCodeRunningSyntheticFrontEnd ()
+{}
+
+lldb_private::formatters::NSDictionaryISyntheticFrontEnd::NSDictionaryISyntheticFrontEnd (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)
+        return;
+    if (valobj_sp->IsDynamic())
+        valobj_sp = valobj_sp->GetStaticValue();
+    if (!valobj_sp)
+        return;
+    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;
+    }
+    error.Clear();
+    lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+    if (!process_sp)
+        return;
+    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;
+    m_data_ptr = data_location + m_ptr_size;
+}
+
+lldb_private::formatters::NSDictionaryISyntheticFrontEnd::~NSDictionaryISyntheticFrontEnd ()
+{
+    delete m_data_32;
+    m_data_32 = NULL;
+    delete m_data_64;
+    m_data_64 = NULL;
+}
+
+uint32_t
+lldb_private::formatters::NSDictionaryISyntheticFrontEnd::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;
+}
+
+uint32_t
+lldb_private::formatters::NSDictionaryISyntheticFrontEnd::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::NSDictionaryISyntheticFrontEnd::Update()
+{
+    m_children.clear();
+    return false;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetChildAtIndex (uint32_t idx)
+{
+    uint32_t num_children = CalculateNumChildren();
+    
+    if (idx >= num_children)
+        return lldb::ValueObjectSP();
+    
+    if (m_children.empty())
+    {
+        // do the scan phase
+        lldb::addr_t key_at_idx = 0, val_at_idx = 0;
+        
+        uint32_t tries = 0;
+        uint32_t test_idx = 0;
+        
+        while(tries < num_children)
+        {
+            key_at_idx = m_data_ptr + (2*test_idx * m_ptr_size);
+            val_at_idx = key_at_idx + m_ptr_size;
+            ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
+            if (!process_sp)
+                return lldb::ValueObjectSP();
+            Error error;
+            key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
+            if (error.Fail())
+                return lldb::ValueObjectSP();
+            val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
+            if (error.Fail())
+                return lldb::ValueObjectSP();
+
+            test_idx++;
+            
+            if (!key_at_idx || !val_at_idx)
+                continue;
+            tries++;
+            
+            DictionaryItemDescriptor descriptor = {key_at_idx,val_at_idx,lldb::ValueObjectSP()};
+            
+            m_children.push_back(descriptor);
+        }
+    }
+    
+    if (idx >= m_children.size()) // should never happen
+        return lldb::ValueObjectSP();
+    
+    DictionaryItemDescriptor &dict_item = m_children[idx];
+    if (!dict_item.valobj_sp)
+    {
+        // make the new ValueObject
+        StreamString expr;
+        expr.Printf("struct { id key; id value; } _lldb_valgen_item; _lldb_valgen_item.key = (id)%llu ; _lldb_valgen_item.value = (id)%llu; _lldb_valgen_item;",dict_item.key_ptr,dict_item.val_ptr);
+        StreamString idx_name;
+        idx_name.Printf("[%d]",idx);
+        dict_item.valobj_sp = ValueObject::CreateValueObjectFromExpression(idx_name.GetData(), expr.GetData(), m_exe_ctx_ref);
+    }
+    return dict_item.valobj_sp;
+}
+
+lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::NSDictionaryMSyntheticFrontEnd (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)
+        return;
+    if (valobj_sp->IsDynamic())
+        valobj_sp = valobj_sp->GetStaticValue();
+    if (!valobj_sp)
+        return;
+    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;
+    }
+    error.Clear();
+    lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+    if (!process_sp)
+        return;
+    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;
+}
+
+lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::~NSDictionaryMSyntheticFrontEnd ()
+{
+    delete m_data_32;
+    m_data_32 = NULL;
+    delete m_data_64;
+    m_data_64 = NULL;
+}
+
+uint32_t
+lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::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;
+}
+
+uint32_t
+lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::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::NSDictionaryMSyntheticFrontEnd::Update()
+{
+    m_children.clear();
+    return false;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetChildAtIndex (uint32_t idx)
+{
+    lldb::addr_t m_keys_ptr = (m_data_32 ? m_data_32->_keys_addr : m_data_64->_keys_addr);
+    lldb::addr_t m_values_ptr = (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();
+    
+    if (m_children.empty())
+    {
+        // do the scan phase
+        lldb::addr_t key_at_idx = 0, val_at_idx = 0;
+        
+        uint32_t tries = 0;
+        uint32_t test_idx = 0;
+        
+        while(tries < num_children)
+        {
+            key_at_idx = m_keys_ptr + (test_idx * m_ptr_size);
+            val_at_idx = m_values_ptr + (test_idx * m_ptr_size);;
+            ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
+            if (!process_sp)
+                return lldb::ValueObjectSP();
+            Error error;
+            key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
+            if (error.Fail())
+                return lldb::ValueObjectSP();
+            val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
+            if (error.Fail())
+                return lldb::ValueObjectSP();
+            
+            test_idx++;
+            
+            if (!key_at_idx || !val_at_idx)
+                continue;
+            tries++;
+            
+            DictionaryItemDescriptor descriptor = {key_at_idx,val_at_idx,lldb::ValueObjectSP()};
+            
+            m_children.push_back(descriptor);
+        }
+    }
+    
+    if (idx >= m_children.size()) // should never happen
+        return lldb::ValueObjectSP();
+    
+    DictionaryItemDescriptor &dict_item = m_children[idx];
+    if (!dict_item.valobj_sp)
+    {
+        // make the new ValueObject
+        StreamString expr;
+        expr.Printf("struct { id key; id value; } _lldb_valgen_item; _lldb_valgen_item.key = (id)%llu ; _lldb_valgen_item.value = (id)%llu; _lldb_valgen_item;",dict_item.key_ptr,dict_item.val_ptr);
+        StreamString idx_name;
+        idx_name.Printf("[%d]",idx);
+        dict_item.valobj_sp = ValueObject::CreateValueObjectFromExpression(idx_name.GetData(), expr.GetData(), m_exe_ctx_ref);
+    }
+    return dict_item.valobj_sp;
+}
 
 template bool
 lldb_private::formatters::NSDictionarySummaryProvider<true> (ValueObject&, Stream&) ;

Modified: lldb/trunk/source/Core/FormatManager.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FormatManager.cpp?rev=164144&r1=164143&r2=164144&view=diff
==============================================================================
--- lldb/trunk/source/Core/FormatManager.cpp (original)
+++ lldb/trunk/source/Core/FormatManager.cpp Tue Sep 18 12:43:16 2012
@@ -1041,7 +1041,6 @@
                ConstString("HIRect"),
                objc_flags);
     
-#ifndef LLDB_DISABLE_PYTHON
     TypeCategoryImpl::SharedPointer appkit_category_sp = GetCategory(m_appkit_category_name);
     
     TypeSummaryImpl::Flags appkit_flags;
@@ -1064,6 +1063,16 @@
     AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("CFArrayRef"), appkit_flags);
     AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("CFMutableArrayRef"), appkit_flags);
 
+    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("NSDictionary"), appkit_flags);
+    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("NSMutableDictionary"), appkit_flags);
+    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSCFDictionary"), appkit_flags);
+    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSDictionaryI"), appkit_flags);
+    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSDictionaryM"), appkit_flags);
+    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<true>, "NSDictionary summary provider", ConstString("CFDictionaryRef"), appkit_flags);
+    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<true>, "NSDictionary summary provider", ConstString("CFMutableDictionaryRef"), appkit_flags);
+    
+    // AddSummary(appkit_category_sp, "${var.key%@} -> ${var.value%@}", ConstString("$_lldb_typegen_nspair"), appkit_flags);
+    
     appkit_flags.SetDontShowChildren(true);
     
     AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSArrayM"), TypeSyntheticImpl::Flags());
@@ -1072,6 +1081,14 @@
     AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("NSMutableArray"), TypeSyntheticImpl::Flags());
     AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSCFArray"), TypeSyntheticImpl::Flags());
 
+    AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("__NSDictionaryM"), TypeSyntheticImpl::Flags());
+    AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("__NSDictionaryI"), TypeSyntheticImpl::Flags());
+    AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("NSDictionary"), TypeSyntheticImpl::Flags());
+    AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("NSMutableDictionary"), TypeSyntheticImpl::Flags());
+    AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("CFDictionaryRef"), TypeSyntheticImpl::Flags());
+    AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("CFMutableDictionaryRef"), TypeSyntheticImpl::Flags());
+
+#ifndef LLDB_DISABLE_PYTHON
     AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBag.CFBag_SummaryProvider", ConstString("CFBagRef"), appkit_flags);
     AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBag.CFBag_SummaryProvider", ConstString("__CFBag"), appkit_flags);
     AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBag.CFBag_SummaryProvider", ConstString("const struct __CFBag"), appkit_flags);
@@ -1080,13 +1097,6 @@
     AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBinaryHeap.CFBinaryHeap_SummaryProvider", ConstString("CFBinaryHeapRef"), appkit_flags);
     AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBinaryHeap.CFBinaryHeap_SummaryProvider", ConstString("__CFBinaryHeap"), appkit_flags);
 
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("NSDictionary"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSCFDictionary"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSDictionaryI"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSDictionaryM"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<true>, "NSDictionary summary provider", ConstString("CFDictionaryRef"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<true>, "NSDictionary summary provider", ConstString("CFMutableDictionaryRef"), appkit_flags);
-
     AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSString"), appkit_flags);
     AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("CFStringRef"), appkit_flags);
     AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("CFMutableStringRef"), appkit_flags);

Modified: lldb/trunk/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=164144&r1=164143&r2=164144&view=diff
==============================================================================
--- lldb/trunk/source/Target/Target.cpp (original)
+++ lldb/trunk/source/Target/Target.cpp Tue Sep 18 12:43:16 2012
@@ -1620,6 +1620,8 @@
     const EvaluateExpressionOptions& options
 )
 {
+    result_valobj_sp.reset();
+    
     ExecutionResults execution_results = eExecutionSetupError;
 
     if (expr_cstr == NULL || expr_cstr[0] == '\0')

Added: lldb/trunk/test/functionalities/data-formatter/rdar-11988289/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/rdar-11988289/Makefile?rev=164144&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/rdar-11988289/Makefile (added)
+++ lldb/trunk/test/functionalities/data-formatter/rdar-11988289/Makefile Tue Sep 18 12:43:16 2012
@@ -0,0 +1,9 @@
+LEVEL = ../../../make
+
+OBJC_SOURCES := main.m
+
+CFLAGS_EXTRAS += -w
+
+include $(LEVEL)/Makefile.rules
+
+LDFLAGS += -framework Foundation

Added: lldb/trunk/test/functionalities/data-formatter/rdar-11988289/TestRdar 11988289.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/rdar-11988289/TestRdar%2011988289.py?rev=164144&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/rdar-11988289/TestRdar 11988289.py (added)
+++ lldb/trunk/test/functionalities/data-formatter/rdar-11988289/TestRdar 11988289.py Tue Sep 18 12:43:16 2012
@@ -0,0 +1,84 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+import datetime
+
+class DataFormatterRdar11988289TestCase(TestBase):
+
+    mydir = os.path.join("functionalities", "data-formatter", "rdar-11988289")
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @dsym_test
+    def test_rdar11988289_with_dsym_and_run_command(self):
+        """Test that NSDictionary reports its synthetic children properly."""
+        self.buildDsym()
+        self.rdar11988289_tester()
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @dwarf_test
+    def test_rdar11988289_with_dwarf_and_run_command(self):
+        """Test that NSDictionary reports its synthetic children properly."""
+        self.buildDwarf()
+        self.rdar11988289_tester()
+
+    def setUp(self):
+        # Call super's setUp().
+        TestBase.setUp(self)
+        # Find the line number to break at.
+        self.line = line_number('main.m', '// Set break point at this line.')
+
+    def rdar11988289_tester(self):
+        """Test that NSDictionary reports its synthetic children properly."""
+        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+        self.expect("breakpoint set -f main.m -l %d" % self.line,
+                    BREAKPOINT_CREATED,
+            startstr = "Breakpoint created: 1: file ='main.m', 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 synth clear', check=False)
+
+        # Execute the cleanup function during test case tear down.
+        self.addTearDownHook(cleanup)
+
+        # Now check that we are displaying Cocoa classes correctly
+        self.expect('frame variable dictionary',
+                    substrs = ['3 key/value pairs'])
+        self.expect('frame variable mutable',
+                    substrs = ['4 key/value pairs'])
+        self.expect('frame variable dictionary --ptr-depth 1',
+                    substrs = ['3 key/value pairs','[0] = {','key = 0x','value = 0x','[1] = {','[2] = {'])
+        self.expect('frame variable mutable --ptr-depth 1',
+                    substrs = ['4 key/value pairs','[0] = {','key = 0x','value = 0x','[1] = {','[2] = {','[3] = {'])
+        self.expect('frame variable dictionary --ptr-depth 1 -d no-run-target',
+                    substrs = ['3 key/value pairs','@"bar"','@"2 objects"','@"baz"','2 key/value pairs'])
+        self.expect('frame variable mutable --ptr-depth 1 -d no-run-target',
+                    substrs = ['4 key/value pairs','(int)23','@"123"','@"http://www.apple.com"','@"puartist"','3 key/value pairs'])
+        self.expect('frame variable mutable --ptr-depth 2 -d no-run-target',
+        substrs = ['4 key/value pairs','(int)23','@"123"','@"http://www.apple.com"','@"puartist"','3 key/value pairs {','@"bar"','@"2 objects"'])
+        self.expect('frame variable mutable --ptr-depth 3 -d no-run-target',
+        substrs = ['4 key/value pairs','(int)23','@"123"','@"http://www.apple.com"','@"puartist"','3 key/value pairs {','@"bar"','@"2 objects"','(int)1','@"two"'])
+
+
+if __name__ == '__main__':
+    import atexit
+    lldb.SBDebugger.Initialize()
+    atexit.register(lambda: lldb.SBDebugger.Terminate())
+    unittest2.main()

Added: lldb/trunk/test/functionalities/data-formatter/rdar-11988289/main.m
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/rdar-11988289/main.m?rev=164144&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/rdar-11988289/main.m (added)
+++ lldb/trunk/test/functionalities/data-formatter/rdar-11988289/main.m Tue Sep 18 12:43:16 2012
@@ -0,0 +1,30 @@
+//===-- main.m ------------------------------------------------*- ObjC -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#import <Foundation/Foundation.h>
+
+int main (int argc, const char * argv[])
+{
+    
+    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+
+
+	NSArray* keys = @[@"foo",@"bar",@"baz"];
+	NSArray* values = @[@"hello",@[@"X",@"Y"],@{@1 : @"one", at 2 : @"two"}];
+	NSDictionary* dictionary = [NSDictionary dictionaryWithObjects:values forKeys:keys];
+	NSMutableDictionary* mutable = [NSMutableDictionary dictionaryWithCapacity:5];
+	[mutable setObject:@"123" forKey:@23];
+	[mutable setObject:[NSURL URLWithString:@"http://www.apple.com"] forKey:@"foobar"];
+	[mutable setObject:@[@"a", at 12] forKey:@57];
+	[mutable setObject:dictionary forKey:@"puartist"];
+
+    [pool drain];// Set break point at this line.
+    return 0;
+}
+





More information about the lldb-commits mailing list