[Lldb-commits] [lldb] r151214 - in /lldb/trunk: include/lldb/Core/ include/lldb/Symbol/ include/lldb/Target/ source/Core/ source/Expression/ source/Plugins/SymbolFile/DWARF/ source/Symbol/ source/Target/ test/lang/objc/hidden-ivars/ test/make/

Sean Callanan scallanan at apple.com
Wed Feb 22 15:57:45 PST 2012


Author: spyffe
Date: Wed Feb 22 17:57:45 2012
New Revision: 151214

URL: http://llvm.org/viewvc/llvm-project?rev=151214&view=rev
Log:
Added support for looking up the complete type for
Objective-C classes.  This allows LLDB to find
ivars declared in class extensions in modules other
than where the debugger is currently stopped (we
already supported this when the debugger was
stopped in the same module as the definition).

This involved the following main changes:

- The ObjCLanguageRuntime now knows how to hunt
  for the authoritative version of an Objective-C
  type.  It looks for the symbol indicating a
  definition, and then gets the type from the
  module containing that symbol.

- ValueObjects now report their type with a
  potential override, and the override is set if
  the type of the ValueObject is an Objective-C
  class or pointer type that is defined somewhere
  other than the original reported type.  This
  means that "frame variable" will always use the
  complete type if one is available.

- The ClangASTSource now looks for the complete
  type when looking for ivars.  This means that
  "expr" will always use the complete type if one
  is available.

- I added a testcase that verifies that both
  "frame variable" and "expr" work.

Added:
    lldb/trunk/test/lang/objc/hidden-ivars/
    lldb/trunk/test/lang/objc/hidden-ivars/InternalDefiner.h
    lldb/trunk/test/lang/objc/hidden-ivars/InternalDefiner.m
    lldb/trunk/test/lang/objc/hidden-ivars/Makefile
    lldb/trunk/test/lang/objc/hidden-ivars/TestHiddenIvars.py
    lldb/trunk/test/lang/objc/hidden-ivars/main.m
Modified:
    lldb/trunk/include/lldb/Core/ValueObject.h
    lldb/trunk/include/lldb/Core/ValueObjectChild.h
    lldb/trunk/include/lldb/Core/ValueObjectConstResult.h
    lldb/trunk/include/lldb/Core/ValueObjectDynamicValue.h
    lldb/trunk/include/lldb/Core/ValueObjectMemory.h
    lldb/trunk/include/lldb/Core/ValueObjectRegister.h
    lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h
    lldb/trunk/include/lldb/Core/ValueObjectVariable.h
    lldb/trunk/include/lldb/Symbol/ClangASTContext.h
    lldb/trunk/include/lldb/Symbol/Type.h
    lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h
    lldb/trunk/source/Core/ValueObject.cpp
    lldb/trunk/source/Core/ValueObjectChild.cpp
    lldb/trunk/source/Core/ValueObjectConstResult.cpp
    lldb/trunk/source/Core/ValueObjectDynamicValue.cpp
    lldb/trunk/source/Core/ValueObjectMemory.cpp
    lldb/trunk/source/Core/ValueObjectRegister.cpp
    lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp
    lldb/trunk/source/Core/ValueObjectVariable.cpp
    lldb/trunk/source/Expression/ClangASTSource.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
    lldb/trunk/source/Symbol/ClangASTContext.cpp
    lldb/trunk/source/Symbol/Type.cpp
    lldb/trunk/source/Target/ObjCLanguageRuntime.cpp
    lldb/trunk/test/make/Makefile.rules

Modified: lldb/trunk/include/lldb/Core/ValueObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=151214&r1=151213&r2=151214&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObject.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObject.h Wed Feb 22 17:57:45 2012
@@ -492,6 +492,12 @@
     SetNeedsUpdate ();
     
     virtual ~ValueObject();
+    
+    clang::ASTContext *
+    GetClangAST ();
+    
+    lldb::clang_type_t
+    GetClangType ();
 
     //------------------------------------------------------------------
     // Sublasses must implement the functions below.
@@ -499,12 +505,6 @@
     virtual size_t
     GetByteSize() = 0;
 
-    virtual clang::ASTContext *
-    GetClangAST () = 0;
-
-    virtual lldb::clang_type_t
-    GetClangType () = 0;
-
     virtual lldb::ValueType
     GetValueType() const = 0;
 
@@ -1084,6 +1084,8 @@
     std::string         m_object_desc_str; // Cached result of the "object printer".  This differs from the summary
                                               // in that the summary is consed up by us, the object_desc_string is builtin.
 
+    ClangASTType        m_override_type;// If the type of the value object should be overridden, the type to impose.
+    
     ValueObjectManager *m_manager;      // This object is managed by the root object (any ValueObject that gets created
                                         // without a parent.)  The manager gets passed through all the generations of
                                         // dependent objects, and will keep the whole cluster of objects alive as long
@@ -1119,7 +1121,8 @@
                         m_is_bitfield_for_scalar:1,
                         m_is_expression_path_child:1,
                         m_is_child_at_offset:1,
-                        m_is_getting_summary:1;
+                        m_is_getting_summary:1,
+                        m_did_calculate_complete_objc_class_type:1;
     
     friend class ClangExpressionDeclMap;  // For GetValue
     friend class ClangExpressionVariable; // For SetName
@@ -1188,11 +1191,24 @@
     DataExtractor &
     GetDataExtractor ();
     
+    //------------------------------------------------------------------
+    // Sublasses must implement the functions below.
+    //------------------------------------------------------------------
+    
+    virtual clang::ASTContext *
+    GetClangASTImpl () = 0;
+    
+    virtual lldb::clang_type_t
+    GetClangTypeImpl () = 0;
+    
 private:
     //------------------------------------------------------------------
     // For ValueObject only
     //------------------------------------------------------------------
     
+    virtual ClangASTType
+    MaybeCalculateCompleteType ();
+    
     lldb::ValueObjectSP
     GetValueForExpressionPath_Impl(const char* expression_cstr,
                                    const char** first_unparsed,

Modified: lldb/trunk/include/lldb/Core/ValueObjectChild.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectChild.h?rev=151214&r1=151213&r2=151214&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObjectChild.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObjectChild.h Wed Feb 22 17:57:45 2012
@@ -50,18 +50,6 @@
         return m_bitfield_bit_offset;
     }
 
