summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Callanan <scallanan@apple.com>2012-09-20 23:21:16 +0000
committerSean Callanan <scallanan@apple.com>2012-09-20 23:21:16 +0000
commit2cb5e527f697d0cf93bb3dd8ffa319ca33d19c40 (patch)
tree974a6ab15e29eda75c0e220e33d311fb80600cb4
parentfcb0ffa622b09a9c8acc325e7b6cd690f3ada487 (diff)
downloadbcm5719-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
-rw-r--r--lldb/include/lldb/Core/ValueObject.h6
-rw-r--r--lldb/include/lldb/Expression/ClangASTSource.h14
-rw-r--r--lldb/include/lldb/Symbol/ClangASTImporter.h3
-rw-r--r--lldb/source/Expression/ClangASTSource.cpp72
-rw-r--r--lldb/source/Expression/ClangExpressionDeclMap.cpp2
-rw-r--r--lldb/source/Symbol/ClangASTImporter.cpp22
-rw-r--r--lldb/source/Symbol/ClangASTType.cpp8
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;
}
OpenPOWER on IntegriCloud