[Lldb-commits] [lldb] r164333 - in /lldb/trunk: include/lldb/Core/ValueObject.h include/lldb/Expression/ClangASTSource.h include/lldb/Symbol/ClangASTImporter.h source/Expression/ClangASTSource.cpp source/Expression/ClangExpressionDeclMap.cpp source/Symbol/ClangASTImporter.cpp source/Symbol/ClangASTType.cpp

Sean Callanan scallanan at apple.com
Thu Sep 20 16:21:16 PDT 2012


Author: spyffe
Date: Thu Sep 20 18:21:16 2012
New Revision: 164333

URL: http://llvm.org/viewvc/llvm-project?rev=164333&view=rev
Log:
Fixed a problem where persistent variables did
not correctly store the contents of Objective-C
classes.  This was due to a combination of
factors:

  1) Types were only being completed if we were
     looking inside them for specific ivars
     (using FindExternalVisibleDeclsByName). 
     We now look the complete type up at every
     FindExternalLexicalDecls.

  2) Even if the types were completed properly,
     ValueObjectConstResult overrode the type
     of every ValueObject using the complete type
     for its class from the debug information.
     Superclasses of complete classes are not
     guaranteed to be complete.  Although "frame
     variable" uses the debug information,
     the expression parser does now piece together
     complete types at every level (as described
     in Bullet 1), so I provided a way for the
     expression parser to prevent overriding.

  3) Type sizes were being miscomputed by
     ClangASTContext.  It ignored the ISA pointer
     and only counted fields.  We now correctly
     count the ISA in the size of an object.

<rdar://problem/12315386>

Modified:
    lldb/trunk/include/lldb/Core/ValueObject.h
    lldb/trunk/include/lldb/Expression/ClangASTSource.h
    lldb/trunk/include/lldb/Symbol/ClangASTImporter.h
    lldb/trunk/source/Expression/ClangASTSource.cpp
    lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
    lldb/trunk/source/Symbol/ClangASTImporter.cpp
    lldb/trunk/source/Symbol/ClangASTType.cpp

Modified: lldb/trunk/include/lldb/Core/ValueObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=164333&r1=164332&r2=164333&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObject.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObject.h Thu Sep 20 18:21:16 2012
@@ -1065,6 +1065,12 @@
         return m_address_type_of_ptr_or_ref_children;
     }
     
+    void
+    SetHasCompleteType()
+    {
+        m_did_calculate_complete_objc_class_type = true;
+    }
+    
 protected:
     typedef ClusterManager<ValueObject> ValueObjectManager;
     

Modified: lldb/trunk/include/lldb/Expression/ClangASTSource.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangASTSource.h?rev=164333&r1=164332&r2=164333&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangASTSource.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangASTSource.h Thu Sep 20 18:21:16 2012
@@ -321,6 +321,20 @@
     
 protected:
     //------------------------------------------------------------------
+    /// Look for the complete version of an Objective-C interface, and
+    /// return it if found.
+    ///
+    /// @param[in] interface_decl
+    ///     An ObjCInterfaceDecl that may not be the complete one.
+    ///
+    /// @return
+    ///     NULL if the complete interface couldn't be found;
+    ///     the complete interface otherwise.
+    //------------------------------------------------------------------
+    clang::ObjCInterfaceDecl *
+    GetCompleteObjCInterface (clang::ObjCInterfaceDecl *interface_decl);
+    
+    //------------------------------------------------------------------
     /// Find all entities matching a given name in a given module,
     /// using a NameSearchContext to make Decls for them.
     ///

Modified: lldb/trunk/include/lldb/Symbol/ClangASTImporter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTImporter.h?rev=164333&r1=164332&r2=164333&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTImporter.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTImporter.h Thu Sep 20 18:21:16 2012
@@ -80,6 +80,9 @@
         return origin.Valid();
     }
     
+    void
+    SetDeclOrigin (const clang::Decl *decl, clang::Decl *original_decl);
+    
     uint64_t
     GetDeclMetadata (const clang::Decl *decl);
     

Modified: lldb/trunk/source/Expression/ClangASTSource.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangASTSource.cpp?rev=164333&r1=164332&r2=164333&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangASTSource.cpp (original)
+++ lldb/trunk/source/Expression/ClangASTSource.cpp Thu Sep 20 18:21:16 2012
@@ -313,8 +313,45 @@
     }
 }
 
+clang::ObjCInterfaceDecl *
+ClangASTSource::GetCompleteObjCInterface (clang::ObjCInterfaceDecl *interface_decl)
+{
+    lldb::ProcessSP process(m_target->GetProcessSP());
+    
+    if (!process)
+        return NULL;
+    
+    ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
+    
+    if (!language_runtime)
+        return NULL;
+        
+    ConstString class_name(interface_decl->getNameAsString().c_str());
+    
+    lldb::TypeSP complete_type_sp(language_runtime->LookupInCompleteClassCache(class_name));
+    
+    if (!complete_type_sp)
+        return NULL;
+    
+    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 NULL;
+    
+    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 NULL;
+    
+    ObjCInterfaceDecl *complete_iface_decl(complete_interface_type->getDecl());
+    
+    return complete_iface_decl;
+}
+
 clang::ExternalLoadResult