-    virtual clang::ASTContext *
-    GetClangAST ()
-    {
-        return m_clang_ast;
-    }
-
-    virtual lldb::clang_type_t
-    GetClangType ()
-    {
-        return m_clang_type;
-    }
-
     virtual lldb::ValueType
     GetValueType() const;
 
@@ -90,6 +78,18 @@
     virtual bool
     UpdateValue ();
 
+    virtual clang::ASTContext *
+    GetClangASTImpl ()
+    {
+        return m_clang_ast;
+    }
+    
+    virtual lldb::clang_type_t
+    GetClangTypeImpl ()
+    {
+        return m_clang_type;
+    }
+    
     clang::ASTContext *m_clang_ast; // The clang AST that the clang type comes from
     void *m_clang_type; // The type of the child in question within the parent (m_parent_sp)
     ConstString m_type_name;

Modified: lldb/trunk/include/lldb/Core/ValueObjectConstResult.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectConstResult.h?rev=151214&r1=151213&r2=151214&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObjectConstResult.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObjectConstResult.h Wed Feb 22 17:57:45 2012
@@ -75,12 +75,6 @@
     virtual size_t
     GetByteSize();
 
-    virtual clang::ASTContext *
-    GetClangAST ();
-
-    virtual lldb::clang_type_t
-    GetClangType ();
-
     virtual lldb::ValueType
     GetValueType() const;
 
@@ -141,6 +135,12 @@
 protected:
     virtual bool
     UpdateValue ();
+    
+    virtual clang::ASTContext *
+    GetClangASTImpl ();
+    
+    virtual lldb::clang_type_t
+    GetClangTypeImpl ();
 
     // CalculateDynamicValue doesn't change the dynamic value, since this can get
     // called at any time and you can't reliably fetch the dynamic value at any time.

Modified: lldb/trunk/include/lldb/Core/ValueObjectDynamicValue.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectDynamicValue.h?rev=151214&r1=151213&r2=151214&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObjectDynamicValue.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObjectDynamicValue.h Wed Feb 22 17:57:45 2012
@@ -33,12 +33,6 @@
         virtual size_t
         GetByteSize();
         
-        virtual clang::ASTContext *
-        GetClangAST ();
-        
-        virtual lldb::clang_type_t
-        GetClangType ();
-        
         virtual ConstString
         GetTypeName();
         
@@ -85,6 +79,12 @@
         virtual bool
         UpdateValue ();
         
+        virtual clang::ASTContext *
+        GetClangASTImpl ();
+        
+        virtual lldb::clang_type_t
+        GetClangTypeImpl ();
+        
         ClangASTType m_cast_type;
         
     private:
@@ -111,12 +111,6 @@
     virtual size_t
     GetByteSize();
 
-    virtual clang::ASTContext *
-    GetClangAST ();
-
-    virtual lldb::clang_type_t
-    GetClangType ();
-
     virtual ConstString
     GetTypeName();
 
@@ -172,6 +166,12 @@
 protected:
     virtual bool
     UpdateValue ();
+    
+    virtual clang::ASTContext *
+    GetClangASTImpl ();
+    
+    virtual lldb::clang_type_t
+    GetClangTypeImpl ();
 
     Address  m_address;  ///< The variable that this value object is based upon
     lldb::TypeSP m_type_sp;

Modified: lldb/trunk/include/lldb/Core/ValueObjectMemory.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectMemory.h?rev=151214&r1=151213&r2=151214&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObjectMemory.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObjectMemory.h Wed Feb 22 17:57:45 2012
@@ -44,12 +44,6 @@
     virtual size_t
     GetByteSize();
 
-    virtual clang::ASTContext *
-    GetClangAST ();
-
-    virtual lldb::clang_type_t
-    GetClangType ();
-
     virtual ConstString
     GetTypeName();
 
@@ -68,6 +62,12 @@
 protected:
     virtual bool
     UpdateValue ();
+    
+    virtual clang::ASTContext *
+    GetClangASTImpl ();
+    
+    virtual lldb::clang_type_t
+    GetClangTypeImpl ();
 
     Address  m_address;  ///< The variable that this value object is based upon
     lldb::TypeSP m_type_sp;

Modified: lldb/trunk/include/lldb/Core/ValueObjectRegister.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectRegister.h?rev=151214&r1=151213&r2=151214&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObjectRegister.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObjectRegister.h Wed Feb 22 17:57:45 2012
@@ -34,12 +34,6 @@
     virtual size_t
     GetByteSize();
 
