[Lldb-commits] [lldb] r163818 - in /lldb/trunk: include/lldb/ include/lldb/Core/ source/Core/ source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/ test/functionalities/data-formatter/rdar-11086338/

Enrico Granata egranata at apple.com
Thu Sep 13 11:27:09 PDT 2012


Author: enrico
Date: Thu Sep 13 13:27:09 2012
New Revision: 163818

URL: http://llvm.org/viewvc/llvm-project?rev=163818&view=rev
Log:
<rdar://problem/11086338> Implementing support for synthetic children generated by running C++ code instead of Python scripts ; Adding a bunch of value-generating APIs to our private code layer ; Providing synthetic children for NSArray

Added:
    lldb/trunk/test/functionalities/data-formatter/rdar-11086338/
    lldb/trunk/test/functionalities/data-formatter/rdar-11086338/Makefile
    lldb/trunk/test/functionalities/data-formatter/rdar-11086338/TestRdar11086338.py
    lldb/trunk/test/functionalities/data-formatter/rdar-11086338/main.m
Modified:
    lldb/trunk/include/lldb/Core/CXXFormatterFunctions.h
    lldb/trunk/include/lldb/Core/FormatClasses.h
    lldb/trunk/include/lldb/Core/FormatNavigator.h
    lldb/trunk/include/lldb/Core/ValueObject.h
    lldb/trunk/include/lldb/lldb-forward.h
    lldb/trunk/source/Core/CXXFormatterFunctions.cpp
    lldb/trunk/source/Core/FormatClasses.cpp
    lldb/trunk/source/Core/FormatManager.cpp
    lldb/trunk/source/Core/ValueObject.cpp
    lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h

Modified: lldb/trunk/include/lldb/Core/CXXFormatterFunctions.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/CXXFormatterFunctions.h?rev=163818&r1=163817&r2=163818&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/CXXFormatterFunctions.h (original)
+++ lldb/trunk/include/lldb/Core/CXXFormatterFunctions.h Thu Sep 13 13:27:09 2012
@@ -13,44 +13,161 @@
 #include <stdint.h>
 #include "lldb/lldb-forward.h"
 
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/FormatClasses.h"
+
+#include "clang/AST/ASTContext.h"
+
 namespace lldb_private {
     namespace formatters
     {
         
         bool
-        CodeRunning_Fetcher (ValueObject &valobj,
-                             const char* target_type,
-                             const char* selector,
-                             uint64_t &value);
+        ExtractValueFromObjCExpression (ValueObject &valobj,
+                                        const char* target_type,
+                                        const char* selector,
+                                        uint64_t &value);
+        
+        lldb::ValueObjectSP
+        CallSelectorOnObject (ValueObject &valobj,
+                              const char* return_type,
+                              const char* selector,
+                              uint64_t index);
+        
+        lldb::ValueObjectSP
+        CallSelectorOnObject (ValueObject &valobj,
+                              const char* return_type,
+                              const char* selector,
+                              const char* key);
         
         template<bool name_entries>
         bool
-        NSDictionary_SummaryProvider (ValueObject& valobj, Stream& stream);
+        NSDictionarySummaryProvider (ValueObject& valobj, Stream& stream);
         
         bool
-        NSArray_SummaryProvider (ValueObject& valobj, Stream& stream);
+        NSArraySummaryProvider (ValueObject& valobj, Stream& stream);
         
         template<bool needs_at>
         bool
-        NSData_SummaryProvider (ValueObject& valobj, Stream& stream);
+        NSDataSummaryProvider (ValueObject& valobj, Stream& stream);
         
         bool
-        NSNumber_SummaryProvider (ValueObject& valobj, Stream& stream);
+        NSNumberSummaryProvider (ValueObject& valobj, Stream& stream);
 
         bool
-        NSString_SummaryProvider (ValueObject& valobj, Stream& stream);
+        NSStringSummaryProvider (ValueObject& valobj, Stream& stream);
         
         extern template bool
-        NSDictionary_SummaryProvider<true> (ValueObject&, Stream&) ;
+        NSDictionarySummaryProvider<true> (ValueObject&, Stream&) ;
         
         extern template bool
-        NSDictionary_SummaryProvider<false> (ValueObject&, Stream&) ;
+        NSDictionarySummaryProvider<false> (ValueObject&, Stream&) ;
         
         extern template bool
-        NSData_SummaryProvider<true> (ValueObject&, Stream&) ;
+        NSDataSummaryProvider<true> (ValueObject&, Stream&) ;
         
         extern template bool
-        NSData_SummaryProvider<false> (ValueObject&, Stream&) ;
+        NSDataSummaryProvider<false> (ValueObject&, Stream&) ;
+        
+        class NSArrayMSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+        {
+        private:
+            struct DataDescriptor_32
+            {
+                uint32_t _used;
+                uint32_t _priv1 : 2 ;
+                uint32_t _size : 30;
+                uint32_t _priv2 : 2;
+                uint32_t offset : 30;
+                uint32_t _priv3;
+                uint32_t _data;
+            };
+            struct DataDescriptor_64
+            {
+                uint64_t _used;
+                uint64_t _priv1 : 2 ;
+                uint64_t _size : 62;
+                uint64_t _priv2 : 2;
+                uint64_t offset : 62;
+                uint32_t _priv3;
+                uint64_t _data;
+            };
+        public:
+            NSArrayMSyntheticFrontEnd (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
+            ~NSArrayMSyntheticFrontEnd ();
+        private:
+            ExecutionContextRef m_exe_ctx_ref;
+            uint8_t m_ptr_size;
+            DataDescriptor_32 *m_data_32;
+            DataDescriptor_64 *m_data_64;
+            ClangASTType m_id_type;
+            std::vector<lldb::ValueObjectSP> m_children;
+        };
+        
+        class NSArrayISyntheticFrontEnd : public SyntheticChildrenFrontEnd
+        {
+        public:
+            NSArrayISyntheticFrontEnd (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
+            ~NSArrayISyntheticFrontEnd ();
+        private:
+            ExecutionContextRef m_exe_ctx_ref;
+            uint8_t m_ptr_size;
+            uint64_t m_items;
+            lldb::addr_t m_data_ptr;
+            ClangASTType m_id_type;
+            std::vector<lldb::ValueObjectSP> m_children;
+        };
+        
+        class NSArrayCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+        {
+        public:
+            NSArrayCodeRunningSyntheticFrontEnd (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
+            ~NSArrayCodeRunningSyntheticFrontEnd ();
+        };
+        
+        SyntheticChildrenFrontEnd* NSArraySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
         
     }
 }

Modified: lldb/trunk/include/lldb/Core/FormatClasses.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/FormatClasses.h?rev=163818&r1=163817&r2=163818&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/FormatClasses.h (original)
+++ lldb/trunk/include/lldb/Core/FormatClasses.h Thu Sep 13 13:27:09 2012
@@ -241,7 +241,7 @@
     CalculateNumChildren() = 0;
     
     virtual lldb::ValueObjectSP
-    GetChildAtIndex (uint32_t idx, bool can_create) = 0;
+    GetChildAtIndex (uint32_t idx) = 0;
     
     virtual uint32_t
     GetIndexOfChildWithName (const ConstString &name) = 0;
@@ -556,11 +556,11 @@
         }
         
         virtual lldb::ValueObjectSP
-        GetChildAtIndex (uint32_t idx, bool can_create)
+        GetChildAtIndex (uint32_t idx)
         {
             if (idx >= filter->GetCount())
                 return lldb::ValueObjectSP();
-            return m_backend.GetSyntheticExpressionPathChild(filter->GetExpressionPathAtIndex(idx), can_create);
+            return m_backend.GetSyntheticExpressionPathChild(filter->GetExpressionPathAtIndex(idx), true);
         }
         
         virtual bool
@@ -602,6 +602,42 @@
     DISALLOW_COPY_AND_ASSIGN(TypeFilterImpl);
 };
 
+    class CXXSyntheticChildren : public SyntheticChildren
+    {
+    public:
+        typedef SyntheticChildrenFrontEnd* (*CreateFrontEndCallback) (CXXSyntheticChildren*, lldb::ValueObjectSP);
+    protected:
+        CreateFrontEndCallback m_create_callback;
+        std::string m_description;
+    public:
+        CXXSyntheticChildren(const SyntheticChildren::Flags& flags,
+                             const char* description,
+                             CreateFrontEndCallback callback) :
+        SyntheticChildren(flags),
+        m_create_callback(callback),
+        m_description(description ? description : "")
+        {
+        }
+        
+        bool
+        IsScripted()
+        {
+            return false;
+        }
+        
+        std::string
+        GetDescription();
+                
+        virtual SyntheticChildrenFrontEnd::AutoPointer
+        GetFrontEnd(ValueObject &backend)
+        {
+            return SyntheticChildrenFrontEnd::AutoPointer(m_create_callback(this, backend.GetSP()));
+        }
+        
+    private:
+        DISALLOW_COPY_AND_ASSIGN(CXXSyntheticChildren);
+    };
+
 #ifndef LLDB_DISABLE_PYTHON
 
 class TypeSyntheticImpl : public SyntheticChildren
@@ -680,7 +716,7 @@
         }
         
         virtual lldb::ValueObjectSP
