[Lldb-commits] [lldb] r136695 - in /lldb/trunk: include/lldb/ include/lldb/Core/ include/lldb/Symbol/ include/lldb/Target/ source/Commands/ source/Core/ source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/ source/Symbol/ test/functionalities/data-formatter/data-formatter-categories/ test/functionalities/data-formatter/data-formatter-objc/

Enrico Granata granata.enrico at gmail.com
Tue Aug 2 10:27:39 PDT 2011


Author: enrico
Date: Tue Aug  2 12:27:39 2011
New Revision: 136695

URL: http://llvm.org/viewvc/llvm-project?rev=136695&view=rev
Log:
Fixed a bug where a variable could not be formatted in a summary if its datatype already had a custom format
Fixed a bug where Objective-C variables coming out of the expression parser could crash the Python synthetic providers:
 - expression parser output has a "frozen data" component, which is a byte-exact copy of the value (in host memory),
   if trying to read into memory based on the host address, LLDB would crash. we are now passing the correct (target)
   pointer to the Python code
Objective-C "id" variables are now formatted according to their dynamic type, if the -d option to frame variable is used:
 - Code based on the Objective-C 2.0 runtime is used to obtain this information without running code on the target

Modified:
    lldb/trunk/include/lldb/Core/Debugger.h
    lldb/trunk/include/lldb/Core/FormatManager.h
    lldb/trunk/include/lldb/Core/ValueObject.h
    lldb/trunk/include/lldb/Symbol/ClangASTType.h
    lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h
    lldb/trunk/include/lldb/lldb-enumerations.h
    lldb/trunk/source/Commands/CommandObjectExpression.cpp
    lldb/trunk/source/Core/Debugger.cpp
    lldb/trunk/source/Core/FormatClasses.cpp
    lldb/trunk/source/Core/ValueObject.cpp
    lldb/trunk/source/Core/ValueObjectChild.cpp
    lldb/trunk/source/Core/ValueObjectDynamicValue.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
    lldb/trunk/source/Symbol/ClangASTType.cpp
    lldb/trunk/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py
    lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py
    lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/main.m