-    virtual clang::ASTContext *
-    GetClangAST ();
-
-    virtual lldb::clang_type_t
-    GetClangType ();
-
     virtual lldb::ValueType
     GetValueType () const
     {
@@ -58,6 +52,12 @@
 protected:
     virtual bool
     UpdateValue ();
+    
+    virtual clang::ASTContext *
+    GetClangASTImpl ();
+    
+    virtual lldb::clang_type_t
+    GetClangTypeImpl ();
 
     lldb::RegisterContextSP m_reg_ctx_sp;
 
@@ -81,12 +81,6 @@
     virtual size_t
     GetByteSize();
 
-    virtual clang::ASTContext *
-    GetClangAST ();
-
-    virtual lldb::clang_type_t
-    GetClangType ();
-
     virtual lldb::ValueType
     GetValueType () const
     {
@@ -112,6 +106,12 @@
 protected:
     virtual bool
     UpdateValue ();
+    
+    virtual clang::ASTContext *
+    GetClangASTImpl ();
+    
+    virtual lldb::clang_type_t
+    GetClangTypeImpl ();
 
     lldb::RegisterContextSP m_reg_ctx_sp;
     const RegisterSet *m_reg_set;
@@ -139,12 +139,6 @@
     virtual size_t
     GetByteSize();
 
-    virtual clang::ASTContext *
-    GetClangAST ();
-
-    virtual lldb::clang_type_t
-    GetClangType ();
-
     virtual lldb::ValueType
     GetValueType () const
     {
@@ -166,6 +160,12 @@
 protected:
     virtual bool
     UpdateValue ();
+    
+    virtual clang::ASTContext *
+    GetClangASTImpl ();
+    
+    virtual lldb::clang_type_t
+    GetClangTypeImpl ();
 
     lldb::RegisterContextSP m_reg_ctx_sp;
     RegisterInfo m_reg_info;

Modified: lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h?rev=151214&r1=151213&r2=151214&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObjectSyntheticFilter.h Wed Feb 22 17:57:45 2012
@@ -36,13 +36,7 @@
 
     virtual size_t
     GetByteSize();
-
-    virtual clang::ASTContext *
-    GetClangAST ();
-
-    virtual lldb::clang_type_t
-    GetClangType ();
-
+    
     virtual ConstString
     GetTypeName();
 
@@ -116,6 +110,12 @@
 protected:
     virtual bool
     UpdateValue ();
+    
+    virtual clang::ASTContext *
+    GetClangASTImpl ();
+    
+    virtual lldb::clang_type_t
+    GetClangTypeImpl ();
 
     Address  m_address;  ///< The variable that this value object is based upon
     lldb::TypeSP m_type_sp;

Modified: lldb/trunk/include/lldb/Core/ValueObjectVariable.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectVariable.h?rev=151214&r1=151213&r2=151214&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObjectVariable.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObjectVariable.h Wed Feb 22 17:57:45 2012
@@ -34,12 +34,6 @@
     virtual size_t
     GetByteSize();
 
-    virtual clang::ASTContext *
-    GetClangAST ();
-
-    virtual lldb::clang_type_t
-    GetClangType ();
-
     virtual ConstString
     GetTypeName();
 
@@ -64,6 +58,12 @@
 protected:
     virtual bool
     UpdateValue ();
+    
+    virtual clang::ASTContext *
+    GetClangASTImpl ();
+    
+    virtual lldb::clang_type_t
+    GetClangTypeImpl ();
 
     lldb::VariableSP  m_variable_sp;  ///< The variable that this value object is based upon
 

Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=151214&r1=151213&r2=151214&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Wed Feb 22 17:57:45 2012
@@ -869,6 +869,13 @@
     
     static bool
     IsObjCClassType (lldb::clang_type_t clang_type);
+    
+    static bool
+    IsObjCObjectPointerType (lldb::clang_type_t clang_type, lldb::clang_type_t *target_type);
+    
+    static bool
+    GetObjCClassName (lldb::clang_type_t clang_type,
+                      std::string &class_name);
 
     static bool
     IsCharType (lldb::clang_type_t clang_type);

Modified: lldb/trunk/include/lldb/Symbol/Type.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Type.h?rev=151214&r1=151213&r2=151214&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/Type.h (original)
+++ lldb/trunk/include/lldb/Symbol/Type.h Wed Feb 22 17:57:45 2012
@@ -265,6 +265,18 @@
     
     bool
     IsRealObjCClass();
+    
+    bool
+    IsCompleteObjCClass()
+    {
+        return m_flags.is_complete_objc_class;
+    }
+    
+    void
+    SetIsCompleteObjCClass(bool is_complete_objc_class)
+    {
+        m_flags.is_complete_objc_class = is_complete_objc_class;
+    }
 
 protected:
     ConstString m_name;
@@ -276,7 +288,11 @@
     uint32_t m_byte_size;
     Declaration m_decl;
     lldb::clang_type_t m_clang_type;
-    ResolveState m_clang_type_resolve_state;
+    
+    struct Flags {
+        ResolveState    clang_type_resolve_state : 2;
+        bool            is_complete_objc_class   : 1;
+    } m_flags;
 
     Type *
     GetEncodingType ();

Modified: lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h?rev=151214&r1=151213&r2=151214&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h (original)
+++ lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h Wed Feb 22 17:57:45 2012
@@ -18,6 +18,7 @@
 // Project includes
 #include "lldb/lldb-private.h"
 #include "lldb/Core/PluginInterface.h"
+#include "lldb/Symbol/Type.h"
 #include "lldb/Target/LanguageRuntime.h"
 
 namespace lldb_private {
@@ -64,6 +65,9 @@
     void
     AddToClassNameCache (lldb::addr_t class_addr, const TypeAndOrName &class_or_type_name);
     
+    lldb::TypeSP
+    LookupInCompleteClassCache (ConstString &name);
+    
     virtual ClangUtilityFunction *
     CreateObjectChecker (const char *) = 0;
     
@@ -246,6 +250,9 @@
     typedef std::map<lldb::addr_t,TypeAndOrName> ClassNameMap;
     typedef ClassNameMap::iterator ClassNameIterator;
     ClassNameMap m_class_name_cache;
+    
+    typedef std::map<ConstString, lldb::TypeWP> CompleteClassMap;
+    CompleteClassMap m_complete_class_cache;
 
     DISALLOW_COPY_AND_ASSIGN (ObjCLanguageRuntime);
 };

Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=151214&r1=151213&r2=151214&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Wed Feb 22 17:57:45 2012
@@ -95,7 +95,8 @@
     m_is_bitfield_for_scalar(false),
     m_is_expression_path_child(false),
     m_is_child_at_offset(false),
-    m_is_getting_summary(false)
+    m_is_getting_summary(false),
+    m_did_calculate_complete_objc_class_type(false)
 {
     m_manager->ManageObject(this);
 }
@@ -141,7 +142,8 @@
     m_is_bitfield_for_scalar(false),
     m_is_expression_path_child(false),
     m_is_child_at_offset(false),
-    m_is_getting_summary(false)
+    m_is_getting_summary(false),
+    m_did_calculate_complete_objc_class_type(false)
 {
     m_manager = new ValueObjectManager();
     m_manager->ManageObject (this);
@@ -271,6 +273,103 @@
     m_value_str.clear();
 }
 
+ClangASTType
+ValueObject::MaybeCalculateCompleteType ()
+{
+    ClangASTType ret(GetClangASTImpl(), GetClangTypeImpl());
+    
+    if (m_did_calculate_complete_objc_class_type)
+    {
+        if (m_override_type.IsValid())
+            return m_override_type;
+        else
+            return ret;
+    }
+    
+    clang_type_t ast_type(GetClangTypeImpl());
+    clang_type_t class_type;
+    bool is_pointer_type;
+    
+    if (ClangASTContext::IsObjCObjectPointerType(ast_type, &class_type))
+    {
+        is_pointer_type = true;
+    }
+    else if (ClangASTContext::IsObjCClassType(ast_type))
+    {
+        is_pointer_type = false;
+        class_type = ast_type;
+    }
+    else
+    {
+        return ret;
+    }
+    
+    m_did_calculate_complete_objc_class_type = true;
+    
+    if (!class_type)
+        return ret;
+    
+    std::string class_name;
+    
+    if (!ClangASTContext::GetObjCClassName(class_type, class_name))
+        return ret;
+    
+    ProcessSP process_sp(GetUpdatePoint().GetExecutionContextRef().GetProcessSP());
+    
+    if (!process_sp)
+        return ret;
+    
+    ObjCLanguageRuntime *objc_language_runtime(process_sp->GetObjCLanguageRuntime());
+    
+    if (!objc_language_runtime)
+        return ret;
+    
+    ConstString class_name_cs(class_name.c_str());
+    
+    TypeSP complete_objc_class_type_sp = objc_language_runtime->LookupInCompleteClassCache(class_name_cs);
+    
+    if (!complete_objc_class_type_sp)
+        return ret;
+    
+    ClangASTType complete_class(complete_objc_class_type_sp->GetClangAST(),
+                                complete_objc_class_type_sp->GetClangFullType());
+    
+    if (!ClangASTContext::GetCompleteType(complete_class.GetASTContext(), 
+                                          complete_class.GetOpaqueQualType()))
+        return ret;
+    
+    if (is_pointer_type)
+    {
+        clang_type_t pointer_type = ClangASTContext::CreatePointerType(complete_class.GetASTContext(),
+                                                                       complete_class.GetOpaqueQualType());
+        
+        m_override_type = ClangASTType(complete_class.GetASTContext(),
+                                       pointer_type);
+    }
+    else
+    {
+        m_override_type = complete_class;
+    }
+    
+    return m_override_type;
+}
+
+clang::ASTContext *
+ValueObject::GetClangAST ()
+{
+    ClangASTType type = MaybeCalculateCompleteType();
+    
+    return type.GetASTContext();
+}
+
+lldb::clang_type_t
+ValueObject::GetClangType ()
+{
+    ClangASTType type = MaybeCalculateCompleteType();
+    
+    return type.GetOpaqueQualType();
+}
+
 DataExtractor &
 ValueObject::GetDataExtractor ()
 {

Modified: lldb/trunk/source/Core/ValueObjectChild.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectChild.cpp?rev=151214&r1=151213&r2=151214&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObjectChild.cpp (original)
+++ lldb/trunk/source/Core/ValueObjectChild.cpp Wed Feb 22 17:57:45 2012
@@ -65,7 +65,7 @@
 uint32_t
 ValueObjectChild::CalculateNumChildren()
 {
-    return ClangASTContext::GetNumChildren (GetClangAST (), m_clang_type, true);
+    return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true);
 }
 
 ConstString
@@ -101,7 +101,7 @@
     {
         if (parent->UpdateValueIfNeeded(false))
         {
-            m_value.SetContext(Value::eContextTypeClangType, m_clang_type);
+            m_value.SetContext(Value::eContextTypeClangType, GetClangType());
 
             // Copy the parent scalar value and the scalar value type
             m_value.GetScalar() = parent->GetValue().GetScalar();

Modified: lldb/trunk/source/Core/ValueObjectConstResult.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectConstResult.cpp?rev=151214&r1=151213&r2=151214&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObjectConstResult.cpp (original)
+++ lldb/trunk/source/Core/ValueObjectConstResult.cpp Wed Feb 22 17:57:45 2012
@@ -275,7 +275,7 @@
 }
 
 lldb::clang_type_t
-ValueObjectConstResult::GetClangType()
+ValueObjectConstResult::GetClangTypeImpl()
 {
     return m_value.GetClangType();
 }
@@ -307,7 +307,7 @@
 }
 
 clang::ASTContext *
-ValueObjectConstResult::GetClangAST ()
+ValueObjectConstResult::GetClangASTImpl ()
 {
     return m_clang_ast;
 }

Modified: lldb/trunk/source/Core/ValueObjectDynamicValue.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectDynamicValue.cpp?rev=151214&r1=151213&r2=151214&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObjectDynamicValue.cpp (original)
+++ lldb/trunk/source/Core/ValueObjectDynamicValue.cpp Wed Feb 22 17:57:45 2012
@@ -61,7 +61,7 @@
 }
 
 lldb::clang_type_t
-ValueObjectCast::GetClangType ()
+ValueObjectCast::GetClangTypeImpl ()
 {
     return m_cast_type.GetOpaqueQualType();
 }
@@ -79,7 +79,7 @@
 }
 
 clang::ASTContext *
-ValueObjectCast::GetClangAST ()
+ValueObjectCast::GetClangASTImpl ()
 {
     return m_cast_type.GetASTContext();
 }
@@ -159,7 +159,7 @@
 }
 
 lldb::clang_type_t