-        GetChildAtIndex (uint32_t idx, bool can_create);
+        GetChildAtIndex (uint32_t idx);
         
         virtual bool
         Update()
@@ -888,11 +924,11 @@
         }
         
         virtual lldb::ValueObjectSP
-        GetChildAtIndex (uint32_t idx, bool can_create)
+        GetChildAtIndex (uint32_t idx)
         {
             if (idx >= filter->GetCount())
                 return lldb::ValueObjectSP();
-            return m_backend.GetSyntheticArrayMember(filter->GetRealIndexForIndex(idx), can_create);
+            return m_backend.GetSyntheticArrayMember(filter->GetRealIndexForIndex(idx), true);
         }
         
         virtual bool

Modified: lldb/trunk/include/lldb/Core/FormatNavigator.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/FormatNavigator.h?rev=163818&r1=163817&r2=163818&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/FormatNavigator.h (original)
+++ lldb/trunk/include/lldb/Core/FormatNavigator.h Thu Sep 13 13:27:09 2012
@@ -25,6 +25,9 @@
 #include "lldb/Core/Log.h"
 #include "lldb/Core/RegularExpression.h"
 #include "lldb/Core/ValueObject.h"
+
+#include "lldb/Symbol/ClangASTContext.h"
+
 #include "lldb/Target/ObjCLanguageRuntime.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/StackFrame.h"
@@ -578,8 +581,7 @@
                 return true;
             }
         }
-        
-        if (typePtr->isPointerType())
+        else if (typePtr->isPointerType())
         {
             if (log)
                 log->Printf("stripping pointer");
@@ -591,7 +593,13 @@
             }
         }
 
