summaryrefslogtreecommitdiffstats
path: root/lldb/source/API/SBValue.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/API/SBValue.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/API/SBValue.cpp')
-rw-r--r--lldb/source/API/SBValue.cpp81
1 files changed, 81 insertions, 0 deletions
diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp
index 31606af4a22..b83a4effcd5 100644
--- a/lldb/source/API/SBValue.cpp
+++ b/lldb/source/API/SBValue.cpp
@@ -1294,6 +1294,87 @@ bool SBValue::GetExpressionPath(SBStream &description,
return false;
}
+lldb::SBValue SBValue::EvaluateExpression(const char* expr) const {
+ ValueLocker locker;
+ lldb::ValueObjectSP value_sp(GetSP(locker));
+ if (!value_sp)
+ return SBValue();
+
+ lldb::TargetSP target_sp = value_sp->GetTargetSP();
+ if (!target_sp)
+ return SBValue();
+
+ lldb::SBExpressionOptions options;
+ options.SetFetchDynamicValue(target_sp->GetPreferDynamicValue());
+ options.SetUnwindOnError(true);
+ options.SetIgnoreBreakpoints(true);
+
+ return EvaluateExpression(expr, options, nullptr);
+}
+
+lldb::SBValue
+SBValue::EvaluateExpression(const char *expr,
+ const SBExpressionOptions &options) const {
+ return EvaluateExpression(expr, options, nullptr);
+}
+
+lldb::SBValue SBValue::EvaluateExpression(const char *expr,
+ const SBExpressionOptions &options,
+ const char *name) const {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+
+ if (!expr || expr[0] == '\0') {
+ LLDB_LOG(log,
+ "SBValue::EvaluateExpression called with an empty expression");
+ return SBValue();
+ }
+
+ LLDB_LOG(log, "SBValue()::EvaluateExpression (expr=\"{0}\")...", expr);
+
+ ValueLocker locker;
+ lldb::ValueObjectSP value_sp(GetSP(locker));
+ if (!value_sp) {
+ LLDB_LOG(log, "SBValue::EvaluateExpression () => error: could not "
+ "reconstruct value object for this SBValue");
+ return SBValue();
+ }
+
+ lldb::TargetSP target_sp = value_sp->GetTargetSP();
+ if (!target_sp) {
+ LLDB_LOG(
+ log,
+ "SBValue::EvaluateExpression () => error: could not retrieve target");
+ return SBValue();
+ }
+
+ std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
+ ExecutionContext exe_ctx(target_sp.get());
+
+ StackFrame *frame = exe_ctx.GetFramePtr();
+ if (!frame) {
+ LLDB_LOG(log, "SBValue::EvaluateExpression () => error: could not retrieve "
+ "current stack frame");
+ return SBValue();
+ }
+
+ ValueObjectSP res_val_sp;
+ ExpressionResults expr_res = target_sp->EvaluateExpression(
+ expr, frame, res_val_sp, options.ref(), nullptr, value_sp.get());
+
+ if (name)
+ res_val_sp->SetName(ConstString(name));
+
+ LLDB_LOG(log,
+ "SBValue(Name=\"{0}\")::EvaluateExpression (expr=\"{1}\") => "
+ "SBValue(Success={2}) (execution result={3})",
+ value_sp->GetName(), expr, res_val_sp->GetError().Success(),
+ expr_res);
+
+ SBValue result;
+ result.SetSP(res_val_sp, options.GetFetchDynamicValue());
+ return result;
+}
+
bool SBValue::GetDescription(SBStream &description) {
Stream &strm = description.ref();
OpenPOWER on IntegriCloud