-ValueObjectDynamicValue::GetClangType ()
+ValueObjectDynamicValue::GetClangTypeImpl ()
 {
     if (m_type_sp)
         return m_value.GetClangType();
@@ -188,7 +188,7 @@
 }
 
 clang::ASTContext *
-ValueObjectDynamicValue::GetClangAST ()
+ValueObjectDynamicValue::GetClangASTImpl ()
 {
     const bool success = UpdateValueIfNeeded(false);
     if (success && m_type_sp)

Modified: lldb/trunk/source/Core/ValueObjectMemory.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectMemory.cpp?rev=151214&r1=151213&r2=151214&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObjectMemory.cpp (original)
+++ lldb/trunk/source/Core/ValueObjectMemory.cpp Wed Feb 22 17:57:45 2012
@@ -131,7 +131,7 @@
 }
 
 lldb::clang_type_t
-ValueObjectMemory::GetClangType ()
+ValueObjectMemory::GetClangTypeImpl ()
 {
     if (m_type_sp)
         return m_type_sp->GetClangForwardType();
@@ -158,7 +158,7 @@
 }
 
 clang::ASTContext *
-ValueObjectMemory::GetClangAST ()
+ValueObjectMemory::GetClangASTImpl ()
 {
     if (m_type_sp)
         return m_type_sp->GetClangAST();

Modified: lldb/trunk/source/Core/ValueObjectRegister.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectRegister.cpp?rev=151214&r1=151213&r2=151214&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObjectRegister.cpp (original)
+++ lldb/trunk/source/Core/ValueObjectRegister.cpp Wed Feb 22 17:57:45 2012
@@ -43,7 +43,7 @@
 }
 
 lldb::clang_type_t