-        if (typePtr->isObjCObjectPointerType())
+        bool canBeObjCDynamic = ClangASTContext::IsPossibleDynamicType (valobj.GetClangAST(),
+                                                                        type.getAsOpaquePtr(),
+                                                                        NULL,
+                                                                        false, // no C++
+                                                                        true); // yes ObjC
+        
+        if (canBeObjCDynamic)
         {
             if (use_dynamic != lldb::eNoDynamicValues)
             {

Modified: lldb/trunk/include/lldb/Core/ValueObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=163818&r1=163817&r2=163818&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObject.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObject.h Thu Sep 13 13:27:09 2012
@@ -910,6 +910,23 @@
                      ValueObject *valobj,
                      const DumpValueObjectOptions& options);
 
+    static lldb::ValueObjectSP
+    CreateValueObjectFromExpression (const char* name,
+                                     const char* expression,
+                                     const ExecutionContext& exe_ctx);
+    
+    static lldb::ValueObjectSP
+    CreateValueObjectFromAddress (const char* name,
+                                  uint64_t address,
+                                  const ExecutionContext& exe_ctx,
+                                  ClangASTType type);
+    
+    static lldb::ValueObjectSP
+    CreateValueObjectFromData (const char* name,
+                               DataExtractor& data,
+                               const ExecutionContext& exe_ctx,
+                               ClangASTType type);
+    
     static void
     LogValueObject (Log *log,
                     ValueObject *valobj);

Modified: lldb/trunk/include/lldb/lldb-forward.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward.h?rev=163818&r1=163817&r2=163818&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-forward.h (original)
+++ lldb/trunk/include/lldb/lldb-forward.h Thu Sep 13 13:27:09 2012
@@ -85,6 +85,7 @@
 class   Connection;
 class   ConnectionFileDescriptor;
 class   ConstString;
+class   CXXSyntheticChildren;
 class   DWARFCallFrameInfo;
 class   DWARFExpression;
 class   DataBuffer;

Modified: lldb/trunk/source/Core/CXXFormatterFunctions.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/CXXFormatterFunctions.cpp?rev=163818&r1=163817&r2=163818&view=diff
==============================================================================
--- lldb/trunk/source/Core/CXXFormatterFunctions.cpp (original)
+++ lldb/trunk/source/Core/CXXFormatterFunctions.cpp Thu Sep 13 13:27:09 2012
@@ -13,8 +13,12 @@
 #define CLANG_NEEDS_THESE_ONE_DAY
 #include "clang/Basic/ConvertUTF.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/Host/Endian.h"
 #include "lldb/Target/ObjCLanguageRuntime.h"
 #include "lldb/Target/Target.h"
 
@@ -23,10 +27,10 @@
 using namespace lldb_private::formatters;
 
 bool
-lldb_private::formatters::CodeRunning_Fetcher (ValueObject &valobj,
-                                               const char* target_type,
-                                               const char* selector,
-                                               uint64_t &value)
+lldb_private::formatters::ExtractValueFromObjCExpression (ValueObject &valobj,
+                                                          const char* target_type,
+                                                          const char* selector,
+                                                          uint64_t &value)
 {
     if (!target_type || !*target_type)
         return false;
@@ -59,9 +63,81 @@
     return true;
 }
 
+lldb::ValueObjectSP
+lldb_private::formatters::CallSelectorOnObject (ValueObject &valobj,
+                                                const char* return_type,
+                                                const char* selector,
+                                                uint64_t index)
+{
+    lldb::ValueObjectSP valobj_sp;
+    if (!return_type || !*return_type)
+        return valobj_sp;
+    if (!selector || !*selector)
+        return valobj_sp;
+    StreamString expr_path_stream;
+    valobj.GetExpressionPath(expr_path_stream, false);
+    StreamString expr;
+    expr.Printf("(%s)[%s %s:%lld]",return_type,expr_path_stream.GetData(),selector,index);
+    ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
+    lldb::ValueObjectSP result_sp;
+    Target* target = exe_ctx.GetTargetPtr();
+    StackFrame* stack_frame = exe_ctx.GetFramePtr();
+    if (!target || !stack_frame)
+        return valobj_sp;
+    
+    Target::EvaluateExpressionOptions options;
+    options.SetCoerceToId(false)
+    .SetUnwindOnError(true)
+    .SetKeepInMemory(true)
+    .SetUseDynamic(lldb::eDynamicCanRunTarget);
+    
+    target->EvaluateExpression(expr.GetData(),
+                               stack_frame,
+                               valobj_sp,
+                               options);
+    return valobj_sp;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::CallSelectorOnObject (ValueObject &valobj,
+                                                const char* return_type,
+                                                const char* selector,
+                                                const char* key)
+{
+    lldb::ValueObjectSP valobj_sp;
+    if (!return_type || !*return_type)
+        return valobj_sp;
+    if (!selector || !*selector)
+        return valobj_sp;
+    if (!key || !*key)
+        return valobj_sp;
+    StreamString expr_path_stream;
+    valobj.GetExpressionPath(expr_path_stream, false);
+    StreamString expr;
+    expr.Printf("(%s)[%s %s:%s]",return_type,expr_path_stream.GetData(),selector,key);
+    ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
+    lldb::ValueObjectSP result_sp;
+    Target* target = exe_ctx.GetTargetPtr();
+    StackFrame* stack_frame = exe_ctx.GetFramePtr();
+    if (!target || !stack_frame)
+        return valobj_sp;
+    
+    Target::EvaluateExpressionOptions options;
+    options.SetCoerceToId(false)
+    .SetUnwindOnError(true)
+    .SetKeepInMemory(true)
+    .SetUseDynamic(lldb::eDynamicCanRunTarget);
+    
+    target->EvaluateExpression(expr.GetData(),
+                               stack_frame,
+                               valobj_sp,
+                               options);
+    return valobj_sp;
+}
+
 template<bool name_entries>
 bool
-lldb_private::formatters::NSDictionary_SummaryProvider (ValueObject& valobj, Stream& stream)
+lldb_private::formatters::NSDictionarySummaryProvider (ValueObject& valobj, Stream& stream)
 {
     ProcessSP process_sp = valobj.GetProcessSP();
     if (!process_sp)
@@ -115,7 +191,7 @@
             }
     else
     {
-        if (!CodeRunning_Fetcher(valobj, "int", "count", value))
+        if (!ExtractValueFromObjCExpression(valobj, "int", "count", value))
             return false;
     }
     
@@ -128,7 +204,7 @@
 }
 
 bool
-lldb_private::formatters::NSArray_SummaryProvider (ValueObject& valobj, Stream& stream)
+lldb_private::formatters::NSArraySummaryProvider (ValueObject& valobj, Stream& stream)
 {
     ProcessSP process_sp = valobj.GetProcessSP();
     if (!process_sp)
@@ -177,7 +253,7 @@
     }
     else
     {
-        if (!CodeRunning_Fetcher(valobj, "int", "count", value))
+        if (!ExtractValueFromObjCExpression(valobj, "int", "count", value))
             return false;
     }
     
@@ -189,7 +265,7 @@
 
 template<bool needs_at>
 bool
-lldb_private::formatters::NSData_SummaryProvider (ValueObject& valobj, Stream& stream)
+lldb_private::formatters::NSDataSummaryProvider (ValueObject& valobj, Stream& stream)
 {
     ProcessSP process_sp = valobj.GetProcessSP();
     if (!process_sp)
@@ -226,7 +302,7 @@
     }
     else
     {
-        if (!CodeRunning_Fetcher(valobj, "int", "length", value))
+        if (!ExtractValueFromObjCExpression(valobj, "int", "length", value))
             return false;
     }
     
@@ -240,7 +316,7 @@
 }
 
 bool