Modified: lldb/trunk/include/lldb/Core/Debugger.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Debugger.h?rev=136695&r1=136694&r2=136695&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Debugger.h (original)
+++ lldb/trunk/include/lldb/Core/Debugger.h Tue Aug  2 12:27:39 2011
@@ -486,7 +486,7 @@
         {
         public:
             static bool
-            Get(ValueObject& vobj, ValueFormat::SharedPointer &entry);
+            Get(ValueObject& vobj, lldb::DynamicValueType use_dynamic, ValueFormat::SharedPointer &entry);
             
             static void
             Add(const ConstString &type, const ValueFormat::SharedPointer &entry);
@@ -509,9 +509,11 @@
 
         static bool
         GetSummaryFormat(ValueObject& vobj,
+                         lldb::DynamicValueType use_dynamic,
                          lldb::SummaryFormatSP& entry);
         static bool
         GetSyntheticFilter(ValueObject& vobj,
+                           lldb::DynamicValueType use_dynamic,
                            lldb::SyntheticChildrenSP& entry);
         
         class NamedSummaryFormats

Modified: lldb/trunk/include/lldb/Core/FormatManager.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/FormatManager.h?rev=136695&r1=136694&r2=136695&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/FormatManager.h (original)
+++ lldb/trunk/include/lldb/Core/FormatManager.h Tue Aug  2 12:27:39 2011
@@ -55,7 +55,9 @@
 #include "lldb/Core/ValueObject.h"
 #include "lldb/Interpreter/ScriptInterpreterPython.h"
 #include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
 #include "lldb/Target/Platform.h"
+#include "lldb/Target/Process.h"
 #include "lldb/Target/StackFrame.h"
 #include "lldb/Target/TargetList.h"
 
@@ -189,6 +191,8 @@
     typedef FormatMap<KeyType,ValueType> BackEndType;
     
     BackEndType m_format_map;
+    
+    std::string m_name;
         
 public:
     typedef typename BackEndType::MapType MapType;
@@ -201,8 +205,10 @@
     
     friend class FormatCategory;
 
-    FormatNavigator(IFormatChangeListener* lst = NULL) :
-    m_format_map(lst)
+    FormatNavigator(std::string name,
+                    IFormatChangeListener* lst = NULL) :
+    m_format_map(lst),
+    m_name(name)
     {
     }
     
@@ -223,11 +229,12 @@
     bool
     Get(ValueObject& vobj,
         MapValueType& entry,
+        lldb::DynamicValueType use_dynamic,
         uint32_t* why = NULL)
     {
         uint32_t value = lldb::eFormatterChoiceCriterionDirectChoice;
         clang::QualType type = clang::QualType::getFromOpaquePtr(vobj.GetClangType());
-        bool ret = Get(vobj, type, entry, value);
+        bool ret = Get(vobj, type, entry, use_dynamic, value);
         if (ret)
             entry = MapValueType(entry);
         else
@@ -267,9 +274,64 @@
         return m_format_map.Get(type, entry);
     }
     
+    bool Get_ObjC(ValueObject& vobj,
+             ObjCLanguageRuntime::ObjCISA isa,
+             MapValueType& entry,
+             uint32_t& reason)
+    {
+        LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
+        if (log)
+            log->Printf("going to an Objective-C dynamic scanning");
+        Process* process = vobj.GetUpdatePoint().GetProcessSP().get();
+        ObjCLanguageRuntime* runtime = process->GetObjCLanguageRuntime();
+        if (runtime == NULL)
+        {
+            if (log)
+                log->Printf("no valid ObjC runtime, bailing out");
+            return false;
+        }
+        if (runtime->IsValidISA(isa) == false)
+        {
+            if (log)
+                log->Printf("invalid ISA, bailing out");
+            return false;
+        }
+        ConstString name = runtime->GetActualTypeName(isa);
+        if (log)
+            log->Printf("looking for formatter for %s", name.GetCString());
+        if (Get(name.GetCString(), entry))
+        {
+            if (log)
+                log->Printf("direct match found, returning");
+            return true;
+        }
+        if (log)
+            log->Printf("no direct match");
+        ObjCLanguageRuntime::ObjCISA parent = runtime->GetParentClass(isa);
+        if (runtime->IsValidISA(parent) == false)
+        {
+            if (log)
+                log->Printf("invalid parent ISA, bailing out");
+            return false;
+        }
+        if (parent == isa)
+        {
+            if (log)
+                log->Printf("parent-child loop, bailing out");
+            return false;
+        }
+        if (Get_ObjC(vobj, parent, entry, reason))
+        {
+            reason |= lldb::eFormatterChoiceCriterionNavigatedBaseClasses;
+            return true;
+        }
+        return false;
+    }
+    
     bool Get(ValueObject& vobj,
              clang::QualType type,
              MapValueType& entry,
+             lldb::DynamicValueType use_dynamic,
              uint32_t& reason)
     {
         LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
@@ -299,7 +361,10 @@
                 log->Printf("appended bitfield info, final result is %s", name.GetCString());
         }
         if (log)
-            log->Printf("trying to get format for VO name %s of type %s",vobj.GetName().AsCString(),name.AsCString());
+            log->Printf("trying to get %s for VO name %s of type %s",
+                        m_name.c_str(),
+                        vobj.GetName().AsCString(),
+                        name.AsCString());
         if (Get(name.GetCString(), entry))
         {
             if (log)
@@ -313,17 +378,48 @@
         {
             if (log)
                 log->Printf("stripping reference");
-            if (Get(vobj,type.getNonReferenceType(),entry, reason) && !entry->m_skip_references)
+            if (Get(vobj,type.getNonReferenceType(),entry, use_dynamic, reason) && !entry->m_skip_references)
             {
                 reason |= lldb::eFormatterChoiceCriterionStrippedPointerReference;
                 return true;
             }
         }
+        if (use_dynamic != lldb::eNoDynamicValues &&
+            typePtr == vobj.GetClangAST()->ObjCBuiltinIdTy.getTypePtr())
+        {
+            if (log)
+                log->Printf("this is an ObjC 'id', let's do dynamic search");
+            Process* process = vobj.GetUpdatePoint().GetProcessSP().get();
+            ObjCLanguageRuntime* runtime = process->GetObjCLanguageRuntime();
+            if (runtime == NULL)
+            {
+                if (log)
+                    log->Printf("no valid ObjC runtime, skipping dynamic");
+            }
+            else
+            {
+                if (Get_ObjC(vobj, runtime->GetISA(vobj), entry, reason))
+                {
+                    reason |= lldb::eFormatterChoiceCriterionDynamicObjCHierarchy;
+                    return true;
+                }
+            }
+        }
+        else if (use_dynamic != lldb::eNoDynamicValues && log)
+        {
+            log->Printf("typename: %s, typePtr = %p, id = %p",
+                        name.AsCString(), typePtr, vobj.GetClangAST()->ObjCBuiltinIdTy.getTypePtr());
+        }
+        else if (log)
+        {
+            log->Printf("no dynamic");
+        }
         if (typePtr->isPointerType())
         {
             if (log)
                 log->Printf("stripping pointer");
-            if (Get(vobj, typePtr->getPointeeType(), entry, reason) && !entry->m_skip_pointers)
+            clang::QualType pointee = typePtr->getPointeeType();
+            if (Get(vobj, pointee, entry, use_dynamic, reason) && !entry->m_skip_pointers)
             {
                 reason |= lldb::eFormatterChoiceCriterionStrippedPointerReference;
                 return true;
@@ -331,6 +427,27 @@
         }
         if (typePtr->isObjCObjectPointerType())
         {
+            if (use_dynamic != lldb::eNoDynamicValues &&
+                name.GetCString() == ConstString("id").GetCString())
+            {
+                if (log)
+                    log->Printf("this is an ObjC 'id', let's do dynamic search");
+                Process* process = vobj.GetUpdatePoint().GetProcessSP().get();
+                ObjCLanguageRuntime* runtime = process->GetObjCLanguageRuntime();
+                if (runtime == NULL)
+                {
+                    if (log)
+                        log->Printf("no valid ObjC runtime, skipping dynamic");
+                }
+                else
+                {
+                    if (Get_ObjC(vobj, runtime->GetISA(vobj), entry, reason))
+                    {
+                        reason |= lldb::eFormatterChoiceCriterionDynamicObjCHierarchy;
+                        return true;
+                    }
+                }
+            }
             if (log)
                 log->Printf("stripping ObjC pointer");
             /*
@@ -343,7 +460,7 @@
             ValueObject* target = vobj.Dereference(error).get();
             if (error.Fail() || !target)
                 return false;
-            if (Get(*target, typePtr->getPointeeType(), entry, reason) && !entry->m_skip_pointers)
+            if (Get(*target, typePtr->getPointeeType(), entry, use_dynamic, reason) && !entry->m_skip_pointers)
             {
                 reason |= lldb::eFormatterChoiceCriterionStrippedPointerReference;
                 return true;
@@ -368,7 +485,7 @@
                         if (log)
                             log->Printf("got a parent class for this ObjC class");
                         clang::QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl));
-                        if (Get(vobj, ivar_qual_type, entry, reason) && entry->m_cascades)
+                        if (Get(vobj, ivar_qual_type, entry, use_dynamic, reason) && entry->m_cascades)
                         {
                             reason |= lldb::eFormatterChoiceCriterionNavigatedBaseClasses;
                             return true;
@@ -397,7 +514,7 @@
                         end = record->bases_end();
                         for (pos = record->bases_begin(); pos != end; pos++)
                         {
-                            if ((Get(vobj, pos->getType(), entry, reason)) && entry->m_cascades)
+                            if ((Get(vobj, pos->getType(), entry, use_dynamic, reason)) && entry->m_cascades)
                             {
                                 reason |= lldb::eFormatterChoiceCriterionNavigatedBaseClasses;
                                 return true;
@@ -411,7 +528,7 @@
                         end = record->vbases_end();
                         for (pos = record->vbases_begin(); pos != end; pos++)
                         {
-                            if ((Get(vobj, pos->getType(), entry, reason)) && entry->m_cascades)
+                            if ((Get(vobj, pos->getType(), entry, use_dynamic, reason)) && entry->m_cascades)
                             {
                                 reason |= lldb::eFormatterChoiceCriterionNavigatedBaseClasses;
                                 return true;
@@ -427,7 +544,7 @@
         {
             if (log)
                 log->Printf("stripping typedef");
-            if ((Get(vobj, type_tdef->getDecl()->getUnderlyingType(), entry, reason)) && entry->m_cascades)
+            if ((Get(vobj, type_tdef->getDecl()->getUnderlyingType(), entry, use_dynamic, reason)) && entry->m_cascades)
             {
                 reason |= lldb::eFormatterChoiceCriterionNavigatedTypedefs;
                 return true;
@@ -495,9 +612,9 @@
     
     FormatCategory(IFormatChangeListener* clist,
                    std::string name) :
-    m_summary_nav(new SummaryNavigator(clist)),
-    m_regex_summary_nav(new RegexSummaryNavigator(clist)),
-    m_filter_nav(new FilterNavigator(clist)),
+    m_summary_nav(new SummaryNavigator("summary",clist)),
+    m_regex_summary_nav(new RegexSummaryNavigator("regex-summary",clist)),
+    m_filter_nav(new FilterNavigator("filter",clist)),
     m_enabled(false),
     m_change_listener(clist),
     m_mutex(Mutex::eMutexTypeRecursive),
@@ -531,13 +648,14 @@
     bool
     Get(ValueObject& vobj,
         lldb::SummaryFormatSP& entry,
+        lldb::DynamicValueType use_dynamic,
         uint32_t* reason = NULL)
     {
         if (!IsEnabled())
             return false;
-        if (Summary()->Get(vobj, entry, reason))
+        if (Summary()->Get(vobj, entry, use_dynamic, reason))
             return true;
-        bool regex = RegexSummary()->Get(vobj, entry, reason);
+        bool regex = RegexSummary()->Get(vobj, entry, use_dynamic, reason);
         if (regex && reason)
             *reason |= lldb::eFormatterChoiceCriterionRegularExpressionSummary;
         return regex;
@@ -546,11 +664,12 @@
     bool
     Get(ValueObject& vobj,
         lldb::SyntheticChildrenSP& entry,
+        lldb::DynamicValueType use_dynamic,
         uint32_t* reason = NULL)
     {
         if (!IsEnabled())
             return false;
-        return (Filter()->Get(vobj, entry, reason));
+        return (Filter()->Get(vobj, entry, use_dynamic, reason));
     }
     
     // just a shortcut for Summary()->Clear; RegexSummary()->Clear()
@@ -760,43 +879,44 @@
     
     bool
     Get(ValueObject& vobj,
-        lldb::SummaryFormatSP& entry)
+        lldb::SummaryFormatSP& entry,
+        lldb::DynamicValueType use_dynamic)
     {
         Mutex::Locker(m_map_mutex);
         
-        uint32_t reason_why;
-        bool first = true;
-        
+        uint32_t reason_why;        
         ActiveCategoriesIterator begin, end = m_active_categories.end();
         
         for (begin = m_active_categories.begin(); begin != end; begin++)
         {
             FormatCategory::SharedPointer category = *begin;
             lldb::SummaryFormatSP current_format;
-            if (!category->Get(vobj, current_format, &reason_why))
+            if (!category->Get(vobj, current_format, use_dynamic, &reason_why))
                 continue;
-            if (reason_why == lldb::eFormatterChoiceCriterionDirectChoice)
-            {
-                entry = current_format;
-                return true;
-            }
-            else if (first)
-            {
-                entry = current_format;
-                first = false;
-            }
+            /*if (reason_why == lldb::eFormatterChoiceCriterionDirectChoice)
+             {
+             entry = current_format;
+             return true;
+             }
+             else if (first)
+             {
+             entry = current_format;
+             first = false;
+             }*/
+            entry = current_format;
+            return true;
         }
-        return !first;
+        return false;
     }
     
     bool
     Get(ValueObject& vobj,
-        lldb::SyntheticChildrenSP& entry)
+        lldb::SyntheticChildrenSP& entry,
+        lldb::DynamicValueType use_dynamic)
     {
         Mutex::Locker(m_map_mutex);
         
         uint32_t reason_why;
-        bool first = true;
         
         ActiveCategoriesIterator begin, end = m_active_categories.end();
         
@@ -804,9 +924,9 @@
         {
             FormatCategory::SharedPointer category = *begin;
             lldb::SyntheticChildrenSP current_format;
-            if (!category->Get(vobj, current_format, &reason_why))
+            if (!category->Get(vobj, current_format, use_dynamic, &reason_why))
                 continue;
-            if (reason_why == lldb::eFormatterChoiceCriterionDirectChoice)
+            /*if (reason_why == lldb::eFormatterChoiceCriterionDirectChoice)
             {
                 entry = current_format;
                 return true;
@@ -815,9 +935,11 @@
             {
                 entry = current_format;
                 first = false;
-            }
+            }*/
+            entry = current_format;
+            return true;
         }
-        return !first;
+        return false;
     }
 
 };