-ValueObjectRegisterContext::GetClangType ()
+ValueObjectRegisterContext::GetClangTypeImpl ()
 {
     return NULL;
 }
@@ -62,7 +62,7 @@
 }
 
 clang::ASTContext *
-ValueObjectRegisterContext::GetClangAST ()
+ValueObjectRegisterContext::GetClangASTImpl ()
 {
     return NULL;
 }
@@ -140,7 +140,7 @@
 }
 
 lldb::clang_type_t
-ValueObjectRegisterSet::GetClangType ()
+ValueObjectRegisterSet::GetClangTypeImpl ()
 {
     return NULL;
 }
@@ -161,7 +161,7 @@
 }
 
 clang::ASTContext *
-ValueObjectRegisterSet::GetClangAST ()
+ValueObjectRegisterSet::GetClangASTImpl ()
 {
     return NULL;
 }
@@ -303,7 +303,7 @@
 }
 
 lldb::clang_type_t
-ValueObjectRegister::GetClangType ()
+ValueObjectRegister::GetClangTypeImpl ()
 {
     if (m_clang_type == NULL)
     {
@@ -337,7 +337,7 @@
 }
 
 clang::ASTContext *
-ValueObjectRegister::GetClangAST ()
+ValueObjectRegister::GetClangASTImpl ()
 {
     ExecutionContext exe_ctx (GetExecutionContextRef());
     Target *target = exe_ctx.GetTargetPtr();

Modified: lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp?rev=151214&r1=151213&r2=151214&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp (original)
+++ lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp Wed Feb 22 17:57:45 2012
@@ -54,7 +54,7 @@
 }
 
 lldb::clang_type_t
-ValueObjectSynthetic::GetClangType ()
+ValueObjectSynthetic::GetClangTypeImpl ()
 {
     if (m_type_sp)
         return m_value.GetClangType();
@@ -79,7 +79,7 @@
 }
 
 clang::ASTContext *
-ValueObjectSynthetic::GetClangAST ()
+ValueObjectSynthetic::GetClangASTImpl ()
 {
     const bool success = UpdateValueIfNeeded(false);
     if (success && m_type_sp)

Modified: lldb/trunk/source/Core/ValueObjectVariable.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectVariable.cpp?rev=151214&r1=151213&r2=151214&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObjectVariable.cpp (original)
+++ lldb/trunk/source/Core/ValueObjectVariable.cpp Wed Feb 22 17:57:45 2012
@@ -53,7 +53,7 @@
 }
 
 lldb::clang_type_t
-ValueObjectVariable::GetClangType ()
+ValueObjectVariable::GetClangTypeImpl ()
 {
     Type *var_type = m_variable_sp->GetType();
     if (var_type)
@@ -73,15 +73,19 @@
 
 uint32_t
 ValueObjectVariable::CalculateNumChildren()
-{
-    Type *var_type = m_variable_sp->GetType();
-    if (var_type)
-        return var_type->GetNumChildren(true);
-    return 0;
+{    
+    ClangASTType type(GetClangAST(),
+                      GetClangType());
+    
+    if (!type.IsValid())
+        return 0;
+    
+    const bool omit_empty_base_classes = true;
+    return ClangASTContext::GetNumChildren(type.GetASTContext(), type.GetOpaqueQualType(), omit_empty_base_classes);
 }
 
 clang::ASTContext *
-ValueObjectVariable::GetClangAST ()
+ValueObjectVariable::GetClangASTImpl ()
 {
     Type *var_type = m_variable_sp->GetType();
     if (var_type)
@@ -92,10 +96,13 @@
 size_t
 ValueObjectVariable::GetByteSize()
 {
-    Type *type = m_variable_sp->GetType();
-    if (type)
-        return type->GetByteSize();
-    return 0;
+    ClangASTType type(GetClangAST(),
+                      GetClangType());
+    
+    if (!type.IsValid())
+        return 0;
+    
+    return (ClangASTType::GetClangTypeBitWidth(type.GetASTContext(), type.GetOpaqueQualType()) + 7) / 8;
 }
 
 lldb::ValueType

Modified: lldb/trunk/source/Expression/ClangASTSource.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangASTSource.cpp?rev=151214&r1=151213&r2=151214&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangASTSource.cpp (original)
+++ lldb/trunk/source/Expression/ClangASTSource.cpp Wed Feb 22 17:57:45 2012
@@ -847,36 +847,29 @@
     return DeclFromParser<D>(dyn_cast<D>(parser_generic_decl.decl));
 }
 
-void
-ClangASTSource::FindObjCPropertyAndIvarDecls (NameSearchContext &context)
+static bool
+FindObjCPropertyAndIvarDeclsWithOrigin (unsigned int current_id, 
+                                        NameSearchContext &context,
+                                        clang::ASTContext &ast_context,
+                                        ClangASTImporter *ast_importer,
+                                        DeclFromUser<const ObjCInterfaceDecl> &origin_iface_decl)
 {
     lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
 
-    static unsigned int invocation_id = 0;
-    unsigned int current_id = invocation_id++;
-    
-    DeclFromParser<const ObjCInterfaceDecl> parser_iface_decl(cast<ObjCInterfaceDecl>(context.m_decl_context));
-    DeclFromUser<const ObjCInterfaceDecl> origin_iface_decl(parser_iface_decl.GetOrigin(m_ast_importer));
-    
     if (origin_iface_decl.IsInvalid())
-        return;
+        return false;
     
     std::string name_str = context.m_decl_name.getAsString();
     StringRef name(name_str.c_str());
     IdentifierInfo &name_identifier(origin_iface_decl->getASTContext().Idents.get(name));
     
-    if (log)
-        log->Printf("ClangASTSource::FindObjCPropertyAndIvarDecls[%d] on (ASTContext*)%p for '%s.%s'",
-                    current_id, 
-                    m_ast_context,
-                    parser_iface_decl->getNameAsString().c_str(), 
-                    name_str.c_str());
-    
     DeclFromUser<ObjCPropertyDecl> origin_property_decl(origin_iface_decl->FindPropertyDeclaration(&name_identifier));
     
+    bool found = false;
+    
     if (origin_property_decl.IsValid())
     {
-        DeclFromParser<ObjCPropertyDecl> parser_property_decl(origin_property_decl.Import(m_ast_importer, *m_ast_context));
+        DeclFromParser<ObjCPropertyDecl> parser_property_decl(origin_property_decl.Import(ast_importer, ast_context));
         if (parser_property_decl.IsValid())
         {
             if (log)
@@ -886,6 +879,7 @@
             }
             
             context.AddNamedDecl(parser_property_decl.decl);
+            found = true;
         }
     }
     
@@ -893,7 +887,7 @@
     
     if (origin_ivar_decl.IsValid())
     {
-        DeclFromParser<ObjCIvarDecl> parser_ivar_decl(origin_ivar_decl.Import(m_ast_importer, *m_ast_context));
+        DeclFromParser<ObjCIvarDecl> parser_ivar_decl(origin_ivar_decl.Import(ast_importer, ast_context));
         if (parser_ivar_decl.IsValid())
         {
             if (log)
@@ -903,8 +897,94 @@
             }
             
             context.AddNamedDecl(parser_ivar_decl.decl);
+            found = true;
         }
     }
+    
+    return found;
+}
+
+void
+ClangASTSource::FindObjCPropertyAndIvarDecls (NameSearchContext &context)
+{
+    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+    static unsigned int invocation_id = 0;
+    unsigned int current_id = invocation_id++;
+    
+    DeclFromParser<const ObjCInterfaceDecl> parser_iface_decl(cast<ObjCInterfaceDecl>(context.m_decl_context));
+    DeclFromUser<const ObjCInterfaceDecl> origin_iface_decl(parser_iface_decl.GetOrigin(m_ast_importer));
+
+    ConstString class_name(parser_iface_decl->getNameAsString().c_str());
+    
+    if (log)
+        log->Printf("ClangASTSource::FindObjCPropertyAndIvarDecls[%d] on (ASTContext*)%p for '%s.%s'",
+                    current_id, 
+                    m_ast_context,
+                    parser_iface_decl->getNameAsString().c_str(), 
+                    context.m_decl_name.getAsString().c_str());
+    
+    if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id, 
+                                               context, 
+                                               *m_ast_context, 
+                                               m_ast_importer, 
+                                               origin_iface_decl))
+        return;
+    
+    if (log)
+        log->Printf("CAS::FOPD[%d] couldn't find the property on origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p, searching elsewhere...",
+                    current_id,
+                    origin_iface_decl.decl, 
+                    &origin_iface_decl->getASTContext());
+    
+    SymbolContext null_sc;
+    TypeList type_list;
+    
+    lldb::ProcessSP process(m_target->GetProcessSP());
+    
+    if (!process)
+        return;
+    
+    ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
+    
+    if (!language_runtime)
+        return;
+    
+    lldb::TypeSP complete_type_sp(language_runtime->LookupInCompleteClassCache(class_name));
+    
+    if (!complete_type_sp)
+        return;
+    
+    TypeFromUser complete_type = TypeFromUser(complete_type_sp->GetClangFullType(), complete_type_sp->GetClangAST());
+    lldb::clang_type_t complete_opaque_type = complete_type.GetOpaqueQualType();
+    
+    if (!complete_opaque_type)
+        return;
+    
+    const clang::Type *complete_clang_type = QualType::getFromOpaquePtr(complete_opaque_type).getTypePtr();
+    const ObjCInterfaceType *complete_interface_type = dyn_cast<ObjCInterfaceType>(complete_clang_type);
+    
+    if (!complete_interface_type)
+        return;
+    
+    DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(complete_interface_type->getDecl());
+    
+    if (complete_iface_decl.decl == origin_iface_decl.decl)
+        return; // already checked this one
+    
+    if (log)
+        log->Printf("CAS::FOPD[%d] trying origin (ObjCInterfaceDecl*)%p/(ASTContext*)%p...",
+                    current_id,
+                    complete_iface_decl.decl, 
+                    &complete_iface_decl->getASTContext());
+    
+    
+    if (FindObjCPropertyAndIvarDeclsWithOrigin(current_id, 
+                                               context, 
+                                               *m_ast_context, 
+                                               m_ast_importer, 
+                                               complete_iface_decl))
+        return;
 }
 
 typedef llvm::DenseMap <const FieldDecl *, uint64_t> FieldOffsetMap;

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=151214&r1=151213&r2=151214&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Wed Feb 22 17:57:45 2012
@@ -4962,6 +4962,8 @@
                                              &decl, 
                                              clang_type, 
                                              Type::eResolveStateForward));
