[PowerPC] Collect some CallLowering arguments into a struct. [NFC]
[llvm-project.git] / lldb / source / API / SBThreadPlan.cpp
blobeed4d1bfb9c49a41a62bf0140bb23be87731d4a7
1 //===-- SBThreadPlan.cpp ----------------------------------------*- C++ -*-===//
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 //===----------------------------------------------------------------------===//
9 #include "SBReproducerPrivate.h"
10 #include "lldb/API/SBThread.h"
12 #include "lldb/API/SBFileSpec.h"
13 #include "lldb/API/SBStream.h"
14 #include "lldb/API/SBStructuredData.h"
15 #include "lldb/API/SBSymbolContext.h"
16 #include "lldb/Breakpoint/BreakpointLocation.h"
17 #include "lldb/Core/Debugger.h"
18 #include "lldb/Core/StreamFile.h"
19 #include "lldb/Core/StructuredDataImpl.h"
20 #include "lldb/Interpreter/CommandInterpreter.h"
21 #include "lldb/Symbol/CompileUnit.h"
22 #include "lldb/Symbol/SymbolContext.h"
23 #include "lldb/Target/Process.h"
24 #include "lldb/Target/Queue.h"
25 #include "lldb/Target/StopInfo.h"
26 #include "lldb/Target/SystemRuntime.h"
27 #include "lldb/Target/Target.h"
28 #include "lldb/Target/Thread.h"
29 #include "lldb/Target/ThreadPlan.h"
30 #include "lldb/Target/ThreadPlanPython.h"
31 #include "lldb/Target/ThreadPlanStepInRange.h"
32 #include "lldb/Target/ThreadPlanStepInstruction.h"
33 #include "lldb/Target/ThreadPlanStepOut.h"
34 #include "lldb/Target/ThreadPlanStepRange.h"
35 #include "lldb/Utility/State.h"
36 #include "lldb/Utility/Stream.h"
37 #include "lldb/Utility/StructuredData.h"
39 #include "lldb/API/SBAddress.h"
40 #include "lldb/API/SBDebugger.h"
41 #include "lldb/API/SBEvent.h"
42 #include "lldb/API/SBFrame.h"
43 #include "lldb/API/SBProcess.h"
44 #include "lldb/API/SBThreadPlan.h"
45 #include "lldb/API/SBValue.h"
47 #include <memory>
49 using namespace lldb;
50 using namespace lldb_private;
52 // Constructors
53 SBThreadPlan::SBThreadPlan() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBThreadPlan); }
55 SBThreadPlan::SBThreadPlan(const ThreadPlanSP &lldb_object_sp)
56 : m_opaque_sp(lldb_object_sp) {
57 LLDB_RECORD_CONSTRUCTOR(SBThreadPlan, (const lldb::ThreadPlanSP &),
58 lldb_object_sp);
61 SBThreadPlan::SBThreadPlan(const SBThreadPlan &rhs)
62 : m_opaque_sp(rhs.m_opaque_sp) {
63 LLDB_RECORD_CONSTRUCTOR(SBThreadPlan, (const lldb::SBThreadPlan &), rhs);
66 SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name) {
67 LLDB_RECORD_CONSTRUCTOR(SBThreadPlan, (lldb::SBThread &, const char *),
68 sb_thread, class_name);
70 Thread *thread = sb_thread.get();
71 if (thread)
72 m_opaque_sp = std::make_shared<ThreadPlanPython>(*thread, class_name,
73 nullptr);
76 SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name,
77 lldb::SBStructuredData &args_data) {
78 LLDB_RECORD_CONSTRUCTOR(SBThreadPlan, (lldb::SBThread &, const char *,
79 SBStructuredData &),
80 sb_thread, class_name, args_data);
82 Thread *thread = sb_thread.get();
83 if (thread)
84 m_opaque_sp = std::make_shared<ThreadPlanPython>(*thread, class_name,
85 args_data.m_impl_up.get());
88 // Assignment operator
90 const lldb::SBThreadPlan &SBThreadPlan::operator=(const SBThreadPlan &rhs) {
91 LLDB_RECORD_METHOD(const lldb::SBThreadPlan &,
92 SBThreadPlan, operator=,(const lldb::SBThreadPlan &), rhs);
94 if (this != &rhs)
95 m_opaque_sp = rhs.m_opaque_sp;
96 return LLDB_RECORD_RESULT(*this);
98 // Destructor
99 SBThreadPlan::~SBThreadPlan() {}
101 lldb_private::ThreadPlan *SBThreadPlan::get() { return m_opaque_sp.get(); }
103 bool SBThreadPlan::IsValid() const {
104 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBThreadPlan, IsValid);
105 return this->operator bool();
107 SBThreadPlan::operator bool() const {
108 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBThreadPlan, operator bool);
110 return m_opaque_sp.get() != nullptr;
113 void SBThreadPlan::Clear() {
114 LLDB_RECORD_METHOD_NO_ARGS(void, SBThreadPlan, Clear);
116 m_opaque_sp.reset();
119 lldb::StopReason SBThreadPlan::GetStopReason() {
120 LLDB_RECORD_METHOD_NO_ARGS(lldb::StopReason, SBThreadPlan, GetStopReason);
122 return eStopReasonNone;
125 size_t SBThreadPlan::GetStopReasonDataCount() {
126 LLDB_RECORD_METHOD_NO_ARGS(size_t, SBThreadPlan, GetStopReasonDataCount);
128 return 0;
131 uint64_t SBThreadPlan::GetStopReasonDataAtIndex(uint32_t idx) {
132 LLDB_RECORD_METHOD(uint64_t, SBThreadPlan, GetStopReasonDataAtIndex,
133 (uint32_t), idx);
135 return 0;
138 SBThread SBThreadPlan::GetThread() const {
139 LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBThread, SBThreadPlan, GetThread);
141 if (m_opaque_sp) {
142 return LLDB_RECORD_RESULT(
143 SBThread(m_opaque_sp->GetThread().shared_from_this()));
144 } else
145 return LLDB_RECORD_RESULT(SBThread());
148 bool SBThreadPlan::GetDescription(lldb::SBStream &description) const {
149 LLDB_RECORD_METHOD_CONST(bool, SBThreadPlan, GetDescription,
150 (lldb::SBStream &), description);
152 if (m_opaque_sp) {
153 m_opaque_sp->GetDescription(description.get(), eDescriptionLevelFull);
154 } else {
155 description.Printf("Empty SBThreadPlan");
157 return true;
160 void SBThreadPlan::SetThreadPlan(const ThreadPlanSP &lldb_object_sp) {
161 m_opaque_sp = lldb_object_sp;
164 void SBThreadPlan::SetPlanComplete(bool success) {
165 LLDB_RECORD_METHOD(void, SBThreadPlan, SetPlanComplete, (bool), success);
167 if (m_opaque_sp)
168 m_opaque_sp->SetPlanComplete(success);
171 bool SBThreadPlan::IsPlanComplete() {
172 LLDB_RECORD_METHOD_NO_ARGS(bool, SBThreadPlan, IsPlanComplete);
174 if (m_opaque_sp)
175 return m_opaque_sp->IsPlanComplete();
176 else
177 return true;
180 bool SBThreadPlan::IsPlanStale() {
181 LLDB_RECORD_METHOD_NO_ARGS(bool, SBThreadPlan, IsPlanStale);
183 if (m_opaque_sp)
184 return m_opaque_sp->IsPlanStale();
185 else
186 return true;
189 bool SBThreadPlan::IsValid() {
190 LLDB_RECORD_METHOD_NO_ARGS(bool, SBThreadPlan, IsValid);
192 if (m_opaque_sp)
193 return m_opaque_sp->ValidatePlan(nullptr);
194 else
195 return false;
198 // This section allows an SBThreadPlan to push another of the common types of
199 // plans...
201 // FIXME, you should only be able to queue thread plans from inside the methods
202 // of a Scripted Thread Plan. Need a way to enforce that.
204 SBThreadPlan
205 SBThreadPlan::QueueThreadPlanForStepOverRange(SBAddress &sb_start_address,
206 lldb::addr_t size) {
207 LLDB_RECORD_METHOD(lldb::SBThreadPlan, SBThreadPlan,
208 QueueThreadPlanForStepOverRange,
209 (lldb::SBAddress &, lldb::addr_t), sb_start_address, size);
211 SBError error;
212 return LLDB_RECORD_RESULT(
213 QueueThreadPlanForStepOverRange(sb_start_address, size, error));
216 SBThreadPlan SBThreadPlan::QueueThreadPlanForStepOverRange(
217 SBAddress &sb_start_address, lldb::addr_t size, SBError &error) {
218 LLDB_RECORD_METHOD(lldb::SBThreadPlan, SBThreadPlan,
219 QueueThreadPlanForStepOverRange,
220 (lldb::SBAddress &, lldb::addr_t, lldb::SBError &),
221 sb_start_address, size, error);
223 if (m_opaque_sp) {
224 Address *start_address = sb_start_address.get();
225 if (!start_address) {
226 return LLDB_RECORD_RESULT(SBThreadPlan());
229 AddressRange range(*start_address, size);
230 SymbolContext sc;
231 start_address->CalculateSymbolContext(&sc);
232 Status plan_status;
234 SBThreadPlan plan =
235 SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepOverRange(
236 false, range, sc, eAllThreads, plan_status));
238 if (plan_status.Fail())
239 error.SetErrorString(plan_status.AsCString());
241 return LLDB_RECORD_RESULT(plan);
242 } else {
243 return LLDB_RECORD_RESULT(SBThreadPlan());
247 SBThreadPlan
248 SBThreadPlan::QueueThreadPlanForStepInRange(SBAddress &sb_start_address,
249 lldb::addr_t size) {
250 LLDB_RECORD_METHOD(lldb::SBThreadPlan, SBThreadPlan,
251 QueueThreadPlanForStepInRange,
252 (lldb::SBAddress &, lldb::addr_t), sb_start_address, size);
254 SBError error;
255 return LLDB_RECORD_RESULT(
256 QueueThreadPlanForStepInRange(sb_start_address, size, error));
259 SBThreadPlan
260 SBThreadPlan::QueueThreadPlanForStepInRange(SBAddress &sb_start_address,
261 lldb::addr_t size, SBError &error) {
262 LLDB_RECORD_METHOD(lldb::SBThreadPlan, SBThreadPlan,
263 QueueThreadPlanForStepInRange,
264 (lldb::SBAddress &, lldb::addr_t, lldb::SBError &),
265 sb_start_address, size, error);
267 if (m_opaque_sp) {
268 Address *start_address = sb_start_address.get();
269 if (!start_address) {
270 return LLDB_RECORD_RESULT(SBThreadPlan());
273 AddressRange range(*start_address, size);
274 SymbolContext sc;
275 start_address->CalculateSymbolContext(&sc);
277 Status plan_status;
278 SBThreadPlan plan =
279 SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepInRange(
280 false, range, sc, nullptr, eAllThreads, plan_status));
282 if (plan_status.Fail())
283 error.SetErrorString(plan_status.AsCString());
285 return LLDB_RECORD_RESULT(plan);
286 } else {
287 return LLDB_RECORD_RESULT(SBThreadPlan());
291 SBThreadPlan
292 SBThreadPlan::QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to,
293 bool first_insn) {
294 LLDB_RECORD_METHOD(lldb::SBThreadPlan, SBThreadPlan,
295 QueueThreadPlanForStepOut, (uint32_t, bool),
296 frame_idx_to_step_to, first_insn);
298 SBError error;
299 return LLDB_RECORD_RESULT(
300 QueueThreadPlanForStepOut(frame_idx_to_step_to, first_insn, error));
303 SBThreadPlan
304 SBThreadPlan::QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to,
305 bool first_insn, SBError &error) {
306 LLDB_RECORD_METHOD(lldb::SBThreadPlan, SBThreadPlan,
307 QueueThreadPlanForStepOut,
308 (uint32_t, bool, lldb::SBError &), frame_idx_to_step_to,
309 first_insn, error);
311 if (m_opaque_sp) {
312 SymbolContext sc;
313 sc = m_opaque_sp->GetThread().GetStackFrameAtIndex(0)->GetSymbolContext(
314 lldb::eSymbolContextEverything);
316 Status plan_status;
317 SBThreadPlan plan =
318 SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepOut(
319 false, &sc, first_insn, false, eVoteYes, eVoteNoOpinion,
320 frame_idx_to_step_to, plan_status));
322 if (plan_status.Fail())
323 error.SetErrorString(plan_status.AsCString());
325 return LLDB_RECORD_RESULT(plan);
326 } else {
327 return LLDB_RECORD_RESULT(SBThreadPlan());
331 SBThreadPlan
332 SBThreadPlan::QueueThreadPlanForRunToAddress(SBAddress sb_address) {
333 LLDB_RECORD_METHOD(lldb::SBThreadPlan, SBThreadPlan,
334 QueueThreadPlanForRunToAddress, (lldb::SBAddress),
335 sb_address);
337 SBError error;
338 return LLDB_RECORD_RESULT(QueueThreadPlanForRunToAddress(sb_address, error));
341 SBThreadPlan SBThreadPlan::QueueThreadPlanForRunToAddress(SBAddress sb_address,
342 SBError &error) {
343 LLDB_RECORD_METHOD(lldb::SBThreadPlan, SBThreadPlan,
344 QueueThreadPlanForRunToAddress,
345 (lldb::SBAddress, lldb::SBError &), sb_address, error);
347 if (m_opaque_sp) {
348 Address *address = sb_address.get();
349 if (!address)
350 return LLDB_RECORD_RESULT(SBThreadPlan());
352 Status plan_status;
353 SBThreadPlan plan =
354 SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForRunToAddress(
355 false, *address, false, plan_status));
357 if (plan_status.Fail())
358 error.SetErrorString(plan_status.AsCString());
360 return LLDB_RECORD_RESULT(plan);
361 } else {
362 return LLDB_RECORD_RESULT(SBThreadPlan());
366 SBThreadPlan
367 SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name) {
368 LLDB_RECORD_METHOD(lldb::SBThreadPlan, SBThreadPlan,
369 QueueThreadPlanForStepScripted, (const char *),
370 script_class_name);
372 SBError error;
373 return LLDB_RECORD_RESULT(
374 QueueThreadPlanForStepScripted(script_class_name, error));
377 SBThreadPlan
378 SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name,
379 SBError &error) {
380 LLDB_RECORD_METHOD(lldb::SBThreadPlan, SBThreadPlan,
381 QueueThreadPlanForStepScripted,
382 (const char *, lldb::SBError &), script_class_name, error);
384 if (m_opaque_sp) {
385 Status plan_status;
386 StructuredData::ObjectSP empty_args;
387 SBThreadPlan plan =
388 SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepScripted(
389 false, script_class_name, empty_args, false, plan_status));
391 if (plan_status.Fail())
392 error.SetErrorString(plan_status.AsCString());
394 return LLDB_RECORD_RESULT(plan);
395 } else {
396 return LLDB_RECORD_RESULT(SBThreadPlan());
400 SBThreadPlan
401 SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name,
402 lldb::SBStructuredData &args_data,
403 SBError &error) {
404 LLDB_RECORD_METHOD(lldb::SBThreadPlan, SBThreadPlan,
405 QueueThreadPlanForStepScripted,
406 (const char *, lldb::SBStructuredData &, lldb::SBError &),
407 script_class_name, args_data, error);
409 if (m_opaque_sp) {
410 Status plan_status;
411 StructuredData::ObjectSP args_obj = args_data.m_impl_up->GetObjectSP();
412 SBThreadPlan plan =
413 SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepScripted(
414 false, script_class_name, args_obj, false, plan_status));
416 if (plan_status.Fail())
417 error.SetErrorString(plan_status.AsCString());
419 return LLDB_RECORD_RESULT(plan);
420 } else {
421 return LLDB_RECORD_RESULT(SBThreadPlan());
425 namespace lldb_private {
426 namespace repro {
428 template <>
429 void RegisterMethods<SBThreadPlan>(Registry &R) {
430 LLDB_REGISTER_CONSTRUCTOR(SBThreadPlan, ());
431 LLDB_REGISTER_CONSTRUCTOR(SBThreadPlan, (const lldb::ThreadPlanSP &));
432 LLDB_REGISTER_CONSTRUCTOR(SBThreadPlan, (const lldb::SBThreadPlan &));
433 LLDB_REGISTER_CONSTRUCTOR(SBThreadPlan, (lldb::SBThread &, const char *));
434 LLDB_REGISTER_CONSTRUCTOR(SBThreadPlan, (lldb::SBThread &, const char *,
435 lldb::SBStructuredData &));
436 LLDB_REGISTER_METHOD(const lldb::SBThreadPlan &,
437 SBThreadPlan, operator=,(const lldb::SBThreadPlan &));
438 LLDB_REGISTER_METHOD_CONST(bool, SBThreadPlan, IsValid, ());
439 LLDB_REGISTER_METHOD_CONST(bool, SBThreadPlan, operator bool, ());
440 LLDB_REGISTER_METHOD(void, SBThreadPlan, Clear, ());
441 LLDB_REGISTER_METHOD(lldb::StopReason, SBThreadPlan, GetStopReason, ());
442 LLDB_REGISTER_METHOD(size_t, SBThreadPlan, GetStopReasonDataCount, ());
443 LLDB_REGISTER_METHOD(uint64_t, SBThreadPlan, GetStopReasonDataAtIndex,
444 (uint32_t));
445 LLDB_REGISTER_METHOD_CONST(lldb::SBThread, SBThreadPlan, GetThread, ());
446 LLDB_REGISTER_METHOD_CONST(bool, SBThreadPlan, GetDescription,
447 (lldb::SBStream &));
448 LLDB_REGISTER_METHOD(void, SBThreadPlan, SetPlanComplete, (bool));
449 LLDB_REGISTER_METHOD(bool, SBThreadPlan, IsPlanComplete, ());
450 LLDB_REGISTER_METHOD(bool, SBThreadPlan, IsPlanStale, ());
451 LLDB_REGISTER_METHOD(bool, SBThreadPlan, IsValid, ());
452 LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan,
453 QueueThreadPlanForStepOverRange,
454 (lldb::SBAddress &, lldb::addr_t));
455 LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan,
456 QueueThreadPlanForStepOverRange,
457 (lldb::SBAddress &, lldb::addr_t, lldb::SBError &));
458 LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan,
459 QueueThreadPlanForStepInRange,
460 (lldb::SBAddress &, lldb::addr_t));
461 LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan,
462 QueueThreadPlanForStepInRange,
463 (lldb::SBAddress &, lldb::addr_t, lldb::SBError &));
464 LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan,
465 QueueThreadPlanForStepOut, (uint32_t, bool));
466 LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan,
467 QueueThreadPlanForStepOut,
468 (uint32_t, bool, lldb::SBError &));
469 LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan,
470 QueueThreadPlanForRunToAddress, (lldb::SBAddress));
471 LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan,
472 QueueThreadPlanForRunToAddress,
473 (lldb::SBAddress, lldb::SBError &));
474 LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan,
475 QueueThreadPlanForStepScripted, (const char *));
476 LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan,
477 QueueThreadPlanForStepScripted,
478 (const char *, lldb::SBError &));
479 LLDB_REGISTER_METHOD(lldb::SBThreadPlan, SBThreadPlan,
480 QueueThreadPlanForStepScripted,
481 (const char *, lldb::SBStructuredData &,
482 lldb::SBError &));