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