@@ -847,7 +969,7 @@
     typedef bool (*CategoryCallback)(void*, const char*, const FormatCategory::SharedPointer&);
     
     FormatManager() : 
-    m_value_nav(this),
+    m_value_nav("format",this),
     m_named_summaries_map(this),
     m_last_revision(0),
     m_categories_map(this)
@@ -941,15 +1063,17 @@
     
     bool
     Get(ValueObject& vobj,
-        lldb::SummaryFormatSP& entry)
+        lldb::SummaryFormatSP& entry,
+        lldb::DynamicValueType use_dynamic)
     {
-        return m_categories_map.Get(vobj, entry);
+        return m_categories_map.Get(vobj, entry, use_dynamic);
     }
     bool
     Get(ValueObject& vobj,
-        lldb::SyntheticChildrenSP& entry)
+        lldb::SyntheticChildrenSP& entry,
+        lldb::DynamicValueType use_dynamic)
     {
-        return m_categories_map.Get(vobj, entry);
+        return m_categories_map.Get(vobj, entry, use_dynamic);
     }
 
     static bool

Modified: lldb/trunk/include/lldb/Core/ValueObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=136695&r1=136694&r2=136695&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObject.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObject.h Tue Aug  2 12:27:39 2011
@@ -443,6 +443,9 @@
 
     virtual const char *
     GetValueAsCString ();
+    
+    virtual unsigned long long
+    GetValueAsUnsigned();
 
     virtual bool
     SetValueFromCString (const char *value_str);
@@ -513,8 +516,11 @@
     bool
     UpdateValueIfNeeded (bool update_format = true);
     
+    bool
+    UpdateValueIfNeeded (lldb::DynamicValueType use_dynamic, bool update_format = true);
+    
     void
-    UpdateFormatsIfNeeded();
+    UpdateFormatsIfNeeded(lldb::DynamicValueType use_dynamic = lldb::eNoDynamicValues);
 
     DataExtractor &
     GetDataExtractor ();
@@ -640,6 +646,18 @@
     }
     
     void
