summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
diff options
context:
space:
mode:
authorAleksandr Urakov <aleksandr.urakov@jetbrains.com>2019-02-05 09:14:36 +0000
committerAleksandr Urakov <aleksandr.urakov@jetbrains.com>2019-02-05 09:14:36 +0000
commit40624a085c03fb6d41834885d41f7158ab72950e (patch)
tree669263f8f423f073f133b68787079cf8fecb8411 /lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
parentde5220ed5e5ab1f7064e9bae57d7b4b8887277fa (diff)
downloadbcm5719-llvm-40624a085c03fb6d41834885d41f7158ab72950e.tar.gz
bcm5719-llvm-40624a085c03fb6d41834885d41f7158ab72950e.zip
[Expressions] Add support of expressions evaluation in some object's context
Summary: This patch adds support of expression evaluation in a context of some object. Consider the following example: ``` struct S { int a = 11; int b = 12; }; int main() { S s; int a = 1; int b = 2; // We have stopped here return 0; } ``` This patch allows to do something like that: ``` lldb.frame.FindVariable("s").EvaluateExpression("a + b") ``` and the result will be `33` (not `3`) because fields `a` and `b` of `s` will be used (not locals `a` and `b`). This is achieved by replacing of `this` type and object for the expression. This has some limitations: an expression can be evaluated only for values located in the debuggee process memory (they must have an address of `eAddressTypeLoad` type). Reviewers: teemperor, clayborg, jingham, zturner, labath, davide, spyffe, serge-sans-paille Reviewed By: jingham Subscribers: abidh, lldb-commits, leonid.mashinskiy Tags: #lldb Differential Revision: https://reviews.llvm.org/D55318 llvm-svn: 353149
Diffstat (limited to 'lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp')
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp47
1 files changed, 40 insertions, 7 deletions
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 *
OpenPOWER on IntegriCloud