+                    
+                    type_sp->SetIsCompleteObjCClass(is_complete_objc_class);
 
 
                     // Add our type to the unique type map so we don't

Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=151214&r1=151213&r2=151214&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Wed Feb 22 17:57:45 2012
@@ -5831,6 +5831,49 @@
     return false;
 }
 
+bool
+ClangASTContext::IsObjCObjectPointerType (lldb::clang_type_t clang_type, clang_type_t *class_type)
+{
+    if (clang_type)
+    {
+        QualType qual_type (QualType::getFromOpaquePtr(clang_type));
+        if (qual_type->isObjCObjectPointerType())
+        {
+            if (class_type)
+            {
+                *class_type = NULL;
+                
+                if (!qual_type->isObjCClassType() &&
+                    !qual_type->isObjCIdType())
+                {
+                    const ObjCObjectPointerType *obj_pointer_type = dyn_cast<ObjCObjectPointerType>(qual_type);
+                    *class_type = QualType(obj_pointer_type->getInterfaceType(), 0).getAsOpaquePtr();
+                }
+            }
+            return true;
+        }
+    }
+    return false;
+}
+
+bool
+ClangASTContext::GetObjCClassName (lldb::clang_type_t clang_type,
+                                   std::string &class_name)
+{
+    if (!clang_type)
+        return false;
+        
+    const ObjCObjectType *object_type = dyn_cast<ObjCObjectType>(QualType::getFromOpaquePtr(clang_type));
+    if (!object_type)
+        return false;
+    
+    const ObjCInterfaceDecl *interface = object_type->getInterface();
+    if (!interface)
+        return false;
+    
+    class_name = interface->getNameAsString();
+    return true;
+}
 
 bool 
 ClangASTContext::IsCharType (clang_type_t clang_type)

