diff options
author | Aleksandr Urakov <aleksandr.urakov@jetbrains.com> | 2019-02-05 09:14:36 +0000 |
---|---|---|
committer | Aleksandr Urakov <aleksandr.urakov@jetbrains.com> | 2019-02-05 09:14:36 +0000 |
commit | 40624a085c03fb6d41834885d41f7158ab72950e (patch) | |
tree | 669263f8f423f073f133b68787079cf8fecb8411 /lldb/source/Expression/UserExpression.cpp | |
parent | de5220ed5e5ab1f7064e9bae57d7b4b8887277fa (diff) | |
download | bcm5719-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/Expression/UserExpression.cpp')
-rw-r--r-- | lldb/source/Expression/UserExpression.cpp | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/lldb/source/Expression/UserExpression.cpp b/lldb/source/Expression/UserExpression.cpp index 87e560bd563..4fb56177d98 100644 --- a/lldb/source/Expression/UserExpression.cpp +++ b/lldb/source/Expression/UserExpression.cpp @@ -140,10 +140,22 @@ lldb::ExpressionResults UserExpression::Evaluate( ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options, llvm::StringRef expr, llvm::StringRef prefix, lldb::ValueObjectSP &result_valobj_sp, Status &error, uint32_t line_offset, - std::string *fixed_expression, lldb::ModuleSP *jit_module_sp_ptr) { + std::string *fixed_expression, lldb::ModuleSP *jit_module_sp_ptr, + ValueObject *ctx_obj) { Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP)); + if (ctx_obj) { + static unsigned const ctx_type_mask = + lldb::TypeFlags::eTypeIsClass | lldb::TypeFlags::eTypeIsStructUnion; + if (!(ctx_obj->GetTypeInfo() & ctx_type_mask)) { + LLDB_LOG(log, "== [UserExpression::Evaluate] Passed a context object of " + "an invalid type, can't run expressions."); + error.SetErrorString("a context object of an invalid type passed"); + return lldb::eExpressionSetupError; + } + } + lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy(); lldb::LanguageType language = options.GetLanguage(); const ResultType desired_type = options.DoesCoerceToId() @@ -208,7 +220,8 @@ lldb::ExpressionResults UserExpression::Evaluate( lldb::UserExpressionSP user_expression_sp( target->GetUserExpressionForLanguage(expr, full_prefix, language, - desired_type, options, error)); + desired_type, options, ctx_obj, + error)); if (error.Fail()) { if (log) log->Printf("== [UserExpression::Evaluate] Getting expression: %s ==", @@ -253,7 +266,8 @@ lldb::ExpressionResults UserExpression::Evaluate( lldb::UserExpressionSP fixed_expression_sp( target->GetUserExpressionForLanguage(fixed_expression->c_str(), full_prefix, language, - desired_type, options, error)); + desired_type, options, ctx_obj, + error)); DiagnosticManager fixed_diagnostic_manager; parse_success = fixed_expression_sp->Parse( fixed_diagnostic_manager, exe_ctx, execution_policy, |