1 | //===-- ExpressionParser.cpp ----------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "lldb/Expression/ExpressionParser.h" |
10 | #include "lldb/Expression/DiagnosticManager.h" |
11 | #include "lldb/Expression/IRExecutionUnit.h" |
12 | #include "lldb/Target/ExecutionContext.h" |
13 | #include "lldb/Target/ThreadPlanCallFunction.h" |
14 | |
15 | using namespace lldb; |
16 | using namespace lldb_private; |
17 | |
18 | Status ExpressionParser::PrepareForExecution( |
19 | addr_t &func_addr, addr_t &func_end, |
20 | std::shared_ptr<IRExecutionUnit> &execution_unit_sp, |
21 | ExecutionContext &exe_ctx, bool &can_interpret, |
22 | ExecutionPolicy execution_policy) { |
23 | Status status = |
24 | DoPrepareForExecution(func_addr, func_end, execution_unit_sp, exe_ctx, |
25 | can_interpret, execution_policy); |
26 | if (status.Success() && exe_ctx.GetProcessPtr() && exe_ctx.HasThreadScope()) |
27 | status = RunStaticInitializers(execution_unit_sp, exe_ctx); |
28 | |
29 | return status; |
30 | } |
31 | |
32 | Status |
33 | ExpressionParser::RunStaticInitializers(IRExecutionUnitSP &execution_unit_sp, |
34 | ExecutionContext &exe_ctx) { |
35 | Status err; |
36 | |
37 | if (!execution_unit_sp.get()) { |
38 | err = Status::FromErrorString( |
39 | str: "can't run static initializers for a NULL execution unit" ); |
40 | return err; |
41 | } |
42 | |
43 | if (!exe_ctx.HasThreadScope()) { |
44 | err = Status::FromErrorString( |
45 | str: "can't run static initializers without a thread" ); |
46 | return err; |
47 | } |
48 | |
49 | std::vector<addr_t> static_initializers; |
50 | |
51 | execution_unit_sp->GetStaticInitializers(static_initializers); |
52 | |
53 | for (addr_t static_initializer : static_initializers) { |
54 | EvaluateExpressionOptions options; |
55 | |
56 | ThreadPlanSP call_static_initializer(new ThreadPlanCallFunction( |
57 | exe_ctx.GetThreadRef(), Address(static_initializer), CompilerType(), |
58 | llvm::ArrayRef<addr_t>(), options)); |
59 | |
60 | DiagnosticManager execution_errors; |
61 | ExpressionResults results = |
62 | exe_ctx.GetThreadRef().GetProcess()->RunThreadPlan( |
63 | exe_ctx, thread_plan_sp&: call_static_initializer, options, diagnostic_manager&: execution_errors); |
64 | |
65 | if (results != eExpressionCompleted) { |
66 | err = Status::FromError(error: execution_errors.GetAsError( |
67 | result: lldb::eExpressionSetupError, message: "couldn't run static initializer:" )); |
68 | return err; |
69 | } |
70 | } |
71 | |
72 | return err; |
73 | } |
74 | |