diff options
| author | Sean Callanan <scallanan@apple.com> | 2013-01-19 01:49:02 +0000 |
|---|---|---|
| committer | Sean Callanan <scallanan@apple.com> | 2013-01-19 01:49:02 +0000 |
| commit | a2868d4c2e612aad10bfff144bf80441132e0857 (patch) | |
| tree | dcfdf3c969398e4d57b3851e268b7b2a58bddaa1 /lldb/source/Expression/ClangUserExpression.cpp | |
| parent | 97e77abf8389e65f5eb935033cf1f71a69b4e00a (diff) | |
| download | bcm5719-llvm-a2868d4c2e612aad10bfff144bf80441132e0857.tar.gz bcm5719-llvm-a2868d4c2e612aad10bfff144bf80441132e0857.zip | |
Extended LLDB to handle blocks capturing 'self'
in an Objective-C class method. Before, errors
of the form
error: cannot find interface declaration for '$__lldb_objc_class'
would appear when running any expression when
the current frame is a block that captures 'self'
from an Objective-C class method.
<rdar://problem/12905561>
llvm-svn: 172880
Diffstat (limited to 'lldb/source/Expression/ClangUserExpression.cpp')
| -rw-r--r-- | lldb/source/Expression/ClangUserExpression.cpp | 85 |
1 files changed, 83 insertions, 2 deletions
diff --git a/lldb/source/Expression/ClangUserExpression.cpp b/lldb/source/Expression/ClangUserExpression.cpp index d228569fa1c..66783812508 100644 --- a/lldb/source/Expression/ClangUserExpression.cpp +++ b/lldb/source/Expression/ClangUserExpression.cpp @@ -234,13 +234,94 @@ ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err) lldb::LanguageType language = metadata->GetObjectPtrLanguage(); if (language == lldb::eLanguageTypeC_plus_plus) { + if (m_enforce_valid_object) + { + lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true)); + + const char *thisErrorString = "Stopped in a context claiming to capture a C++ object pointer, but 'this' isn't available; pretending we are in a generic context"; + + if (!variable_list_sp) + { + err.SetErrorString(thisErrorString); + return; + } + + lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this"))); + + if (!this_var_sp || + !this_var_sp->IsInScope(frame) || + !this_var_sp->LocationIsValidForFrame (frame)) + { + err.SetErrorString(thisErrorString); + return; + } + } + m_cplusplus = true; m_needs_object_ptr = true; } else if (language == lldb::eLanguageTypeObjC) { - m_objectivec = true; - m_needs_object_ptr = true; + if (m_enforce_valid_object) + { + lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true)); + + const char *selfErrorString = "Stopped in a context claiming to capture an Objective-C object pointer, but 'self' isn't available; pretending we are in a generic context"; + + if (!variable_list_sp) + { + err.SetErrorString(selfErrorString); + return; + } + + lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self")); + + if (!self_variable_sp || + !self_variable_sp->IsInScope(frame) || + !self_variable_sp->LocationIsValidForFrame (frame)) + { + err.SetErrorString(selfErrorString); + return; + } + + Type *self_type = self_variable_sp->GetType(); + + if (!self_type) + { + err.SetErrorString(selfErrorString); + return; + } + + lldb::clang_type_t self_opaque_type = self_type->GetClangForwardType(); + + if (!self_opaque_type) + { + err.SetErrorString(selfErrorString); + return; + } + + clang::QualType self_qual_type = clang::QualType::getFromOpaquePtr(self_opaque_type); + + if (self_qual_type->isObjCClassType()) + { + return; + } + else if (self_qual_type->isObjCObjectPointerType()) + { + m_objectivec = true; + m_needs_object_ptr = true; + } + else + { + err.SetErrorString(selfErrorString); + return; + } + } + else + { + m_objectivec = true; + m_needs_object_ptr = true; + } } } } |

