diff options
-rw-r--r-- | lldb/include/lldb/Core/ValueObject.h | 6 | ||||
-rw-r--r-- | lldb/include/lldb/Expression/ClangASTSource.h | 14 | ||||
-rw-r--r-- | lldb/include/lldb/Symbol/ClangASTImporter.h | 3 | ||||
-rw-r--r-- | lldb/source/Expression/ClangASTSource.cpp | 72 | ||||
-rw-r--r-- | lldb/source/Expression/ClangExpressionDeclMap.cpp | 2 | ||||
-rw-r--r-- | lldb/source/Symbol/ClangASTImporter.cpp | 22 | ||||
-rw-r--r-- | lldb/source/Symbol/ClangASTType.cpp | 8 |
7 files changed, 107 insertions, 20 deletions
diff --git a/lldb/include/lldb/Core/ValueObject.h b/lldb/include/lldb/Core/ValueObject.h index 1946300a128..c2f33a545f2 100644 --- a/lldb/include/lldb/Core/ValueObject.h +++ b/lldb/include/lldb/Core/ValueObject.h @@ -1065,6 +1065,12 @@ public: return m_address_type_of_ptr_or_ref_children; } + void + SetHasCompleteType() + { + m_did_calculate_complete_objc_class_type = true; + } + protected: typedef ClusterManager<ValueObject> ValueObjectManager; diff --git a/lldb/include/lldb/Expression/ClangASTSource.h b/lldb/include/lldb/Expression/ClangASTSource.h index b9e71d97d80..27190346d27 100644 --- a/lldb/include/lldb/Expression/ClangASTSource.h +++ b/lldb/include/lldb/Expression/ClangASTSource.h @@ -321,6 +321,20 @@ public: 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. /// diff --git a/lldb/include/lldb/Symbol/ClangASTImporter.h b/lldb/include/lldb/Symbol/ClangASTImporter.h index 6b68489f373..3fd1bd8f4c1 100644 --- a/lldb/include/lldb/Symbol/ClangASTImporter.h +++ b/lldb/include/lldb/Symbol/ClangASTImporter.h @@ -80,6 +80,9 @@ public: return origin.Valid(); } + void + SetDeclOrigin (const clang::Decl *decl, clang::Decl *original_decl); + uint64_t GetDeclMetadata (const clang::Decl *decl); diff --git a/lldb/source/Expression/ClangASTSource.cpp b/lldb/source/Expression/ClangASTSource.cpp index 80a9ea3dd6a..3d3a6f61ca7 100644 --- a/lldb/source/Expression/ClangASTSource.cpp +++ b/lldb/source/Expression/ClangASTSource.cpp @@ -313,8 +313,45 @@ ClangASTSource::CompleteType (clang::ObjCInterfaceDecl *interface_decl) } } +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 @@ ClangASTSource::FindExternalLexicalDecls (const DeclContext *decl_context, 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 @@ ClangASTSource::FindObjCPropertyAndIvarDecls (NameSearchContext &context) 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 diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index 6e597655ec8..33910279bc7 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -480,6 +480,8 @@ ClangExpressionDeclMap::AddPersistentVariable if (!var_sp) return false; + var_sp->m_frozen_sp->SetHasCompleteType(); + if (is_result) var_sp->m_flags |= ClangExpressionVariable::EVNeedsFreezeDry; else diff --git a/lldb/source/Symbol/ClangASTImporter.cpp b/lldb/source/Symbol/ClangASTImporter.cpp index fe4c2aa3d65..40434384cc6 100644 --- a/lldb/source/Symbol/ClangASTImporter.cpp +++ b/lldb/source/Symbol/ClangASTImporter.cpp @@ -269,7 +269,27 @@ ClangASTImporter::GetDeclOrigin(const clang::Decl *decl) 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) { diff --git a/lldb/source/Symbol/ClangASTType.cpp b/lldb/source/Symbol/ClangASTType.cpp index 642936106ee..8e5f3b86177 100644 --- a/lldb/source/Symbol/ClangASTType.cpp +++ b/lldb/source/Symbol/ClangASTType.cpp @@ -1629,7 +1629,13 @@ ClangASTType::GetTypeByteSize( 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; } |