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