-lldb_private::formatters::NSNumber_SummaryProvider (ValueObject& valobj, Stream& stream)
+lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream& stream)
 {
     ProcessSP process_sp = valobj.GetProcessSP();
     if (!process_sp)
@@ -356,7 +432,7 @@
     }
     else
     {
-        // similar to CodeRunning_Fetcher but uses summary instead of value
+        // similar to ExtractValueFromObjCExpression but uses summary instead of value
         StreamString expr_path_stream;
         valobj.GetExpressionPath(expr_path_stream, false);
         StreamString expr;
@@ -386,7 +462,7 @@
 }
 
 bool
-lldb_private::formatters::NSString_SummaryProvider (ValueObject& valobj, Stream& stream)
+lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& stream)
 {
     ProcessSP process_sp = valobj.GetProcessSP();
     if (!process_sp)
@@ -673,14 +749,296 @@
     
 }
 
+lldb_private::formatters::NSArrayMSyntheticFrontEnd::NSArrayMSyntheticFrontEnd (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_id_type = ClangASTType(valobj_sp->GetClangAST(),valobj_sp->GetClangAST()->ObjCBuiltinIdTy.getAsOpaquePtr());
+}
+
+uint32_t
+lldb_private::formatters::NSArrayMSyntheticFrontEnd::CalculateNumChildren ()
+{
+    if (m_data_32)
+        return m_data_32->_used;
+    if (m_data_64)
+        return m_data_64->_used;
+    return 0;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetChildAtIndex (uint32_t idx)
+{
+    if (!m_data_32 && !m_data_64)
+        return lldb::ValueObjectSP();
+    if (idx >= CalculateNumChildren())
+        return lldb::ValueObjectSP();
+    lldb::addr_t object_at_idx = (m_data_32 ? m_data_32->_data : m_data_64->_data);
+    object_at_idx += (idx * m_ptr_size);
+    StreamString idx_name;
+    idx_name.Printf("[%d]",idx);
+    lldb::ValueObjectSP retval_sp = ValueObject::CreateValueObjectFromAddress(idx_name.GetData(),
+                                                                              object_at_idx,
+                                                                              m_exe_ctx_ref,
+                                                                              m_id_type);
+    m_children.push_back(retval_sp);
+    return retval_sp;
+}
+
+bool
+lldb_private::formatters::NSArrayMSyntheticFrontEnd::Update()
+{
+    m_children.clear();
+    return false;
+}
+
+static uint32_t
+ExtractIndexFromString (const char* item_name)
+{
+    if (!item_name || !*item_name)
+        return UINT32_MAX;
+    if (*item_name != '[')
+        return UINT32_MAX;
+    item_name++;
+    uint32_t idx = 0;
+    while(*item_name)
+    {
+        char x = *item_name;
+        if (x == ']')
+            break;
+        if (x < '0' || x > '9')
+            return UINT32_MAX;
+        idx = 10*idx + (x-'0');
+        item_name++;
+    }
+    return idx;
+}
+
+uint32_t
+lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+    if (!m_data_32 && !m_data_64)
+        return UINT32_MAX;
+    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::NSArrayMSyntheticFrontEnd::~NSArrayMSyntheticFrontEnd ()
+{
+    delete m_data_32;
+    m_data_32 = NULL;
+    delete m_data_64;
+    m_data_64 = NULL;
+}
+
+lldb_private::formatters::NSArrayISyntheticFrontEnd::NSArrayISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+SyntheticChildrenFrontEnd(*valobj_sp.get()),
+m_exe_ctx_ref(),
+m_ptr_size(8),
+m_items(0),
+m_data_ptr(0)
+{
+    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;
+    m_items = process_sp->ReadPointerFromMemory(data_location, error);
+    if (error.Fail())
+        return;
+    m_data_ptr = data_location+m_ptr_size;
+    m_id_type = ClangASTType(valobj_sp->GetClangAST(),valobj_sp->GetClangAST()->ObjCBuiltinIdTy.getAsOpaquePtr());
+}
+
+lldb_private::formatters::NSArrayISyntheticFrontEnd::~NSArrayISyntheticFrontEnd ()
+{
+}
+
+uint32_t
+lldb_private::formatters::NSArrayISyntheticFrontEnd::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::NSArrayISyntheticFrontEnd::CalculateNumChildren ()
+{
+    return m_items;
+}
+
+bool
+lldb_private::formatters::NSArrayISyntheticFrontEnd::Update()
+{
+    m_children.clear();
+    return false;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::NSArrayISyntheticFrontEnd::GetChildAtIndex (uint32_t idx)
+{
+    if (idx >= CalculateNumChildren())
+        return lldb::ValueObjectSP();
+    lldb::addr_t object_at_idx = m_data_ptr;
+    object_at_idx += (idx * m_ptr_size);
+    ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
+    if (!process_sp)
+        return lldb::ValueObjectSP();
+    Error error;
+    object_at_idx = process_sp->ReadPointerFromMemory(object_at_idx, error);
+    if (error.Fail())
+        return lldb::ValueObjectSP();
+    StreamString expr;
+    expr.Printf("(id)%llu",object_at_idx);
+    StreamString idx_name;
+    idx_name.Printf("[%d]",idx);
+    lldb::ValueObjectSP retval_sp = ValueObject::CreateValueObjectFromExpression(idx_name.GetData(), expr.GetData(), m_exe_ctx_ref);
+    m_children.push_back(retval_sp);
+    return retval_sp;
+}
+
+SyntheticChildrenFrontEnd* lldb_private::formatters::NSArraySyntheticFrontEndCreator (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,"__NSArrayI"))
+    {
+        return (new NSArrayISyntheticFrontEnd(valobj_sp));
+    }
+    else if (!strcmp(class_name,"__NSArrayM"))
+    {
+        return (new NSArrayMSyntheticFrontEnd(valobj_sp));
+    }
+    else
+    {
+        return (new NSArrayCodeRunningSyntheticFrontEnd(valobj_sp));
+    }
+}
+
+lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::NSArrayCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+SyntheticChildrenFrontEnd(*valobj_sp.get())
+{}
+
+uint32_t
+lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::CalculateNumChildren ()
+{
+        return 0;
+    uint64_t count = 0;
+    if (ExtractValueFromObjCExpression(m_backend, "int", "count", count))
+        return count;
+    return 0;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::GetChildAtIndex (uint32_t idx)
+{
+    StreamString idx_name;
+    idx_name.Printf("[%d]",idx);
+    lldb::ValueObjectSP valobj_sp = CallSelectorOnObject(m_backend,"id","objectAtIndex:",idx);
+    if (valobj_sp)
+        valobj_sp->SetName(ConstString(idx_name.GetData()));
+    return valobj_sp;
+}
+
+bool
+lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::Update()
+{
+    return false;
+}
+
+uint32_t
+lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+    return 0;
+}
+
+lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::~NSArrayCodeRunningSyntheticFrontEnd ()
+{}
+
+
 template bool
