diff options
author | Sean Callanan <scallanan@apple.com> | 2012-09-20 23:21:16 +0000 |
---|---|---|
committer | Sean Callanan <scallanan@apple.com> | 2012-09-20 23:21:16 +0000 |
commit | 2cb5e527f697d0cf93bb3dd8ffa319ca33d19c40 (patch) | |
tree | 974a6ab15e29eda75c0e220e33d311fb80600cb4 /lldb/source/Expression | |
parent | fcb0ffa622b09a9c8acc325e7b6cd690f3ada487 (diff) | |
download | bcm5719-llvm-2cb5e527f697d0cf93bb3dd8ffa319ca33d19c40.tar.gz bcm5719-llvm-2cb5e527f697d0cf93bb3dd8ffa319ca33d19c40.zip |
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>
llvm-svn: 164333
Diffstat (limited to 'lldb/source/Expression')
-rw-r--r-- | lldb/source/Expression/ClangASTSource.cpp | 72 | ||||
-rw-r--r-- | lldb/source/Expression/ClangExpressionDeclMap.cpp | 2 |
2 files changed, 56 insertions, 18 deletions
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 |