+    SetIsExpressionResult(bool expr)
+    {
+        m_is_expression_result = expr;
+    }
+    
+    bool
+    GetIsExpressionResult()
+    {
+        return m_is_expression_result;
+    }
+    
+    void
     SetFormat (lldb::Format format)
     {
         if (format != m_format)
@@ -677,7 +695,7 @@
     lldb::SummaryFormatSP
     GetSummaryFormat()
     {
-        UpdateFormatsIfNeeded();
+        UpdateFormatsIfNeeded(m_last_format_mgr_dynamic);
         if (HasCustomSummaryFormat())
             return m_forced_summary_format;
         return m_last_summary_format;
@@ -744,6 +762,7 @@
 
     lldb::Format                m_format;
     uint32_t                    m_last_format_mgr_revision;
+    lldb::DynamicValueType      m_last_format_mgr_dynamic;
     lldb::SummaryFormatSP       m_last_summary_format;
     lldb::SummaryFormatSP       m_forced_summary_format;
     lldb::ValueFormatSP         m_last_value_format;
@@ -759,7 +778,8 @@
                         m_is_array_item_for_pointer:1,
                         m_is_bitfield_for_scalar:1,
                         m_is_expression_path_child:1,
-                        m_is_child_at_offset:1;
+                        m_is_child_at_offset:1,
+                        m_is_expression_result:1;
     
     // used to prevent endless looping into GetpPrintableRepresentation()
     uint32_t            m_dump_printable_counter;

Modified: lldb/trunk/include/lldb/Symbol/ClangASTType.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTType.h?rev=136695&r1=136694&r2=136695&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTType.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTType.h Tue Aug  2 12:27:39 2011
@@ -98,7 +98,8 @@
     GetMinimumLanguage ();
 
     static lldb::LanguageType
-    GetMinimumLanguage (lldb::clang_type_t clang_type);
+    GetMinimumLanguage (clang::ASTContext *ctx,
+                        lldb::clang_type_t clang_type);
 
     void
     DumpValue (ExecutionContext *exe_ctx,

Modified: lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h?rev=136695&r1=136694&r2=136695&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h (original)
+++ lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h Tue Aug  2 12:27:39 2011
@@ -72,6 +72,20 @@
     {
         return eObjC_VersionUnknown;
     }
+        
+    typedef lldb::addr_t ObjCISA;
+    
+    virtual bool
+    IsValidISA(ObjCISA isa) = 0;
+    
+    virtual ObjCISA
+    GetISA(ValueObject& valobj) = 0;
+    
+    virtual ConstString
+    GetActualTypeName(ObjCISA isa) = 0;
+    
+    virtual ObjCISA
+    GetParentClass(ObjCISA isa) = 0;
     
     // Finds the byte offset of the child_type ivar in parent_type.  If it can't find the
     // offset, returns LLDB_INVALID_IVAR_OFFSET.

Modified: lldb/trunk/include/lldb/lldb-enumerations.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=136695&r1=136694&r2=136695&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-enumerations.h (original)
+++ lldb/trunk/include/lldb/lldb-enumerations.h Tue Aug  2 12:27:39 2011
@@ -505,7 +505,8 @@
         eFormatterChoiceCriterionStrippedPointerReference =      0x00000001,
         eFormatterChoiceCriterionNavigatedTypedefs =             0x00000002,
         eFormatterChoiceCriterionNavigatedBaseClasses =          0x00000004,
-        eFormatterChoiceCriterionRegularExpressionSummary =      0x00000008
+        eFormatterChoiceCriterionRegularExpressionSummary =      0x00000008,
+        eFormatterChoiceCriterionDynamicObjCHierarchy =          0x00000010
     } FormatterChoiceCriterion;
     
     //----------------------------------------------------------------------

Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=136695&r1=136694&r2=136695&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Tue Aug  2 12:27:39 2011
@@ -321,6 +321,9 @@
         {
             if (result_valobj_sp->GetError().Success())
             {
+                
+                result_valobj_sp.get()->SetIsExpressionResult(true);
+                
                 if (m_options.format != eFormatDefault)
                     result_valobj_sp->SetFormat (m_options.format);
 

Modified: lldb/trunk/source/Core/Debugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=136695&r1=136694&r2=136695&view=diff
==============================================================================
--- lldb/trunk/source/Core/Debugger.cpp (original)
+++ lldb/trunk/source/Core/Debugger.cpp Tue Aug  2 12:27:39 2011
@@ -1010,22 +1010,35 @@
                                 if (!vobj)
                                     break;
                                 
+                                if (log)
+                                    log->Printf("initial string: %s",var_name_begin);
+                                
                                 // check for *var and *svar
                                 if (*var_name_begin == '*')
                                 {
                                     do_deref_pointer = true;
                                     var_name_begin++;
                                 }
+                                
+                                if (log)
+                                    log->Printf("initial string: %s",var_name_begin);
+                                
                                 if (*var_name_begin == 's')
                                 {
                                     vobj = vobj->GetSyntheticValue(lldb::eUseSyntheticFilter).get();
                                     var_name_begin++;
                                 }
                                 
+                                if (log)
+                                    log->Printf("initial string: %s",var_name_begin);
+                                
                                 // should be a 'v' by now
                                 if (*var_name_begin != 'v')
                                     break;
                                 
+                                if (log)
+                                    log->Printf("initial string: %s",var_name_begin);
+                                                                
                                 ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
                                                                                   ValueObject::eDereference : ValueObject::eNothing);
                                 ValueObject::GetValueForExpressionPathOptions options;
@@ -1765,9 +1778,9 @@
 }
 
 bool
-Debugger::Formatting::ValueFormats::Get(ValueObject& vobj, ValueFormat::SharedPointer &entry)
+Debugger::Formatting::ValueFormats::Get(ValueObject& vobj, lldb::DynamicValueType use_dynamic, ValueFormat::SharedPointer &entry)
 {
-    return GetFormatManager().Value().Get(vobj,entry);
+    return GetFormatManager().Value().Get(vobj,entry, use_dynamic);
 }
 
 void
@@ -1808,15 +1821,17 @@
 
 bool
 Debugger::Formatting::GetSummaryFormat(ValueObject& vobj,
+                                       lldb::DynamicValueType use_dynamic,
                                        lldb::SummaryFormatSP& entry)
 {
-    return GetFormatManager().Get(vobj, entry);
+    return GetFormatManager().Get(vobj, entry, use_dynamic);
 }
 bool
 Debugger::Formatting::GetSyntheticFilter(ValueObject& vobj,
+                                         lldb::DynamicValueType use_dynamic,
                                          lldb::SyntheticChildrenSP& entry)
 {
-    return GetFormatManager().Get(vobj, entry);
+    return GetFormatManager().Get(vobj, entry, use_dynamic);
 }
 
 bool

Modified: lldb/trunk/source/Core/FormatClasses.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FormatClasses.cpp?rev=136695&r1=136694&r2=136695&view=diff
==============================================================================
--- lldb/trunk/source/Core/FormatClasses.cpp (original)
+++ lldb/trunk/source/Core/FormatClasses.cpp Tue Aug  2 12:27:39 2011
@@ -21,6 +21,7 @@
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/FormatClasses.h"
 #include "lldb/Core/StreamString.h"
+#include "lldb/Core/ValueObjectConstResult.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Symbol/ClangASTType.h"
 #include "lldb/Target/StackFrame.h"
@@ -121,8 +122,29 @@
 std::string
 ScriptSummaryFormat::FormatObject(lldb::ValueObjectSP object)
 {
+    lldb::ValueObjectSP target_object;
+    if (object->GetIsExpressionResult() &&
+        ClangASTContext::IsPointerType(object->GetClangType()) &&
+        object->GetValue().GetValueType() == Value::eValueTypeHostAddress)
+    {
+        // when using the expression parser, an additional layer of "frozen data"
+        // can be created, which is basically a byte-exact copy of the data returned
+        // by the expression, but in host memory. because Python code might need to read
+        // into the object memory in non-obvious ways, we need to hand it the target version
+        // of the expression output
+        lldb::addr_t tgt_address = object->GetValueAsUnsigned();
+        target_object = ValueObjectConstResult::Create (object->GetExecutionContextScope(),
+                                                        object->GetClangAST(),
+                                                        object->GetClangType(),
+                                                        object->GetName(),
+                                                        tgt_address,
+                                                        eAddressTypeLoad,
+                                                        object->GetUpdatePoint().GetProcessSP()->GetAddressByteSize());
+    }
+    else
+        target_object = object;
     return std::string(ScriptInterpreterPython::CallPythonScriptFunction(m_function_name.c_str(),
-                                                                         object).c_str());
+                                                                         target_object).c_str());
 }
 
 std::string
