diff options
| author | Jim Ingham <jingham@apple.com> | 2012-10-30 23:35:54 +0000 |
|---|---|---|
| committer | Jim Ingham <jingham@apple.com> | 2012-10-30 23:35:54 +0000 |
| commit | 5fdeed4e9f03c15f6282bddf70863028d3336813 (patch) | |
| tree | 216dc1837b7cb8bfbdcd2d0fc238ed332f356695 /lldb/source/Expression | |
| parent | 2cffda3ff8bb5435e524da975fd43d9cf7d90e59 (diff) | |
| download | bcm5719-llvm-5fdeed4e9f03c15f6282bddf70863028d3336813.tar.gz bcm5719-llvm-5fdeed4e9f03c15f6282bddf70863028d3336813.zip | |
Make blocks that capture their containing method's object pointer look like methods of
the containing class so that direct ivar access will work in the expression parser.
<rdar://problem/9797999>
llvm-svn: 167061
Diffstat (limited to 'lldb/source/Expression')
| -rw-r--r-- | lldb/source/Expression/ClangExpressionDeclMap.cpp | 222 | ||||
| -rw-r--r-- | lldb/source/Expression/ClangUserExpression.cpp | 27 |
2 files changed, 178 insertions, 71 deletions
diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index f8304b98b6b..f54d53e7f7e 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -2470,34 +2470,83 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context, clang::CXXMethodDecl *method_decl = llvm::dyn_cast<clang::CXXMethodDecl>(decl_context); - if (!method_decl) - return; - - clang::CXXRecordDecl *class_decl = method_decl->getParent(); - - QualType class_qual_type(class_decl->getTypeForDecl(), 0); - - TypeFromUser class_user_type (class_qual_type.getAsOpaquePtr(), - &class_decl->getASTContext()); - - if (log) + if (method_decl) { - ASTDumper ast_dumper(class_qual_type); - log->Printf(" CEDM::FEVD[%u] Adding type for $__lldb_class: %s", current_id, ast_dumper.GetCString()); - } - - AddOneType(context, class_user_type, current_id, true); - if (method_decl->isInstance()) + clang::CXXRecordDecl *class_decl = method_decl->getParent(); + + QualType class_qual_type(class_decl->getTypeForDecl(), 0); + + TypeFromUser class_user_type (class_qual_type.getAsOpaquePtr(), + &class_decl->getASTContext()); + + if (log) + { + ASTDumper ast_dumper(class_qual_type); + log->Printf(" CEDM::FEVD[%u] Adding type for $__lldb_class: %s", current_id, ast_dumper.GetCString()); + } + + AddOneType(context, class_user_type, current_id, true); + + if (method_decl->isInstance()) + { + // self is a pointer to the object + + QualType class_pointer_type = method_decl->getASTContext().getPointerType(class_qual_type); + + TypeFromUser self_user_type(class_pointer_type.getAsOpaquePtr(), + &method_decl->getASTContext()); + + m_struct_vars->m_object_pointer_type = self_user_type; + } + } + else { - // self is a pointer to the object + // This branch will get hit if we are executing code in the context of a function that + // claims to have an object pointer (through DW_AT_object_pointer?) but is not formally a + // method of the class. In that case, just look up the "this" variable in the the current + // scope and use its type. + // FIXME: This code is formally correct, but clang doesn't currently emit DW_AT_object_pointer + // for C++ so it hasn't actually been tested. - QualType class_pointer_type = method_decl->getASTContext().getPointerType(class_qual_type); + VariableList *vars = frame->GetVariableList(false); - TypeFromUser self_user_type(class_pointer_type.getAsOpaquePtr(), - &method_decl->getASTContext()); + lldb::VariableSP this_var = vars->FindVariable(ConstString("this")); - m_struct_vars->m_object_pointer_type = self_user_type; + if (this_var && + this_var->IsInScope(frame) && + this_var->LocationIsValidForFrame (frame)) + { + Type *this_type = this_var->GetType(); + + if (!this_type) + return; + + QualType this_qual_type = QualType::getFromOpaquePtr(this_type->GetClangFullType()); + const PointerType *class_pointer_type = this_qual_type->getAs<PointerType>(); + + if (class_pointer_type) + { + QualType class_type = class_pointer_type->getPointeeType(); + + if (log) + { + ASTDumper ast_dumper(this_type->GetClangFullType()); + log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s", current_id, ast_dumper.GetCString()); + } + + TypeFromUser class_user_type (class_type.getAsOpaquePtr(), + this_type->GetClangAST()); + AddOneType(context, class_user_type, current_id, false); + + + TypeFromUser this_user_type(this_type->GetClangFullType(), + this_type->GetClangAST()); + + m_struct_vars->m_object_pointer_type = this_user_type; + return; + } + } } return; @@ -2529,65 +2578,96 @@ ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context, clang::ObjCMethodDecl *method_decl = llvm::dyn_cast<clang::ObjCMethodDecl>(decl_context); - if (!method_decl) - return; - - ObjCInterfaceDecl* self_interface = method_decl->getClassInterface(); - - if (!self_interface) - return; - - const clang::Type *interface_type = self_interface->getTypeForDecl(); - - TypeFromUser class_user_type(QualType(interface_type, 0).getAsOpaquePtr(), - &method_decl->getASTContext()); - - if (log) + if (method_decl) { - ASTDumper ast_dumper(interface_type); - log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s", current_id, ast_dumper.GetCString()); - } - - AddOneType(context, class_user_type, current_id, false); - -#if 0 - VariableList *vars = frame->GetVariableList(false); - - lldb::VariableSP self_var = vars->FindVariable(ConstString("self")); - - if (self_var && - self_var->IsInScope(frame) && - self_var->LocationIsValidForFrame (frame)) { - Type *self_type = self_var->GetType(); + + ObjCInterfaceDecl* self_interface = method_decl->getClassInterface(); - if (!self_type) + if (!self_interface) return; - TypeFromUser self_user_type(self_type->GetClangFullType(), - self_type->GetClangAST()); - } -#endif - - if (method_decl->isInstanceMethod()) - { - // self is a pointer to the object + const clang::Type *interface_type = self_interface->getTypeForDecl(); + + TypeFromUser class_user_type(QualType(interface_type, 0).getAsOpaquePtr(), + &method_decl->getASTContext()); - QualType class_pointer_type = method_decl->getASTContext().getObjCObjectPointerType(QualType(interface_type, 0)); - - TypeFromUser self_user_type(class_pointer_type.getAsOpaquePtr(), - &method_decl->getASTContext()); - - m_struct_vars->m_object_pointer_type = self_user_type; + if (log) + { + ASTDumper ast_dumper(interface_type); + log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s", current_id, ast_dumper.GetCString()); + } + + AddOneType(context, class_user_type, current_id, false); + + if (method_decl->isInstanceMethod()) + { + // self is a pointer to the object + + QualType class_pointer_type = method_decl->getASTContext().getObjCObjectPointerType(QualType(interface_type, 0)); + + TypeFromUser self_user_type(class_pointer_type.getAsOpaquePtr(), + &method_decl->getASTContext()); + + m_struct_vars->m_object_pointer_type = self_user_type; + } + else + { + // self is a Class pointer + QualType class_type = method_decl->getASTContext().getObjCClassType(); + + TypeFromUser self_user_type(class_type.getAsOpaquePtr(), + &method_decl->getASTContext()); + + m_struct_vars->m_object_pointer_type = self_user_type; + } + + return; } else { - // self is a Class pointer - QualType class_type = method_decl->getASTContext().getObjCClassType(); + // This branch will get hit if we are executing code in the context of a function that + // claims to have an object pointer (through DW_AT_object_pointer?) but is not formally a + // method of the class. In that case, just look up the "self" variable in the the current + // scope and use its type. + + VariableList *vars = frame->GetVariableList(false); - TypeFromUser self_user_type(class_type.getAsOpaquePtr(), - &method_decl->getASTContext()); + lldb::VariableSP self_var = vars->FindVariable(ConstString("self")); - m_struct_vars->m_object_pointer_type = self_user_type; + if (self_var && + self_var->IsInScope(frame) && + self_var->LocationIsValidForFrame (frame)) + { + Type *self_type = self_var->GetType(); + + if (!self_type) + return; + + QualType self_qual_type = QualType::getFromOpaquePtr(self_type->GetClangFullType()); + const ObjCObjectPointerType *class_pointer_type = self_qual_type->getAs<ObjCObjectPointerType>(); + + if (class_pointer_type) + { + QualType class_type = class_pointer_type->getPointeeType(); + + if (log) + { + ASTDumper ast_dumper(self_type->GetClangFullType()); + log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s", current_id, ast_dumper.GetCString()); + } + + TypeFromUser class_user_type (class_type.getAsOpaquePtr(), + self_type->GetClangAST()); + AddOneType(context, class_user_type, current_id, false); + + + TypeFromUser self_user_type(self_type->GetClangFullType(), + self_type->GetClangAST()); + + m_struct_vars->m_object_pointer_type = self_user_type; + return; + } + } } return; diff --git a/lldb/source/Expression/ClangUserExpression.cpp b/lldb/source/Expression/ClangUserExpression.cpp index 450728272e6..9dfd0998a25 100644 --- a/lldb/source/Expression/ClangUserExpression.cpp +++ b/lldb/source/Expression/ClangUserExpression.cpp @@ -31,6 +31,10 @@ #include "lldb/Expression/ExpressionSourceCode.h" #include "lldb/Host/Host.h" #include "lldb/Symbol/Block.h" +#include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Symbol/Function.h" +#include "lldb/Symbol/Type.h" +#include "lldb/Symbol/ClangExternalASTSourceCommon.h" #include "lldb/Symbol/VariableList.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" @@ -192,6 +196,29 @@ ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err) m_static_method = true; } } + else if (clang::FunctionDecl *function_decl = llvm::dyn_cast<clang::FunctionDecl>(decl_context)) + { + // We might also have a function that said in the debug information that it captured an + // object pointer. The best way to deal with getting to the ivars at present it by pretending + // that this is a method of a class in whatever runtime the debug info says the object pointer + // belongs to. Do that here. + + ClangASTMetadata *metadata = ClangASTContext::GetMetadata (&decl_context->getParentASTContext(), (uintptr_t) function_decl); + if (metadata && metadata->HasObjectPtr()) + { + lldb::LanguageType language = metadata->GetObjectPtrLanguage(); + if (language == lldb::eLanguageTypeC_plus_plus) + { + m_cplusplus = true; + m_needs_object_ptr = true; + } + else if (language == lldb::eLanguageTypeObjC) + { + m_objectivec = true; + m_needs_object_ptr = true; + } + } + } } // This is a really nasty hack, meant to fix Objective-C expressions of the form |