-ClangASTSource::FindExternalLexicalDecls (const DeclContext *decl_context, 
+ClangASTSource::FindExternalLexicalDecls (const DeclContext *decl_context,
                                           bool (*predicate)(Decl::Kind),
                                           llvm::SmallVectorImpl<Decl*> &decls)
 {    
@@ -364,6 +401,19 @@
         ASTDumper(original_decl).ToLog(log, "    ");
     }
     
+    if (ObjCInterfaceDecl *original_iface_decl = dyn_cast<ObjCInterfaceDecl>(original_decl))
+    {
+        ObjCInterfaceDecl *complete_iface_decl = GetCompleteObjCInterface(original_iface_decl);
+        
+        if (complete_iface_decl && (complete_iface_decl != original_iface_decl))
+        {
+            original_decl = complete_iface_decl;
+            original_ctx = &complete_iface_decl->getASTContext();
+            
+            m_ast_importer->SetDeclOrigin(context_decl, original_iface_decl);
+        }
+    }
+    
     if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original_decl))
     {
         ExternalASTSource *external_source = original_ctx->getExternalSource();
@@ -1132,26 +1182,12 @@
     
     do
     {
-        // First see if any other debug information has this property/ivar.
-        
-        lldb::TypeSP complete_type_sp(language_runtime->LookupInCompleteClassCache(class_name));
-        
-        if (!complete_type_sp)
-            break;
-        
-        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)
-            break;
-        
-        const clang::Type *complete_clang_type = QualType::getFromOpaquePtr(complete_opaque_type).getTypePtr();
-        const ObjCInterfaceType *complete_interface_type = dyn_cast<ObjCInterfaceType>(complete_clang_type);
+        ObjCInterfaceDecl *complete_interface_decl = GetCompleteObjCInterface(const_cast<ObjCInterfaceDecl*>(parser_iface_decl.decl));
         
-        if (!complete_interface_type)
+        if (!complete_interface_decl)
             break;
         
-        DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(complete_interface_type->getDecl());
+        DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(complete_interface_decl);
         
         if (complete_iface_decl.decl == origin_iface_decl.decl)
             break; // already checked this one

Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=164333&r1=164332&r2=164333&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Thu Sep 20 18:21:16 2012
@@ -480,6 +480,8 @@
     if (!var_sp)
         return false;
     
+    var_sp->m_frozen_sp->SetHasCompleteType();
+    
     if (is_result)
         var_sp->m_flags |= ClangExpressionVariable::EVNeedsFreezeDry;
     else

Modified: lldb/trunk/source/Symbol/ClangASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTImporter.cpp?rev=164333&r1=164332&r2=164333&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTImporter.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTImporter.cpp Thu Sep 20 18:21:16 2012
@@ -269,7 +269,27 @@
         return DeclOrigin();
 }
 
-void 
+void
+ClangASTImporter::SetDeclOrigin (const clang::Decl *decl, clang::Decl *original_decl)
+{
+    ASTContextMetadataSP context_md = GetContextMetadata(&decl->getASTContext());
+    
+    OriginMap &origins = context_md->m_origins;
+    
+    OriginMap::iterator iter = origins.find(decl);
+    
+    if (iter != origins.end())
+    {
+        iter->second.decl = original_decl;
+        iter->second.ctx = &original_decl->getASTContext();
+    }
+    else
+    {
+        origins[decl] = DeclOrigin(&original_decl->getASTContext(), original_decl);
+    }
+}
+
+void
 ClangASTImporter::RegisterNamespaceMap(const clang::NamespaceDecl *decl, 
                                        NamespaceMapSP &namespace_map)
 {

Modified: lldb/trunk/source/Symbol/ClangASTType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTType.cpp?rev=164333&r1=164332&r2=164333&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTType.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTType.cpp Thu Sep 20 18:21:16 2012
@@ -1629,7 +1629,13 @@
     if (ClangASTContext::GetCompleteType (ast_context, opaque_clang_qual_type))
     {
         clang::QualType qual_type(clang::QualType::getFromOpaquePtr(opaque_clang_qual_type));
-        return (ast_context->getTypeSize (qual_type) + 7) / 8;
+        
+        uint32_t byte_size = (ast_context->getTypeSize (qual_type) + 7) / 8;
+        
+        if (ClangASTContext::IsObjCClassType(opaque_clang_qual_type))
+            byte_size += ast_context->getTypeSize(ast_context->ObjCBuiltinClassTy) / 8; // isa
+        
+        return byte_size;
     }
     return 0;
 }





More information about the lldb-commits mailing list