@@ -171,7 +193,26 @@
         return;
     }
     
-    m_interpreter = be->GetUpdatePoint().GetTargetSP()->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
+    if (be->GetIsExpressionResult() &&
+        ClangASTContext::IsPointerType(be->GetClangType()) &&
+        be->GetValue().GetValueType() == Value::eValueTypeHostAddress)
+    {
+        // when using the expression parser, an additional layer of "frozen data"
+        // can be created, which is basically a byte-exact copy of the data returned
+        // by the expression, but in host memory. because Python code might need to read
+        // into the object memory in non-obvious ways, we need to hand it the target version
+        // of the expression output
+        lldb::addr_t tgt_address = be->GetValueAsUnsigned();
+        m_backend = ValueObjectConstResult::Create (be->GetExecutionContextScope(),
+                                                    be->GetClangAST(),
+                                                    be->GetClangType(),
+                                                    be->GetName(),
+                                                    tgt_address,
+                                                    eAddressTypeLoad,
+                                                    be->GetUpdatePoint().GetProcessSP()->GetAddressByteSize());
+    }
+
+    m_interpreter = m_backend->GetUpdatePoint().GetTargetSP()->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
     
     if (m_interpreter == NULL)
         m_wrapper = NULL;

Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=136695&r1=136694&r2=136695&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Tue Aug  2 12:27:39 2011
@@ -39,6 +39,7 @@
 
 #include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/LanguageRuntime.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/Target.h"
@@ -76,6 +77,7 @@
     m_deref_valobj(NULL),
     m_format (eFormatDefault),
     m_last_format_mgr_revision(0),
+    m_last_format_mgr_dynamic(lldb::eNoDynamicValues),
     m_last_summary_format(),
     m_forced_summary_format(),
     m_last_value_format(),
@@ -91,6 +93,7 @@
     m_is_bitfield_for_scalar(false),
     m_is_expression_path_child(false),
     m_is_child_at_offset(false),