-lldb_private::formatters::NSDictionary_SummaryProvider<true> (ValueObject&, Stream&) ;
+lldb_private::formatters::NSDictionarySummaryProvider<true> (ValueObject&, Stream&) ;
 
 template bool
-lldb_private::formatters::NSDictionary_SummaryProvider<false> (ValueObject&, Stream&) ;
+lldb_private::formatters::NSDictionarySummaryProvider<false> (ValueObject&, Stream&) ;
 
 template bool
-lldb_private::formatters::NSData_SummaryProvider<true> (ValueObject&, Stream&) ;
+lldb_private::formatters::NSDataSummaryProvider<true> (ValueObject&, Stream&) ;
 
 template bool
-lldb_private::formatters::NSData_SummaryProvider<false> (ValueObject&, Stream&) ;
+lldb_private::formatters::NSDataSummaryProvider<false> (ValueObject&, Stream&) ;

Modified: lldb/trunk/source/Core/FormatClasses.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FormatClasses.cpp?rev=163818&r1=163817&r2=163818&view=diff
==============================================================================
--- lldb/trunk/source/Core/FormatClasses.cpp (original)
+++ lldb/trunk/source/Core/FormatClasses.cpp Thu Sep 13 13:27:09 2012
@@ -277,6 +277,20 @@
 }
 
 std::string
+CXXSyntheticChildren::GetDescription()
+{
+    StreamString sstr;
+    sstr.Printf("%s%s%s Generator at %p - %s\n",
+                Cascades() ? "" : " (not cascading)",
+                SkipsPointers() ? " (skip pointers)" : "",
+                SkipsReferences() ? " (skip references)" : "",
+                m_create_callback,
+                m_description.c_str());
+    
+    return sstr.GetString();
+}
+
+std::string
 SyntheticArrayView::GetDescription()
 {
     StreamString sstr;
@@ -329,7 +343,7 @@
 }
 
 lldb::ValueObjectSP
-TypeSyntheticImpl::FrontEnd::GetChildAtIndex (uint32_t idx, bool can_create)
+TypeSyntheticImpl::FrontEnd::GetChildAtIndex (uint32_t idx)
 {
     if (!m_wrapper_sp || !m_interpreter)
         return lldb::ValueObjectSP();

Modified: lldb/trunk/source/Core/FormatManager.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FormatManager.cpp?rev=163818&r1=163817&r2=163818&view=diff
==============================================================================
--- lldb/trunk/source/Core/FormatManager.cpp (original)
+++ lldb/trunk/source/Core/FormatManager.cpp Thu Sep 13 13:27:09 2012
@@ -907,6 +907,16 @@
                                             summary_sp);
 }
 