Modified: lldb/trunk/source/Symbol/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Type.cpp?rev=151214&r1=151213&r2=151214&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/Type.cpp (original)
+++ lldb/trunk/source/Symbol/Type.cpp Wed Feb 22 17:57:45 2012
@@ -20,6 +20,7 @@
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Symbol/SymbolContextScope.h"
 #include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Symbol/SymbolVendor.h"
 #include "lldb/Symbol/Type.h"
 #include "lldb/Symbol/TypeList.h"
 
@@ -61,9 +62,10 @@
     m_encoding_uid_type (encoding_uid_type),
     m_byte_size (byte_size),
     m_decl (decl),
-    m_clang_type (clang_type),
-    m_clang_type_resolve_state (clang_type ? clang_type_resolve_state : eResolveStateUnresolved)
+    m_clang_type (clang_type)
 {
+    m_flags.clang_type_resolve_state = (clang_type ? clang_type_resolve_state : eResolveStateUnresolved);
+    m_flags.is_complete_objc_class = false;
 }
 
 Type::Type () :
@@ -76,9 +78,10 @@
     m_encoding_uid_type (eEncodingInvalid),
     m_byte_size (0),
     m_decl (),
-    m_clang_type (NULL),
-    m_clang_type_resolve_state (eResolveStateUnresolved)
+    m_clang_type (NULL)
 {
+    m_flags.clang_type_resolve_state = eResolveStateUnresolved;
+    m_flags.is_complete_objc_class = false;
 }
 
 
@@ -93,7 +96,7 @@
     m_byte_size (rhs.m_byte_size),
     m_decl (rhs.m_decl),
     m_clang_type (rhs.m_clang_type),
-    m_clang_type_resolve_state (rhs.m_clang_type_resolve_state)
+    m_flags (rhs.m_flags)
 {
 }
 
@@ -458,7 +461,7 @@
                 if (encoding_type->ResolveClangType(clang_type_resolve_state))
                 {
                     m_clang_type = encoding_type->m_clang_type;
-                    m_clang_type_resolve_state = encoding_type->m_clang_type_resolve_state;
+                    m_flags.clang_type_resolve_state = encoding_type->m_flags.clang_type_resolve_state;
                 }
                 break;
 
@@ -544,9 +547,9 @@
     }
     
     // Check if we have a forward reference to a class/struct/union/enum?
