diff options
author | Sean Callanan <scallanan@apple.com> | 2012-02-22 23:57:45 +0000 |
---|---|---|
committer | Sean Callanan <scallanan@apple.com> | 2012-02-22 23:57:45 +0000 |
commit | 7277284f87dd195294355416d29ff3e6715d037a (patch) | |
tree | 0869c062a22cad4c17e2e98015b8beaa183bd598 /lldb/source/Core/ValueObject.cpp | |
parent | 9646a472da57c03b44dd4286de571426117395fa (diff) | |
download | bcm5719-llvm-7277284f87dd195294355416d29ff3e6715d037a.tar.gz bcm5719-llvm-7277284f87dd195294355416d29ff3e6715d037a.zip |
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.
llvm-svn: 151214
Diffstat (limited to 'lldb/source/Core/ValueObject.cpp')
-rw-r--r-- | lldb/source/Core/ValueObject.cpp | 103 |
1 files changed, 101 insertions, 2 deletions
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp index 0c75affd1bd..15885eb691f 100644 --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -95,7 +95,8 @@ ValueObject::ValueObject (ValueObject &parent) : 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 @@ ValueObject::ValueObject (ExecutionContextScope *exe_scope, 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 @@ ValueObject::SetNeedsUpdate () 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 () { |