diff options
Diffstat (limited to 'lldb/source/Plugins/ExpressionParser')
5 files changed, 105 insertions, 18 deletions
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp index 745341b2d04..6e7f11fed5f 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -65,10 +65,12 @@ const char *g_lldb_local_vars_namespace_cstr = "$__lldb_local_vars"; ClangExpressionDeclMap::ClangExpressionDeclMap( bool keep_result_in_memory, Materializer::PersistentVariableDelegate *result_delegate, - ExecutionContext &exe_ctx) + ExecutionContext &exe_ctx, + ValueObject *ctx_obj) : ClangASTSource(exe_ctx.GetTargetSP()), m_found_entities(), m_struct_members(), m_keep_result_in_memory(keep_result_in_memory), - m_result_delegate(result_delegate), m_parser_vars(), m_struct_vars() { + m_result_delegate(result_delegate), m_parser_vars(), m_struct_vars(), + m_ctx_obj(ctx_obj) { EnableStructVars(); } @@ -927,6 +929,21 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( static ConstString g_lldb_class_name("$__lldb_class"); if (name == g_lldb_class_name) { + if (m_ctx_obj) { + Status status; + lldb::ValueObjectSP ctx_obj_ptr = m_ctx_obj->AddressOf(status); + if (!ctx_obj_ptr || status.Fail()) + return; + + AddThisType(context, TypeFromUser(m_ctx_obj->GetCompilerType()), + current_id); + + m_struct_vars->m_object_pointer_type = + TypeFromUser(ctx_obj_ptr->GetCompilerType()); + + return; + } + // Clang is looking for the type of "this" if (frame == NULL) @@ -1019,6 +1036,21 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls( static ConstString g_lldb_objc_class_name("$__lldb_objc_class"); if (name == g_lldb_objc_class_name) { + if (m_ctx_obj) { + Status status; + lldb::ValueObjectSP ctx_obj_ptr = m_ctx_obj->AddressOf(status); + if (!ctx_obj_ptr || status.Fail()) + return; + + AddOneType(context, TypeFromUser(m_ctx_obj->GetCompilerType()), + current_id); + + m_struct_vars->m_object_pointer_type = + TypeFromUser(ctx_obj_ptr->GetCompilerType()); + + return; + } + // Clang is looking for the type of "*self" if (!frame) @@ -2124,7 +2156,7 @@ void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, } void ClangExpressionDeclMap::AddThisType(NameSearchContext &context, - TypeFromUser &ut, + const TypeFromUser &ut, unsigned int current_id) { CompilerType copied_clang_type = GuardedCopyType(ut); @@ -2198,7 +2230,7 @@ void ClangExpressionDeclMap::AddThisType(NameSearchContext &context, } void ClangExpressionDeclMap::AddOneType(NameSearchContext &context, - TypeFromUser &ut, + const TypeFromUser &ut, unsigned int current_id) { CompilerType copied_clang_type = GuardedCopyType(ut); diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h index d8609797fdb..ac6690dea0f 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h @@ -72,11 +72,16 @@ public: /// /// @param[in] exe_ctx /// The execution context to use when parsing. + /// + /// @param[in] ctx_obj + /// If not empty, then expression is evaluated in context of this object. + /// See the comment to `UserExpression::Evaluate` for details. //------------------------------------------------------------------ ClangExpressionDeclMap( bool keep_result_in_memory, Materializer::PersistentVariableDelegate *result_delegate, - ExecutionContext &exe_ctx); + ExecutionContext &exe_ctx, + ValueObject *ctx_obj); //------------------------------------------------------------------ /// Destructor @@ -343,6 +348,10 @@ private: Materializer::PersistentVariableDelegate *m_result_delegate; ///< If non-NULL, used to report expression results to ///ClangUserExpression. + ValueObject *m_ctx_obj; ///< If not empty, then expression is + ///evaluated in context of this object. + ///For details see the comment to + ///`UserExpression::Evaluate`. //---------------------------------------------------------------------- /// The following values should not live beyond parsing @@ -581,7 +590,7 @@ private: /// @param[in] type /// The type that needs to be created. //------------------------------------------------------------------ - void AddOneType(NameSearchContext &context, TypeFromUser &type, + void AddOneType(NameSearchContext &context, const TypeFromUser &type, unsigned int current_id); //------------------------------------------------------------------ @@ -594,7 +603,7 @@ private: /// @param[in] type /// The type for *this. //------------------------------------------------------------------ - void AddThisType(NameSearchContext &context, TypeFromUser &type, + void AddThisType(NameSearchContext &context, const TypeFromUser &type, unsigned int current_id); //------------------------------------------------------------------ diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp index e7e9ba972bb..f9672378350 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp @@ -59,13 +59,15 @@ using namespace lldb_private; ClangUserExpression::ClangUserExpression( ExecutionContextScope &exe_scope, llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language, - ResultType desired_type, const EvaluateExpressionOptions &options) + ResultType desired_type, const EvaluateExpressionOptions &options, + ValueObject *ctx_obj) : LLVMUserExpression(exe_scope, expr, prefix, language, desired_type, options), m_type_system_helper(*m_target_wp.lock().get(), options.GetExecutionPolicy() == eExecutionPolicyTopLevel), - m_result_delegate(exe_scope.CalculateTarget()) { + m_result_delegate(exe_scope.CalculateTarget()), + m_ctx_obj(ctx_obj) { switch (m_language) { case lldb::eLanguageTypeC_plus_plus: m_allow_cxx = true; @@ -130,7 +132,27 @@ void ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) { return; } - if (clang::CXXMethodDecl *method_decl = + if (m_ctx_obj) { + switch (m_ctx_obj->GetObjectRuntimeLanguage()) { + case lldb::eLanguageTypeC: + case lldb::eLanguageTypeC89: + case lldb::eLanguageTypeC99: + case lldb::eLanguageTypeC11: + case lldb::eLanguageTypeC_plus_plus: + case lldb::eLanguageTypeC_plus_plus_03: + case lldb::eLanguageTypeC_plus_plus_11: + case lldb::eLanguageTypeC_plus_plus_14: + m_in_cplusplus_method = true; + break; + case lldb::eLanguageTypeObjC: + case lldb::eLanguageTypeObjC_plus_plus: + m_in_objectivec_method = true; + break; + default: + break; + } + m_needs_object_ptr = true; + } else if (clang::CXXMethodDecl *method_decl = ClangASTContext::DeclContextGetAsCXXMethodDecl(decl_context)) { if (m_allow_cxx && method_decl->isInstance()) { if (m_enforce_valid_object) { @@ -396,7 +418,8 @@ void ClangUserExpression::UpdateLanguageForExpr( m_expr_lang = lldb::eLanguageTypeC; if (!source_code->GetText(m_transformed_text, m_expr_lang, - m_in_static_method, exe_ctx)) { + m_in_static_method, exe_ctx, + !m_ctx_obj)) { diagnostic_manager.PutString(eDiagnosticSeverityError, "couldn't construct expression body"); return; @@ -733,7 +756,15 @@ bool ClangUserExpression::AddArguments(ExecutionContext &exe_ctx, Status object_ptr_error; - object_ptr = GetObjectPointer(frame_sp, object_name, object_ptr_error); + if (m_ctx_obj) { + AddressType address_type; + object_ptr = m_ctx_obj->GetAddressOf(false, &address_type); + if (object_ptr == LLDB_INVALID_ADDRESS || + address_type != eAddressTypeLoad) + object_ptr_error.SetErrorString("Can't get context object's " + "debuggee address"); + } else + object_ptr = GetObjectPointer(frame_sp, object_name, object_ptr_error); if (!object_ptr_error.Success()) { exe_ctx.GetTargetRef().GetDebugger().GetAsyncOutputStream()->Printf( @@ -776,9 +807,11 @@ lldb::ExpressionVariableSP ClangUserExpression::GetResultAfterDematerialization( void ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap( ExecutionContext &exe_ctx, Materializer::PersistentVariableDelegate &delegate, - bool keep_result_in_memory) { + bool keep_result_in_memory, + ValueObject *ctx_obj) { m_expr_decl_map_up.reset( - new ClangExpressionDeclMap(keep_result_in_memory, &delegate, exe_ctx)); + new ClangExpressionDeclMap(keep_result_in_memory, &delegate, exe_ctx, + ctx_obj)); } clang::ASTConsumer * diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h index 836d44e7544..2f9a7238b4c 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h @@ -61,7 +61,8 @@ public: void ResetDeclMap(ExecutionContext &exe_ctx, Materializer::PersistentVariableDelegate &result_delegate, - bool keep_result_in_memory); + bool keep_result_in_memory, + ValueObject *ctx_obj); //------------------------------------------------------------------ /// Return the object that the parser should allow to access ASTs. May be @@ -105,11 +106,17 @@ public: /// @param[in] desired_type /// If not eResultTypeAny, the type to use for the expression /// result. + /// + /// @param[in] ctx_obj + /// The object (if any) in which context the expression + /// must be evaluated. For details see the comment to + /// `UserExpression::Evaluate`. //------------------------------------------------------------------ ClangUserExpression(ExecutionContextScope &exe_scope, llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language, ResultType desired_type, - const EvaluateExpressionOptions &options); + const EvaluateExpressionOptions &options, + ValueObject *ctx_obj); ~ClangUserExpression() override; @@ -153,7 +160,8 @@ public: Materializer::PersistentVariableDelegate &result_delegate, bool keep_result_in_memory) { m_type_system_helper.ResetDeclMap(exe_ctx, result_delegate, - keep_result_in_memory); + keep_result_in_memory, + m_ctx_obj); } lldb::ExpressionVariableSP @@ -204,6 +212,10 @@ private: /// were not able to calculate this position. llvm::Optional<size_t> m_user_expression_start_pos; ResultDelegate m_result_delegate; + + /// The object (if any) in which context the expression is evaluated. + /// See the comment to `UserExpression::Evaluate` for details. + ValueObject *m_ctx_obj; }; } // namespace lldb_private diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp index 210ed3c993f..c15bfa5e421 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp @@ -156,5 +156,6 @@ bool ClangUtilityFunction::Install(DiagnosticManager &diagnostic_manager, void ClangUtilityFunction::ClangUtilityFunctionHelper::ResetDeclMap( ExecutionContext &exe_ctx, bool keep_result_in_memory) { m_expr_decl_map_up.reset( - new ClangExpressionDeclMap(keep_result_in_memory, nullptr, exe_ctx)); + new ClangExpressionDeclMap(keep_result_in_memory, nullptr, exe_ctx, + nullptr)); } |