+static void AddCXXSynthetic  (TypeCategoryImpl::SharedPointer category_sp,
+                              CXXSyntheticChildren::CreateFrontEndCallback generator,
+                              const char* description,
+                              ConstString type_name,
+                              TypeSyntheticImpl::Flags flags)
+{
+    lldb::SyntheticChildrenSP synth_sp(new CXXSyntheticChildren(flags,description,generator));
+    category_sp->GetSyntheticNavigator()->Add(type_name,synth_sp);
+}
+
 void
 FormatManager::LoadObjCFormatters()
 {
@@ -1038,13 +1048,23 @@
     .SetShowMembersOneLiner(false)
     .SetHideItemNames(false);
 
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArray_SummaryProvider, "NSArray summary provider", ConstString("NSArray"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArray_SummaryProvider, "NSArray summary provider", ConstString("NSMutableArray"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArray_SummaryProvider, "NSArray summary provider", ConstString("__NSArrayI"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArray_SummaryProvider, "NSArray summary provider", ConstString("__NSArrayM"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArray_SummaryProvider, "NSArray summary provider", ConstString("__NSCFArray"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArray_SummaryProvider, "NSArray summary provider", ConstString("CFArrayRef"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArray_SummaryProvider, "NSArray summary provider", ConstString("CFMutableArrayRef"), appkit_flags);
+    appkit_flags.SetDontShowChildren(false);
+    
+    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("NSArray"), appkit_flags);
+    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("NSMutableArray"), appkit_flags);
+    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSArrayI"), appkit_flags);
+    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSArrayM"), appkit_flags);
+    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSCFArray"), appkit_flags);
+    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);
+
+    appkit_flags.SetDontShowChildren(true);
+    
+    AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSArrayM"), TypeSyntheticImpl::Flags());
+    AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSArrayI"), TypeSyntheticImpl::Flags());
+    AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("NSArray"), TypeSyntheticImpl::Flags());
+    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());
 
 #ifndef LLDB_DISABLE_PYTHON
     AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBag.CFBag_SummaryProvider", ConstString("CFBagRef"), appkit_flags);
@@ -1056,21 +1076,21 @@
     AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBinaryHeap.CFBinaryHeap_SummaryProvider", ConstString("__CFBinaryHeap"), appkit_flags);
 #endif // LLDB_DISABLE_PYTHON
 
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionary_SummaryProvider<false>, "NSDictionary summary provider", ConstString("NSDictionary"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionary_SummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSCFDictionary"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionary_SummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSDictionaryI"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionary_SummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSDictionaryM"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionary_SummaryProvider<true>, "NSDictionary summary provider", ConstString("CFDictionaryRef"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionary_SummaryProvider<true>, "NSDictionary summary provider", ConstString("CFMutableDictionaryRef"), appkit_flags);
-
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSString_SummaryProvider, "NSString summary provider", ConstString("NSString"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSString_SummaryProvider, "NSString summary provider", ConstString("CFStringRef"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSString_SummaryProvider, "NSString summary provider", ConstString("CFMutableStringRef"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSString_SummaryProvider, "NSString summary provider", ConstString("__NSCFConstantString"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSString_SummaryProvider, "NSString summary provider", ConstString("__NSCFString"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSString_SummaryProvider, "NSString summary provider", ConstString("NSCFConstantString"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSString_SummaryProvider, "NSString summary provider", ConstString("NSCFString"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSString_SummaryProvider, "NSString summary provider", ConstString("NSPathStore2"), 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);
+    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("__NSCFConstantString"), appkit_flags);
+    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("__NSCFString"), appkit_flags);
+    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSCFConstantString"), appkit_flags);
+    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSCFString"), appkit_flags);
+    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSPathStore2"), appkit_flags);
     
 #ifndef LLDB_DISABLE_PYTHON
     AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFString.CFAttributedString_SummaryProvider", ConstString("NSAttributedString"), appkit_flags);
@@ -1078,12 +1098,12 @@
     AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSBundle.NSBundle_SummaryProvider", ConstString("NSBundle"), appkit_flags);
 #endif // LLDB_DISABLE_PYTHON
 
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSData_SummaryProvider<false>, "NSData summary provider", ConstString("NSData"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSData_SummaryProvider<false>, "NSData summary provider", ConstString("NSConcreteData"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSData_SummaryProvider<false>, "NSData summary provider", ConstString("NSConcreteMutableData"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSData_SummaryProvider<false>, "NSData summary provider", ConstString("__NSCFData"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSData_SummaryProvider<true>, "NSData summary provider", ConstString("CFDataRef"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSData_SummaryProvider<true>, "NSData summary provider", ConstString("CFMutableDataRef"), appkit_flags);
+    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("NSData"), appkit_flags);
+    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("NSConcreteData"), appkit_flags);
+    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("NSConcreteMutableData"), appkit_flags);
+    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("__NSCFData"), appkit_flags);
+    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDataSummaryProvider<true>, "NSData summary provider", ConstString("CFDataRef"), appkit_flags);
+    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDataSummaryProvider<true>, "NSData summary provider", ConstString("CFMutableDataRef"), appkit_flags);
 
 #ifndef LLDB_DISABLE_PYTHON
     AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSException.NSException_SummaryProvider", ConstString("NSException"), appkit_flags);
@@ -1094,11 +1114,11 @@
     AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSNotification.NSNotification_SummaryProvider", ConstString("NSConcreteNotification"), appkit_flags);
 #endif // LLDB_DISABLE_PYTHON
 
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumber_SummaryProvider, "NSNumber summary provider", ConstString("NSNumber"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumber_SummaryProvider, "NSNumber summary provider", ConstString("__NSCFBoolean"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumber_SummaryProvider, "NSNumber summary provider", ConstString("__NSCFNumber"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumber_SummaryProvider, "NSNumber summary provider", ConstString("NSCFBoolean"), appkit_flags);
-    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumber_SummaryProvider, "NSNumber summary provider", ConstString("NSCFNumber"), appkit_flags);
+    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("NSNumber"), appkit_flags);
+    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("__NSCFBoolean"), appkit_flags);
+    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("__NSCFNumber"), appkit_flags);
+    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("NSCFBoolean"), appkit_flags);
+    AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("NSCFNumber"), appkit_flags);
 
 #ifndef LLDB_DISABLE_PYTHON
     AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSSet.NSSet_SummaryProvider", ConstString("NSSet"), appkit_flags);

Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=163818&r1=163817&r2=163818&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Thu Sep 13 13:27:09 2012
@@ -3990,3 +3990,67 @@
     }
     return NULL;
 }