-    if (m_clang_type && m_clang_type_resolve_state < clang_type_resolve_state)
+    if (m_clang_type && m_flags.clang_type_resolve_state < clang_type_resolve_state)
     {
-        m_clang_type_resolve_state = eResolveStateFull;
+        m_flags.clang_type_resolve_state = eResolveStateFull;
         if (!ClangASTType::IsDefined (m_clang_type))
         {
             // We have a forward declaration, we need to resolve it to a complete

Modified: lldb/trunk/source/Target/ObjCLanguageRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ObjCLanguageRuntime.cpp?rev=151214&r1=151213&r2=151214&view=diff
==============================================================================
--- lldb/trunk/source/Target/ObjCLanguageRuntime.cpp (original)
+++ lldb/trunk/source/Target/ObjCLanguageRuntime.cpp Wed Feb 22 17:57:45 2012
@@ -14,6 +14,7 @@
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/Type.h"
 #include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/Target.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -94,6 +95,84 @@
     return TypeAndOrName ();
 }
 
+lldb::TypeSP
+ObjCLanguageRuntime::LookupInCompleteClassCache (ConstString &name)
+{
+    CompleteClassMap::iterator complete_class_iter = m_complete_class_cache.find(name);
+    
+    if (complete_class_iter != m_complete_class_cache.end())
+    {
+        TypeSP ret(complete_class_iter->second);
+        
+        if (!ret)
+            m_complete_class_cache.erase(name);
+        else
+            return TypeSP(complete_class_iter->second);
+    }
+    
+    ModuleList &modules = m_process->GetTarget().GetImages();
+    
+    SymbolContextList sc_list;
+    
+    modules.FindSymbolsWithNameAndType(name, eSymbolTypeObjCClass, sc_list);
+    
+    if (sc_list.GetSize() == 0)
+        return TypeSP();
+    
+    SymbolContext sc;
+    
+    sc_list.GetContextAtIndex(0, sc);
+    
+    ModuleSP module_sp(sc.module_sp);
+    
+    if (!module_sp)
+        return TypeSP();
+    
+    const SymbolContext null_sc;
+    const ClangNamespaceDecl *null_namespace_decl = NULL;
+    const bool append = false;
+    const uint32_t max_matches = UINT32_MAX;
+    TypeList types;
+    
+    module_sp->FindTypes(null_sc, 
+                         name,
+                         null_namespace_decl,
+                         append, 
+                         max_matches, 
+                         types);
+    
+    if (types.GetSize() == 1)
+    {
+        TypeSP candidate_type = types.GetTypeAtIndex(0);
+        
+        if (ClangASTContext::IsObjCClassType(candidate_type->GetClangForwardType()))
+        {
+            m_complete_class_cache[name] = TypeWP(candidate_type);
+            return candidate_type;
+        }
+        else
+        {
+            return TypeSP();
+        }
+    }
+    
+    for (uint32_t ti = 0, te = types.GetSize();
+         ti < te;
+         ++ti)
+    {
+        TypeSP candidate_type = types.GetTypeAtIndex(ti);
+        
+        if (candidate_type->IsCompleteObjCClass() &&
+            ClangASTContext::IsObjCClassType(candidate_type->GetClangForwardType()))
+        {
+            m_complete_class_cache[name] = TypeWP(candidate_type);
+            return candidate_type;                                       
+        }
+    }
+    
+    return TypeSP();
+}
+
 size_t
 ObjCLanguageRuntime::GetByteOffsetForIvar (ClangASTType &parent_qual_type, const char *ivar_name)
 {

Added: lldb/trunk/test/lang/objc/hidden-ivars/InternalDefiner.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/objc/hidden-ivars/InternalDefiner.h?rev=151214&view=auto
==============================================================================
--- lldb/trunk/test/lang/objc/hidden-ivars/InternalDefiner.h (added)
+++ lldb/trunk/test/lang/objc/hidden-ivars/InternalDefiner.h Wed Feb 22 17:57:45 2012
@@ -0,0 +1,10 @@
+#import <Foundation/Foundation.h>
+
+ at interface InternalDefiner : NSObject {
+ at public
+    int foo;
+}
+
+-(int)setBarTo:(int)newBar;
+
+ at end

Added: lldb/trunk/test/lang/objc/hidden-ivars/InternalDefiner.m
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/objc/hidden-ivars/InternalDefiner.m?rev=151214&view=auto
==============================================================================
--- lldb/trunk/test/lang/objc/hidden-ivars/InternalDefiner.m (added)
+++ lldb/trunk/test/lang/objc/hidden-ivars/InternalDefiner.m Wed Feb 22 17:57:45 2012
@@ -0,0 +1,18 @@
+#import "InternalDefiner.h"
+
+ at interface InternalDefiner () {
+    int bar;
+}
+
+ at end
+
+ at implementation InternalDefiner
+
+-(int)setBarTo:(int)newBar
+{
+    int oldBar = bar;
+    bar = newBar;
+    return oldBar;
+}
+
+ at end

Added: lldb/trunk/test/lang/objc/hidden-ivars/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/objc/hidden-ivars/Makefile?rev=151214&view=auto
==============================================================================
--- lldb/trunk/test/lang/objc/hidden-ivars/Makefile (added)
+++ lldb/trunk/test/lang/objc/hidden-ivars/Makefile Wed Feb 22 17:57:45 2012
@@ -0,0 +1,9 @@
+LEVEL = ../../../make
+
+DYLIB_NAME := libInternalDefiner
+DYLIB_OBJC_SOURCES := InternalDefiner.m
+OBJC_SOURCES := main.m
+
+LDFLAGS = -framework Foundation
+
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/test/lang/objc/hidden-ivars/TestHiddenIvars.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/objc/hidden-ivars/TestHiddenIvars.py?rev=151214&view=auto
==============================================================================
--- lldb/trunk/test/lang/objc/hidden-ivars/TestHiddenIvars.py (added)
+++ lldb/trunk/test/lang/objc/hidden-ivars/TestHiddenIvars.py Wed Feb 22 17:57:45 2012
@@ -0,0 +1,77 @@
+"""Test that hidden ivars in a shared library are visible from the main executable."""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+
+class HiddenIvarsTestCase(TestBase):
+
+    mydir = os.path.join("lang", "objc", "hidden-ivars")
+
+    def test_expr_with_dsym(self):
+        self.buildDsym()
+        self.expr()
+
+    def test_expr_with_dwarf(self):
+        self.buildDwarf()
+        self.expr()
+
+    def test_frame_variable_with_dsym(self):
+        self.buildDsym()
+        self.frame_var()
+
+    def test_frame_variable_with_dwarf(self):
+        self.buildDwarf()
+        self.frame_var()
+
+    def setUp(self):
+        # Call super's setUp().
+        TestBase.setUp(self)
+        # Find the line number to break inside main().
+        self.line = line_number('main.m', '// Set breakpoint 0 here.')
+
+    def common_setup(self):
+        exe = os.path.join(os.getcwd(), "a.out")
+        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+        # Break inside the foo function which takes a bar_ptr argument.
+        self.expect("breakpoint set -f main.m -l %d" % self.line, BREAKPOINT_CREATED,
+            startstr = "Breakpoint created")
+
+        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'])
+
+        # The breakpoint should have a hit count of 1.
+        self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
+            substrs = [' resolved, hit count = 1'])
+
+    def expr(self):
+        self.common_setup()
+
+        # This should display correctly.
+        self.expect("expression (i->bar)", VARIABLES_DISPLAYED_CORRECTLY,
+            substrs = ["= 3"])
+            
+        self.expect("expression (*i)", VARIABLES_DISPLAYED_CORRECTLY,
+            substrs = ["foo = 0", "bar = 3"])
+
+    def frame_var(self):
+        self.common_setup()
+
+        # This should display correctly.
+        self.expect("frame variable i->bar", VARIABLES_DISPLAYED_CORRECTLY,
+            substrs = ["= 3"])
+            
+        self.expect("frame variable *i", VARIABLES_DISPLAYED_CORRECTLY,
+            substrs = ["foo = 0", "bar = 3"])
+                       
+if __name__ == '__main__':
+    import atexit
+    lldb.SBDebugger.Initialize()
+    atexit.register(lambda: lldb.SBDebugger.Terminate())
+    unittest2.main()

Added: lldb/trunk/test/lang/objc/hidden-ivars/main.m
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lang/objc/hidden-ivars/main.m?rev=151214&view=auto
==============================================================================
--- lldb/trunk/test/lang/objc/hidden-ivars/main.m (added)
+++ lldb/trunk/test/lang/objc/hidden-ivars/main.m Wed Feb 22 17:57:45 2012
@@ -0,0 +1,18 @@
+#import <Foundation/Foundation.h>
+#import "InternalDefiner.h"
+
+int main(int argc, const char * argv[])
+{
+
+    @autoreleasepool {
+        
+        InternalDefiner *i = [InternalDefiner alloc];
+        
+        [i setBarTo:3];
+        
+        printf("ivar value = %d", i->foo); // Set breakpoint 0 here.
+        
+    }
+    return 0;
+}
+

Modified: lldb/trunk/test/make/Makefile.rules
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/make/Makefile.rules?rev=151214&r1=151213&r2=151214&view=diff
==============================================================================
--- lldb/trunk/test/make/Makefile.rules (original)
+++ lldb/trunk/test/make/Makefile.rules Wed Feb 22 17:57:45 2012
@@ -95,6 +95,10 @@
 	DYLIB_OBJECTS +=$(strip $(DYLIB_C_SOURCES:.c=.o))
 endif
 
+ifneq "$(strip $(DYLIB_OBJC_SOURCES))" ""
+	DYLIB_OBJECTS +=$(strip $(DYLIB_OBJC_SOURCES:.m=.o))
+endif
+
 ifneq "$(strip $(DYLIB_CXX_SOURCES))" ""
     DYLIB_OBJECTS +=$(strip $(DYLIB_CXX_SOURCES:.cpp=.o))
     CXX = $(call cxx_compiler,$(CC))





More information about the lldb-commits mailing list