+    m_is_expression_result(false),
     m_dump_printable_counter(0)
 {
     m_manager->ManageObject(this);
@@ -120,6 +123,7 @@
     m_deref_valobj(NULL),
     m_format (eFormatDefault),
     m_last_format_mgr_revision(0),
+    m_last_format_mgr_dynamic(lldb::eNoDynamicValues),
     m_last_summary_format(),
     m_forced_summary_format(),
     m_last_value_format(),
@@ -135,6 +139,7 @@
     m_is_bitfield_for_scalar(false),
     m_is_expression_path_child(false),
     m_is_child_at_offset(false),
+    m_is_expression_result(false),
     m_dump_printable_counter(0)
 {
     m_manager = new ValueObjectManager();
@@ -151,9 +156,15 @@
 bool
 ValueObject::UpdateValueIfNeeded (bool update_format)
 {
+    return UpdateValueIfNeeded(m_last_format_mgr_dynamic, update_format);
+}
+
+bool
+ValueObject::UpdateValueIfNeeded (lldb::DynamicValueType use_dynamic, bool update_format)
+{
     
     if (update_format)
-        UpdateFormatsIfNeeded();
+        UpdateFormatsIfNeeded(use_dynamic);
     
     // If this is a constant value, then our success is predicated on whether
     // we have an error or not
@@ -204,7 +215,7 @@
 }
 
 void
-ValueObject::UpdateFormatsIfNeeded()
+ValueObject::UpdateFormatsIfNeeded(lldb::DynamicValueType use_dynamic)
 {
     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
     if (log)
@@ -217,7 +228,8 @@
         ClearCustomSummaryFormat();
         m_summary_str.clear();
     }
-    if (m_last_format_mgr_revision != Debugger::Formatting::ValueFormats::GetCurrentRevision())
+    if ( (m_last_format_mgr_revision != Debugger::Formatting::ValueFormats::GetCurrentRevision()) ||
+          m_last_format_mgr_dynamic != use_dynamic)
     {
         if (m_last_summary_format.get())
             m_last_summary_format.reset((StringSummaryFormat*)NULL);
@@ -228,11 +240,12 @@
 
         m_synthetic_value = NULL;
         
-        Debugger::Formatting::ValueFormats::Get(*this, m_last_value_format);
-        Debugger::Formatting::GetSummaryFormat(*this, m_last_summary_format);
-        Debugger::Formatting::GetSyntheticFilter(*this, m_last_synthetic_filter);
+        Debugger::Formatting::ValueFormats::Get(*this, use_dynamic, m_last_value_format);
+        Debugger::Formatting::GetSummaryFormat(*this, use_dynamic, m_last_summary_format);
+        Debugger::Formatting::GetSyntheticFilter(*this, use_dynamic, m_last_synthetic_filter);
 
         m_last_format_mgr_revision = Debugger::Formatting::ValueFormats::GetCurrentRevision();
+        m_last_format_mgr_dynamic = use_dynamic;
 
         ClearUserVisibleData();
     }
@@ -241,14 +254,14 @@
 DataExtractor &
 ValueObject::GetDataExtractor ()
 {
-    UpdateValueIfNeeded();
+    UpdateValueIfNeeded(false);
     return m_data;
 }
 
 const Error &
 ValueObject::GetError()
 {
-    UpdateValueIfNeeded();
+    UpdateValueIfNeeded(false);
     return m_error;
 }
 
@@ -261,7 +274,7 @@
 const char *
 ValueObject::GetLocationAsCString ()
 {
-    if (UpdateValueIfNeeded())
+    if (UpdateValueIfNeeded(false))
     {
         if (m_location_str.empty())
         {
@@ -358,7 +371,7 @@
     ValueObjectSP child_sp;
     // We may need to update our value if we are dynamic
     if (IsPossibleDynamicType ())
-        UpdateValueIfNeeded();
+        UpdateValueIfNeeded(false);
     if (idx < GetNumChildren())
     {
         // Check if we have already made the child value object?
@@ -395,7 +408,7 @@
 
     // We may need to update our value if we are dynamic
     if (IsPossibleDynamicType ())
-        UpdateValueIfNeeded();
+        UpdateValueIfNeeded(false);
 
     std::vector<uint32_t> child_indexes;
     clang::ASTContext *clang_ast = GetClangAST();
@@ -519,7 +532,7 @@
 const char *
 ValueObject::GetSummaryAsCString ()
 {
-    if (UpdateValueIfNeeded ())
+    if (UpdateValueIfNeeded (m_last_format_mgr_dynamic, true))
     {        
         if (m_summary_str.empty())
         {
@@ -775,7 +788,7 @@
 ValueObject::GetObjectDescription ()
 {
     
-    if (!UpdateValueIfNeeded ())
+    if (!UpdateValueIfNeeded (m_last_format_mgr_dynamic, true))
         return NULL;
 
     if (!m_object_desc_str.empty())
@@ -826,7 +839,7 @@
     // If our byte size is zero this is an aggregate type that has children
     if (ClangASTContext::IsAggregateType (GetClangType()) == false)
     {
-        if (UpdateValueIfNeeded())
+        if (UpdateValueIfNeeded(true))
         {
             if (m_value_str.empty())
             {
@@ -841,7 +854,7 @@
                         clang_type_t clang_type = GetClangType ();
                         if (clang_type)
                         {
-                            if (m_last_value_format)
+                            if (m_format == lldb::eFormatDefault && m_last_value_format)
                             {
                                 m_value_str = m_last_value_format->FormatObject(GetSP());
                             }
@@ -905,6 +918,24 @@
     return m_value_str.c_str();
 }
 
+// if > 8bytes, 0 is returned. this method should mostly be used
+// to read address values out of pointers
+unsigned long long
+ValueObject::GetValueAsUnsigned()
+{
+    // If our byte size is zero this is an aggregate type that has children
+    if (ClangASTContext::IsAggregateType (GetClangType()) == false)
+    {
+        if (UpdateValueIfNeeded(true))
+        {
+            uint32_t offset = 0;
+            return m_data.GetMaxU64(&offset,
+                                    m_data.GetByteSize());
+        }
+    }
+    return 0;
+}
+
 // this call should only return pointers to data that needs no special memory management
 // (either because they are hardcoded strings, or because they are backed by some other
 // object); returning any new()-ed or malloc()-ed data here, will lead to leaks!
@@ -1092,7 +1123,7 @@
 addr_t
 ValueObject::GetAddressOf (AddressType &address_type, bool scalar_is_load_address)
 {
-    if (!UpdateValueIfNeeded())
+    if (!UpdateValueIfNeeded(false))
         return LLDB_INVALID_ADDRESS;
         
     switch (m_value.GetValueType())
@@ -1124,7 +1155,7 @@
     lldb::addr_t address = LLDB_INVALID_ADDRESS;
     address_type = eAddressTypeInvalid;
     
-    if (!UpdateValueIfNeeded())
+    if (!UpdateValueIfNeeded(false))
         return address;
         
     switch (m_value.GetValueType())
@@ -1161,7 +1192,7 @@
 {
     // Make sure our value is up to date first so that our location and location
     // type is valid.
-    if (!UpdateValueIfNeeded())
+    if (!UpdateValueIfNeeded(false))
         return false;
 
     uint32_t count = 0;
@@ -1256,7 +1287,8 @@
 lldb::LanguageType
 ValueObject::GetObjectRuntimeLanguage ()
 {
-    return ClangASTType::GetMinimumLanguage (GetClangType());
+    return ClangASTType::GetMinimumLanguage (GetClangAST(),
+                                             GetClangType());
 }
 
 void
@@ -1521,7 +1553,7 @@
     if (use_synthetic == lldb::eNoSyntheticFilter)
         return;
     
-    UpdateFormatsIfNeeded();
+    UpdateFormatsIfNeeded(m_last_format_mgr_dynamic);
     
     if (m_last_synthetic_filter.get() == NULL)
         return;
@@ -1601,7 +1633,7 @@
     if (use_synthetic == lldb::eNoSyntheticFilter)
         return GetSP();
     
-    UpdateFormatsIfNeeded();
+    UpdateFormatsIfNeeded(m_last_format_mgr_dynamic);
     
     if (m_last_synthetic_filter.get() == NULL)
         return GetSP();
@@ -2537,7 +2569,7 @@
 {
     if (valobj)
     {
-        bool update_success = valobj->UpdateValueIfNeeded ();
+        bool update_success = valobj->UpdateValueIfNeeded (use_dynamic, true);
 
         if (update_success && use_dynamic != lldb::eNoDynamicValues)
         {
@@ -2566,7 +2598,33 @@
 
             // Always show the type for the top level items.
             if (show_types || (curr_depth == 0 && !flat_output))
-                s.Printf("(%s) ", valobj->GetTypeName().AsCString("<invalid type>"));
+            {
+                s.Printf("(%s", valobj->GetTypeName().AsCString("<invalid type>"));
+                if (use_dynamic != lldb::eNoDynamicValues &&
+                    strcmp(valobj->GetTypeName().AsCString("NULL"), "id") == 0)
+                {
+                    Process* process = valobj->GetUpdatePoint().GetProcessSP().get();
+                    if (process == NULL)
+                        s.Printf(") ");
+                    else
+                    {
+                        ObjCLanguageRuntime *runtime = process->GetObjCLanguageRuntime();
+                        if (runtime == NULL)
+                            s.Printf(") ");
+                        else
+                        {
+                            ObjCLanguageRuntime::ObjCISA isa = runtime->GetISA(*valobj);
+                            if (!runtime->IsValidISA(isa))
+                                s.Printf(") ");
+                            else
+                                s.Printf(", dynamic type: %s) ",
+                                         runtime->GetActualTypeName(isa).GetCString());
+                        }
+                    }
+                }
+                else
+                    s.Printf(") ");
+            }
 
 
             if (flat_output)
@@ -2758,7 +2816,7 @@
 {
     ValueObjectSP valobj_sp;
     
-    if (UpdateValueIfNeeded() && m_error.Success())
+    if (UpdateValueIfNeeded(false) && m_error.Success())
     {
         ExecutionContextScope *exe_scope = GetExecutionContextScope();
         if (exe_scope)
@@ -2957,7 +3015,6 @@
     return valobj_sp;
 }
 
-
 ValueObject::EvaluationPoint::EvaluationPoint () :
     m_thread_id (LLDB_INVALID_UID),
     m_stop_id (0)

Modified: lldb/trunk/source/Core/ValueObjectChild.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectChild.cpp?rev=136695&r1=136694&r2=136695&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObjectChild.cpp (original)
+++ lldb/trunk/source/Core/ValueObjectChild.cpp Tue Aug  2 12:27:39 2011
@@ -97,7 +97,7 @@
     ValueObject* parent = m_parent;
     if (parent)
     {
-        if (parent->UpdateValueIfNeeded())
+        if (parent->UpdateValueIfNeeded(false))
         {
             m_value.SetContext(Value::eContextTypeClangType, m_clang_type);
 

Modified: lldb/trunk/source/Core/ValueObjectDynamicValue.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectDynamicValue.cpp?rev=136695&r1=136694&r2=136695&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObjectDynamicValue.cpp (original)
+++ lldb/trunk/source/Core/ValueObjectDynamicValue.cpp Tue Aug  2 12:27:39 2011
@@ -60,7 +60,7 @@
 ConstString
 ValueObjectDynamicValue::GetTypeName()
 {
-    const bool success = UpdateValueIfNeeded();
+    const bool success = UpdateValueIfNeeded(false);
     if (success && m_type_sp)
         return ClangASTType::GetConstTypeName (GetClangType());
     else
@@ -70,7 +70,7 @@
 uint32_t
 ValueObjectDynamicValue::CalculateNumChildren()
 {
-    const bool success = UpdateValueIfNeeded();
+    const bool success = UpdateValueIfNeeded(false);
     if (success && m_type_sp)
         return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true);
     else
@@ -90,7 +90,7 @@
 size_t
 ValueObjectDynamicValue::GetByteSize()
 {
-    const bool success = UpdateValueIfNeeded();
+    const bool success = UpdateValueIfNeeded(false);
     if (success && m_type_sp)
         return m_value.GetValueByteSize(GetClangAST(), NULL);
     else
@@ -109,7 +109,7 @@
     SetValueIsValid (false);
     m_error.Clear();
 
-    if (!m_parent->UpdateValueIfNeeded())
+    if (!m_parent->UpdateValueIfNeeded(false))
     {
         // The dynamic value failed to get an error, pass the error along
         if (m_error.Success() && m_parent->GetError().Fail())

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h?rev=136695&r1=136694&r2=136695&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h Tue Aug  2 12:27:39 2011
@@ -63,6 +63,30 @@
     virtual lldb::ThreadPlanSP
     GetStepThroughTrampolinePlan (Thread &thread, bool stop_others);
     
+    virtual bool
+    IsValidISA(ObjCISA isa)
+    {
+        return false;
+    }
+    
+    virtual ObjCISA
+    GetISA(ValueObject& valobj)
+    {
+        return 0;
+    }
+    
+    virtual ConstString
+    GetActualTypeName(ObjCISA isa)
+    {
+        return ConstString(NULL);
+    }
+    
+    virtual ObjCISA
+    GetParentClass(ObjCISA isa)
+    {
+        return 0;
+    }
+    
     //------------------------------------------------------------------
     // Static Functions
     //------------------------------------------------------------------

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h?rev=136695&r1=136694&r2=136695&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h Tue Aug  2 12:27:39 2011
@@ -72,6 +72,31 @@
     {
         return eAppleObjC_V1;
     }
+    
+    virtual bool
+    IsValidISA(ObjCISA isa)
+    {
+        return false;
+    }
+    
+    virtual ObjCISA
+    GetISA(ValueObject& valobj)
+    {
+        return 0;
+    }
+    
+    virtual ConstString
+    GetActualTypeName(ObjCISA isa)
+    {
+        return ConstString(NULL);
+    }
+    
+    virtual ObjCISA
+    GetParentClass(ObjCISA isa)
+    {
+        return 0;
+    }
+
 protected:
     
 private:

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=136695&r1=136694&r2=136695&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp Tue Aug  2 12:27:39 2011
@@ -563,4 +563,90 @@
     return ivar_offset;
 }
 
+lldb_private::ObjCLanguageRuntime::ObjCISA
+AppleObjCRuntimeV2::GetISA(ValueObject& valobj)
+{
+    if (ClangASTType::GetMinimumLanguage(valobj.GetClangAST(),valobj.GetClangType()) != lldb::eLanguageTypeObjC)
+        return 0;
+    
+    uint32_t offset = 0;
+    uint64_t isa_pointer = valobj.GetDataExtractor().GetPointer(&offset);
+    
+    uint8_t pointer_size = valobj.GetUpdatePoint().GetProcessSP()->GetAddressByteSize();
+    
+    Error error;
+    lldb_private::ObjCLanguageRuntime::ObjCISA isa = 
+    valobj.GetUpdatePoint().GetProcessSP()->ReadUnsignedIntegerFromMemory(isa_pointer,
+                                                                          pointer_size,
+                                                                          0,
+                                                                          error);
+    return isa;
+}
+
+ConstString
+AppleObjCRuntimeV2::GetActualTypeName(lldb_private::ObjCLanguageRuntime::ObjCISA isa)
+{
+    if (!IsValidISA(isa))
+        return ConstString(NULL);
+    
+    uint8_t pointer_size = m_process->GetAddressByteSize();
+    Error error;
+    lldb::addr_t rw_pointer = isa + (4 * pointer_size);
+    //printf("rw_pointer: %llx\n", rw_pointer);
+    
+    uint64_t data_pointer =  m_process->ReadUnsignedIntegerFromMemory(rw_pointer,
+                                                                      pointer_size,
+                                                                      0,
+                                                                      error);
+    if (error.Fail())
+        return ConstString("unknown");
+    
+    data_pointer += 8;
+    //printf("data_pointer: %llx\n", data_pointer);
+    uint64_t ro_pointer = m_process->ReadUnsignedIntegerFromMemory(data_pointer,
+                                                                   pointer_size,
+                                                                   0,
+                                                                   error);
+    if (error.Fail())
+        return ConstString("unknown");
+    
+    ro_pointer += 12;
+    if (pointer_size == 8)
+        ro_pointer += 4;
+    ro_pointer += pointer_size;
+    //printf("ro_pointer: %llx\n", ro_pointer);
+    uint64_t name_pointer = m_process->ReadUnsignedIntegerFromMemory(ro_pointer,
+                                                                     pointer_size,
+                                                                     0,
+                                                                     error);
+    if (error.Fail())
+        return ConstString("unknown");
+    
+    //printf("name_pointer: %llx\n", name_pointer);
+    char* cstr = new char[512];
+    if (m_process->ReadCStringFromMemory(name_pointer, cstr, 512) > 0)
+        return ConstString(cstr);
+    else
+        return ConstString("unknown");
+}
+
+lldb_private::ObjCLanguageRuntime::ObjCISA
+AppleObjCRuntimeV2::GetParentClass(lldb_private::ObjCLanguageRuntime::ObjCISA isa)
+{
+    if (!IsValidISA(isa))
+        return 0;
+    
+    uint8_t pointer_size = m_process->GetAddressByteSize();
+    Error error;
+    lldb::addr_t parent_pointer = isa + pointer_size;
+    //printf("rw_pointer: %llx\n", rw_pointer);
+    
+    uint64_t parent_isa =  m_process->ReadUnsignedIntegerFromMemory(parent_pointer,
+                                                                    pointer_size,
+                                                                    0,
+                                                                    error);
+    if (error.Fail())
+        return 0;
+    return parent_isa;
+}
 

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=136695&r1=136694&r2=136695&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h Tue Aug  2 12:27:39 2011
@@ -76,7 +76,21 @@
 
     virtual size_t
     GetByteOffsetForIvar (ClangASTType &parent_qual_type, const char *ivar_name);
-
+    
+    virtual bool
+    IsValidISA(ObjCISA isa)
+    {
+        return (isa != 0);
+    }
+    
+    virtual ObjCISA
+    GetISA(ValueObject& valobj);   
+    
+    virtual ConstString
+    GetActualTypeName(ObjCISA isa);
+    
+    virtual ObjCISA
+    GetParentClass(ObjCISA isa);
     
 protected:
     

Modified: lldb/trunk/source/Symbol/ClangASTType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTType.cpp?rev=136695&r1=136694&r2=136695&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTType.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTType.cpp Tue Aug  2 12:27:39 2011
@@ -159,11 +159,13 @@
 lldb::LanguageType
 ClangASTType::GetMinimumLanguage ()
 {
-    return ClangASTType::GetMinimumLanguage (m_type);
+    return ClangASTType::GetMinimumLanguage (m_ast,
+                                             m_type);
 }
 
 lldb::LanguageType
-ClangASTType::GetMinimumLanguage (lldb::clang_type_t clang_type)
+ClangASTType::GetMinimumLanguage (clang::ASTContext *ctx,
+                                  lldb::clang_type_t clang_type)
 {
     if (clang_type == NULL)
         return lldb::eLanguageTypeC;
@@ -182,6 +184,8 @@
             return lldb::eLanguageTypeObjC;
         if (pointee_type->isObjCClassType())
             return lldb::eLanguageTypeObjC;
+        if (pointee_type.getTypePtr() == ctx->ObjCBuiltinIdTy.getTypePtr())
+            return lldb::eLanguageTypeObjC;
     }
     else
     {
@@ -238,7 +242,8 @@
             }
             break;
         case clang::Type::Typedef:
-            return GetMinimumLanguage(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
+            return GetMinimumLanguage(ctx,
+                                      llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
         }
     }
     return lldb::eLanguageTypeC;

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py?rev=136695&r1=136694&r2=136695&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-categories/TestDataFormatterCategories.py Tue Aug  2 12:27:39 2011
@@ -286,7 +286,7 @@
                     substrs = ['ACircle',
                                'ARectangle',
                                'ACircle',
-                               'ARectangleStar'])
+                               'ARectangle'])
 
         # Check that abruptly deleting an enabled category does not crash us
         self.runCmd("type category delete RectangleCategory")

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py?rev=136695&r1=136694&r2=136695&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py Tue Aug  2 12:27:39 2011
@@ -164,7 +164,7 @@
                                'inline = ',
                                'explicit = ',
                                'content = ',
-                               'a very much boring task to write a string this way!!\\xe4\\x8c\\xb3'])
+                               'a very much boring task to write a string this way!!\\xcf\\x83'])
         
         self.expect('frame variable str10 -P 1 -Y',
                     substrs = ['mutable =',
@@ -215,7 +215,7 @@
         self.expect('frame variable str8',
                     substrs = ['hasVeryLongExtensionThisTime'])
         self.expect('frame variable str9',
-                    substrs = ['a very much boring task to write a string this way!!\\xe4\\x8c\\xb3'])
+                    substrs = ['a very much boring task to write a string this way!!\\xcf\\x83'])
         self.expect('frame variable str10',
                     substrs = ['This is a Unicode string \\xcf\\x83 number 4 right here'])
         self.expect('frame variable str11',
@@ -224,6 +224,25 @@
                     substrs = ['a.out'])        
         self.expect('frame variable str12',
                     substrs = ['Process Name:  a.out Process Id:'])
+        self.expect('frame variable dyn_test', matching=False,
+                    substrs = ['Process Name:  a.out Process Id:'])
+        self.expect('frame variable dyn_test -d run-target',
+                    substrs = ['(id, dynamic type:',
+                               'Process Name:  a.out Process Id:'])
+
+            
+        # check that we can format stuff out of the expression parser
+        self.expect('expression ((id)@"Hello")', matching=False,
+                    substrs = ['Hello'])
+            
+        self.expect('expression -d true -- ((id)@"Hello")',
+        substrs = ['Hello'])
+
+        self.expect('expr -d true -- label1',
+            substrs = ['Process Name'])
+
+        self.expect('expr -d true -- @"Hello"',
+            substrs = ['Hello'])
 
 if __name__ == '__main__':
     import atexit

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/main.m
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/main.m?rev=136695&r1=136694&r2=136695&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/main.m (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/main.m Tue Aug  2 12:27:39 2011
@@ -117,6 +117,8 @@
     NSString *processID = [NSString stringWithFormat:@"%d", [[NSProcessInfo processInfo] processIdentifier]];
     NSString *str12 = [NSString stringWithFormat:@"%@ %@ %@ %@", label1, processName, label2, processID];
     
+    id dyn_test = str12;
+    
     // Set break point at this line.
     [pool drain];
     return 0;





More information about the lldb-commits mailing list