+
+lldb::ValueObjectSP
+ValueObject::CreateValueObjectFromExpression (const char* name,
+                                              const char* expression,
+                                              const ExecutionContext& exe_ctx)
+{
+    lldb::ValueObjectSP retval_sp;
+    lldb::TargetSP target_sp(exe_ctx.GetTargetSP());
+    if (!target_sp)
+        return retval_sp;
+    if (!expression || !*expression)
+        return retval_sp;
+    target_sp->EvaluateExpression (expression,
+                                   exe_ctx.GetFrameSP().get(),
+                                   retval_sp);
+    if (retval_sp && name && *name)
+        retval_sp->SetName(ConstString(name));
+    return retval_sp;
+}
+
+lldb::ValueObjectSP
+ValueObject::CreateValueObjectFromAddress (const char* name,
+                                           uint64_t address,
+                                           const ExecutionContext& exe_ctx,
+                                           ClangASTType type)
+{
+    ClangASTType pointer_type(type.GetASTContext(),type.GetPointerType());
+    lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t)));
+    lldb::ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
+                                                                             pointer_type.GetASTContext(),
+                                                                             pointer_type.GetOpaqueQualType(),
+                                                                             ConstString(name),
+                                                                             buffer,
+                                                                             lldb::endian::InlHostByteOrder(),
+                                                                             exe_ctx.GetAddressByteSize()));
+    if (ptr_result_valobj_sp)
+    {
+        ptr_result_valobj_sp->GetValue().SetValueType(Value::eValueTypeLoadAddress);
+        Error err;
+        ptr_result_valobj_sp = ptr_result_valobj_sp->Dereference(err);
+        if (ptr_result_valobj_sp && name && *name)
+            ptr_result_valobj_sp->SetName(ConstString(name));
+    }
+    return ptr_result_valobj_sp;
+}
+
+lldb::ValueObjectSP
+ValueObject::CreateValueObjectFromData (const char* name,
+                                        DataExtractor& data,
+                                        const ExecutionContext& exe_ctx,
+                                        ClangASTType type)
+{
+    lldb::ValueObjectSP new_value_sp;
+    new_value_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
+                                                   type.GetASTContext() ,
+                                                   type.GetOpaqueQualType(),
+                                                   ConstString(name),
+                                                   data,
+                                                   LLDB_INVALID_ADDRESS);
+    new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad);
+    if (new_value_sp && name && *name)
+        new_value_sp->SetName(ConstString(name));
+    return new_value_sp;
+}

Modified: lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp?rev=163818&r1=163817&r2=163818&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp (original)
+++ lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp Thu Sep 13 13:27:09 2012
@@ -121,7 +121,7 @@
     {
         if (can_create && m_synth_filter_ap.get() != NULL)
         {
-            lldb::ValueObjectSP synth_guy = m_synth_filter_ap->GetChildAtIndex (idx, can_create);
+            lldb::ValueObjectSP synth_guy = m_synth_filter_ap->GetChildAtIndex (idx);
             if (!synth_guy)
                 return synth_guy;
             m_children_byindex[idx]= synth_guy.get();

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp?rev=163818&r1=163817&r2=163818&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp Thu Sep 13 13:27:09 2012
@@ -646,7 +646,33 @@
     
     // tagged pointer
     if (IsTaggedPointer(isa_pointer))
+    {
+        ClassDescriptorV2Tagged descriptor(valobj);
+        
+        // probably an invalid tagged pointer - say it's wrong
+        if (!descriptor.IsValid())
+            return 0;
+        
+        static const ConstString g_objc_tagged_isa_nsatom_name ("NSAtom");
+        static const ConstString g_objc_tagged_isa_nsnumber_name ("NSNumber");
+        static const ConstString g_objc_tagged_isa_nsdatets_name ("NSDateTS");
+        static const ConstString g_objc_tagged_isa_nsmanagedobject_name ("NSManagedObject");
+        static const ConstString g_objc_tagged_isa_nsdate_name ("NSDate");
+        
+        ConstString class_name_const_string = descriptor.GetClassName();
+
+        if (class_name_const_string == g_objc_tagged_isa_nsatom_name)
+            return g_objc_Tagged_ISA_NSAtom;
+        if (class_name_const_string == g_objc_tagged_isa_nsnumber_name)
+            return g_objc_Tagged_ISA_NSNumber;
+        if (class_name_const_string == g_objc_tagged_isa_nsdatets_name)
+            return g_objc_Tagged_ISA_NSDateTS;
+        if (class_name_const_string == g_objc_tagged_isa_nsmanagedobject_name)
+            return g_objc_Tagged_ISA_NSManagedObject;
+        if (class_name_const_string == g_objc_tagged_isa_nsdate_name)
+            return g_objc_Tagged_ISA_NSDate;
         return g_objc_Tagged_ISA;
+    }
 
     ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
 
@@ -679,7 +705,32 @@
         static const ConstString g_objc_tagged_isa_name ("_lldb_Tagged_ObjC_ISA");
         return g_objc_tagged_isa_name;
     }
-    
+    if (isa == g_objc_Tagged_ISA_NSAtom)
+    {
+        static const ConstString g_objc_tagged_isa_nsatom_name ("NSAtom");
+        return g_objc_tagged_isa_nsatom_name;
+    }
+    if (isa == g_objc_Tagged_ISA_NSNumber)
+    {
+        static const ConstString g_objc_tagged_isa_nsnumber_name ("NSNumber");
+        return g_objc_tagged_isa_nsnumber_name;
+    }
+    if (isa == g_objc_Tagged_ISA_NSDateTS)
+    {
+        static const ConstString g_objc_tagged_isa_nsdatets_name ("NSDateTS");
+        return g_objc_tagged_isa_nsdatets_name;
+    }
+    if (isa == g_objc_Tagged_ISA_NSManagedObject)
+    {
+        static const ConstString g_objc_tagged_isa_nsmanagedobject_name ("NSManagedObject");
+        return g_objc_tagged_isa_nsmanagedobject_name;
+    }
+    if (isa == g_objc_Tagged_ISA_NSDate)
+    {
+        static const ConstString g_objc_tagged_isa_nsdate_name ("NSDate");
+        return g_objc_tagged_isa_nsdate_name;
+    }
+
     ISAToDescriptorIterator found = m_isa_to_descriptor_cache.find(isa);
     ISAToDescriptorIterator end = m_isa_to_descriptor_cache.end();
     

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h?rev=163818&r1=163817&r2=163818&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h Thu Sep 13 13:27:09 2012
@@ -238,10 +238,18 @@
         return (isa != 0);
     }
     
-    // this is not a valid ISA in the sense that no valid
-    // class pointer can live at address 1. we use it to refer to
-    // tagged types, where the ISA must be dynamically determined
+    // none of these are valid ISAs - we use them to infer the type
+    // of tagged pointers - if we have something meaningful to say
+    // we report an actual type - otherwise, we just say tagged
+    // there is no connection between the values here and the tagged pointers map
     static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA = 1;
+
+    static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSAtom = 2;
+    static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSNumber = 3;
+    static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSDateTS = 4;
+    static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSManagedObject = 5;
+    static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSDate = 6;
+
     
     virtual ObjCLanguageRuntime::ObjCISA
     GetISA(ValueObject& valobj);

Added: lldb/trunk/test/functionalities/data-formatter/rdar-11086338/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/rdar-11086338/Makefile?rev=163818&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/rdar-11086338/Makefile (added)
+++ lldb/trunk/test/functionalities/data-formatter/rdar-11086338/Makefile Thu Sep 13 13:27:09 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-11086338/TestRdar11086338.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/rdar-11086338/TestRdar11086338.py?rev=163818&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/rdar-11086338/TestRdar11086338.py (added)
+++ lldb/trunk/test/functionalities/data-formatter/rdar-11086338/TestRdar11086338.py Thu Sep 13 13:27:09 2012
@@ -0,0 +1,82 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+import datetime
+
+class DataFormatterRdar11086338TestCase(TestBase):
+
+    mydir = os.path.join("functionalities", "data-formatter", "rdar-11086338")
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @dsym_test
+    def test_rdar11086338_with_dsym_and_run_command(self):
+        """Test that NSArray reports its synthetic children properly."""
+        self.buildDsym()
+        self.rdar11086338_tester()
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @dwarf_test
+    def test_rdar11086338_with_dwarf_and_run_command(self):
+        """Test that NSArray reports its synthetic children properly."""
+        self.buildDwarf()
+        self.rdar11086338_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 rdar11086338_tester(self):
+        """Test that NSArray 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 arr',
+                    substrs = ['@"6 objects"'])
+        self.expect('frame variable other_arr',
+                    substrs = ['@"4 objects"'])
+        self.expect('frame variable arr --ptr-depth 1',
+                    substrs = ['@"6 objects"','[0] = 0x','[1] = 0x','[2] = 0x','[3] = 0x','[4] = 0x','[5] = 0x'])
+        self.expect('frame variable other_arr --ptr-depth 1',
+                    substrs = ['@"4 objects"','[0] = 0x','[1] = 0x','[2] = 0x','[3] = 0x'])
+        self.expect('frame variable arr --ptr-depth 1 -d no-run-target',
+                    substrs = ['@"6 objects"','@"hello"','@"world"','@"this"','@"is"','@"me"','@"http://www.apple.com'])
+        self.expect('frame variable other_arr --ptr-depth 1 -d no-run-target',
+                    substrs = ['@"4 objects"','(int)5','@"a string"','@"6 objects"'])
+        self.expect('frame variable other_arr --ptr-depth 2 -d no-run-target',
+                    substrs = ['@"4 objects"','@"6 objects" {','@"hello"','@"world"','@"this"','@"is"','@"me"','@"http://www.apple.com'])
+
+
+if __name__ == '__main__':
+    import atexit
+    lldb.SBDebugger.Initialize()
+    atexit.register(lambda: lldb.SBDebugger.Terminate())
+    unittest2.main()

Added: lldb/trunk/test/functionalities/data-formatter/rdar-11086338/main.m
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/rdar-11086338/main.m?rev=163818&view=auto
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/rdar-11086338/main.m (added)
+++ lldb/trunk/test/functionalities/data-formatter/rdar-11086338/main.m Thu Sep 13 13:27:09 2012
@@ -0,0 +1,35 @@
+//===-- 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];
+
+
+	NSMutableArray* arr = [[NSMutableArray alloc] init];
+	[arr addObject:@"hello"];
+	[arr addObject:@"world"];
+	[arr addObject:@"this"];
+	[arr addObject:@"is"];
+	[arr addObject:@"me"];
+	[arr addObject:[NSURL URLWithString:@"http://www.apple.com/"]];
+
+	NSDate *aDate = [NSDate distantFuture];
+	NSValue *aValue = [NSNumber numberWithInt:5];
+	NSString *aString = @"a string";
+
+	NSArray *other_arr = [NSArray arrayWithObjects:aDate, aValue, aString, arr, nil];
+
+    [pool drain];// Set break point at this line.
+    return 0;
+}
+





More information about the lldb-commits mailing list