[lldb][dwarf] Compute fully qualified names on simplified template names with DWARFT...
[llvm-project.git] / lldb / source / API / SBThreadPlan.cpp
blob083a050de8a38139a400601936a065a77ce2961c
1 //===-- SBThreadPlan.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 //===----------------------------------------------------------------------===//
9 #include "lldb/API/SBThread.h"
10 #include "lldb/Utility/Instrumentation.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/StructuredDataImpl.h"
19 #include "lldb/Interpreter/CommandInterpreter.h"
20 #include "lldb/Symbol/CompileUnit.h"
21 #include "lldb/Symbol/SymbolContext.h"
22 #include "lldb/Target/Process.h"
23 #include "lldb/Target/Queue.h"
24 #include "lldb/Target/ScriptedThreadPlan.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/ThreadPlanStepInRange.h"
31 #include "lldb/Target/ThreadPlanStepInstruction.h"
32 #include "lldb/Target/ThreadPlanStepOut.h"
33 #include "lldb/Target/ThreadPlanStepRange.h"
34 #include "lldb/Utility/State.h"
35 #include "lldb/Utility/Stream.h"
36 #include "lldb/Utility/StructuredData.h"
38 #include "lldb/API/SBAddress.h"
39 #include "lldb/API/SBDebugger.h"
40 #include "lldb/API/SBEvent.h"
41 #include "lldb/API/SBFrame.h"
42 #include "lldb/API/SBProcess.h"
43 #include "lldb/API/SBThreadPlan.h"
44 #include "lldb/API/SBValue.h"
46 #include <memory>
48 using namespace lldb;
49 using namespace lldb_private;
51 // Constructors
52 SBThreadPlan::SBThreadPlan() { LLDB_INSTRUMENT_VA(this); }
54 SBThreadPlan::SBThreadPlan(const ThreadPlanSP &lldb_object_sp)
55 : m_opaque_wp(lldb_object_sp) {
56 LLDB_INSTRUMENT_VA(this, lldb_object_sp);
59 SBThreadPlan::SBThreadPlan(const SBThreadPlan &rhs)
60 : m_opaque_wp(rhs.m_opaque_wp) {
61 LLDB_INSTRUMENT_VA(this, rhs);
64 SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name) {
65 LLDB_INSTRUMENT_VA(this, sb_thread, class_name);
67 Thread *thread = sb_thread.get();
68 if (thread)
69 m_opaque_wp = std::make_shared<ScriptedThreadPlan>(*thread, class_name,
70 StructuredDataImpl());
73 SBThreadPlan::SBThreadPlan(lldb::SBThread &sb_thread, const char *class_name,
74 lldb::SBStructuredData &args_data) {
75 LLDB_INSTRUMENT_VA(this, sb_thread, class_name, args_data);
77 Thread *thread = sb_thread.get();
78 if (thread)
79 m_opaque_wp = std::make_shared<ScriptedThreadPlan>(*thread, class_name,
80 *args_data.m_impl_up);
83 // Assignment operator
85 const lldb::SBThreadPlan &SBThreadPlan::operator=(const SBThreadPlan &rhs) {
86 LLDB_INSTRUMENT_VA(this, rhs);
88 if (this != &rhs)
89 m_opaque_wp = rhs.m_opaque_wp;
90 return *this;
92 // Destructor
93 SBThreadPlan::~SBThreadPlan() = default;
95 bool SBThreadPlan::IsValid() const {
96 LLDB_INSTRUMENT_VA(this);
97 return this->operator bool();
99 SBThreadPlan::operator bool() const {
100 LLDB_INSTRUMENT_VA(this);
102 return static_cast<bool>(GetSP());
105 void SBThreadPlan::Clear() {
106 LLDB_INSTRUMENT_VA(this);
108 m_opaque_wp.reset();
111 lldb::StopReason SBThreadPlan::GetStopReason() {
112 LLDB_INSTRUMENT_VA(this);
114 return eStopReasonNone;
117 size_t SBThreadPlan::GetStopReasonDataCount() {
118 LLDB_INSTRUMENT_VA(this);
120 return 0;
123 uint64_t SBThreadPlan::GetStopReasonDataAtIndex(uint32_t idx) {
124 LLDB_INSTRUMENT_VA(this, idx);
126 return 0;
129 SBThread SBThreadPlan::GetThread() const {
130 LLDB_INSTRUMENT_VA(this);
132 ThreadPlanSP thread_plan_sp(GetSP());
133 if (thread_plan_sp) {
134 return SBThread(thread_plan_sp->GetThread().shared_from_this());
135 } else
136 return SBThread();
139 bool SBThreadPlan::GetDescription(lldb::SBStream &description) const {
140 LLDB_INSTRUMENT_VA(this, description);
142 ThreadPlanSP thread_plan_sp(GetSP());
143 if (thread_plan_sp) {
144 thread_plan_sp->GetDescription(description.get(), eDescriptionLevelFull);
145 } else {
146 description.Printf("Empty SBThreadPlan");
148 return true;
151 void SBThreadPlan::SetThreadPlan(const ThreadPlanSP &lldb_object_wp) {
152 m_opaque_wp = lldb_object_wp;
155 void SBThreadPlan::SetPlanComplete(bool success) {
156 LLDB_INSTRUMENT_VA(this, success);
158 ThreadPlanSP thread_plan_sp(GetSP());
159 if (thread_plan_sp)
160 thread_plan_sp->SetPlanComplete(success);
163 bool SBThreadPlan::IsPlanComplete() {
164 LLDB_INSTRUMENT_VA(this);
166 ThreadPlanSP thread_plan_sp(GetSP());
167 if (thread_plan_sp)
168 return thread_plan_sp->IsPlanComplete();
169 return true;
172 bool SBThreadPlan::IsPlanStale() {
173 LLDB_INSTRUMENT_VA(this);
175 ThreadPlanSP thread_plan_sp(GetSP());
176 if (thread_plan_sp)
177 return thread_plan_sp->IsPlanStale();
178 return true;
181 bool SBThreadPlan::IsValid() {
182 LLDB_INSTRUMENT_VA(this);
184 ThreadPlanSP thread_plan_sp(GetSP());
185 if (thread_plan_sp)
186 return thread_plan_sp->ValidatePlan(nullptr);
187 return false;
190 bool SBThreadPlan::GetStopOthers() {
191 LLDB_INSTRUMENT_VA(this);
193 ThreadPlanSP thread_plan_sp(GetSP());
194 if (thread_plan_sp)
195 return thread_plan_sp->StopOthers();
196 return false;
199 void SBThreadPlan::SetStopOthers(bool stop_others) {
200 LLDB_INSTRUMENT_VA(this, stop_others);
202 ThreadPlanSP thread_plan_sp(GetSP());
203 if (thread_plan_sp)
204 thread_plan_sp->SetStopOthers(stop_others);
207 // This section allows an SBThreadPlan to push another of the common types of
208 // plans...
210 // FIXME, you should only be able to queue thread plans from inside the methods
211 // of a Scripted Thread Plan. Need a way to enforce that.
213 SBThreadPlan
214 SBThreadPlan::QueueThreadPlanForStepOverRange(SBAddress &sb_start_address,
215 lldb::addr_t size) {
216 LLDB_INSTRUMENT_VA(this, sb_start_address, size);
218 SBError error;
219 return QueueThreadPlanForStepOverRange(sb_start_address, size, error);
222 SBThreadPlan SBThreadPlan::QueueThreadPlanForStepOverRange(
223 SBAddress &sb_start_address, lldb::addr_t size, SBError &error) {
224 LLDB_INSTRUMENT_VA(this, sb_start_address, size, error);
226 ThreadPlanSP thread_plan_sp(GetSP());
227 if (thread_plan_sp) {
228 Address *start_address = sb_start_address.get();
229 if (!start_address) {
230 return SBThreadPlan();
233 AddressRange range(*start_address, size);
234 SymbolContext sc;
235 start_address->CalculateSymbolContext(&sc);
236 Status plan_status;
238 SBThreadPlan plan = SBThreadPlan(
239 thread_plan_sp->GetThread().QueueThreadPlanForStepOverRange(
240 false, range, sc, eAllThreads, plan_status));
242 if (plan_status.Fail())
243 error.SetErrorString(plan_status.AsCString());
244 else
245 plan.GetSP()->SetPrivate(true);
247 return plan;
249 return SBThreadPlan();
252 SBThreadPlan
253 SBThreadPlan::QueueThreadPlanForStepInRange(SBAddress &sb_start_address,
254 lldb::addr_t size) {
255 LLDB_INSTRUMENT_VA(this, sb_start_address, size);
257 SBError error;
258 return QueueThreadPlanForStepInRange(sb_start_address, size, error);
261 SBThreadPlan
262 SBThreadPlan::QueueThreadPlanForStepInRange(SBAddress &sb_start_address,
263 lldb::addr_t size, SBError &error) {
264 LLDB_INSTRUMENT_VA(this, sb_start_address, size, error);
266 ThreadPlanSP thread_plan_sp(GetSP());
267 if (thread_plan_sp) {
268 Address *start_address = sb_start_address.get();
269 if (!start_address) {
270 return SBThreadPlan();
273 AddressRange range(*start_address, size);
274 SymbolContext sc;
275 start_address->CalculateSymbolContext(&sc);
277 Status plan_status;
278 SBThreadPlan plan =
279 SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForStepInRange(
280 false, range, sc, nullptr, eAllThreads, plan_status));
282 if (plan_status.Fail())
283 error.SetErrorString(plan_status.AsCString());
284 else
285 plan.GetSP()->SetPrivate(true);
287 return plan;
289 return SBThreadPlan();
292 SBThreadPlan
293 SBThreadPlan::QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to,
294 bool first_insn) {
295 LLDB_INSTRUMENT_VA(this, frame_idx_to_step_to, first_insn);
297 SBError error;
298 return QueueThreadPlanForStepOut(frame_idx_to_step_to, first_insn, error);
301 SBThreadPlan
302 SBThreadPlan::QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to,
303 bool first_insn, SBError &error) {
304 LLDB_INSTRUMENT_VA(this, frame_idx_to_step_to, first_insn, error);
306 ThreadPlanSP thread_plan_sp(GetSP());
307 if (thread_plan_sp) {
308 SymbolContext sc;
309 sc = thread_plan_sp->GetThread().GetStackFrameAtIndex(0)->GetSymbolContext(
310 lldb::eSymbolContextEverything);
312 Status plan_status;
313 SBThreadPlan plan =
314 SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForStepOut(
315 false, &sc, first_insn, false, eVoteYes, eVoteNoOpinion,
316 frame_idx_to_step_to, plan_status));
318 if (plan_status.Fail())
319 error.SetErrorString(plan_status.AsCString());
320 else
321 plan.GetSP()->SetPrivate(true);
323 return plan;
325 return SBThreadPlan();
328 SBThreadPlan
329 SBThreadPlan::QueueThreadPlanForRunToAddress(SBAddress sb_address) {
330 LLDB_INSTRUMENT_VA(this, sb_address);
332 SBError error;
333 return QueueThreadPlanForRunToAddress(sb_address, error);
336 SBThreadPlan SBThreadPlan::QueueThreadPlanForRunToAddress(SBAddress sb_address,
337 SBError &error) {
338 LLDB_INSTRUMENT_VA(this, sb_address, error);
340 ThreadPlanSP thread_plan_sp(GetSP());
341 if (thread_plan_sp) {
342 Address *address = sb_address.get();
343 if (!address)
344 return SBThreadPlan();
346 Status plan_status;
347 SBThreadPlan plan =
348 SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForRunToAddress(
349 false, *address, false, plan_status));
351 if (plan_status.Fail())
352 error.SetErrorString(plan_status.AsCString());
353 else
354 plan.GetSP()->SetPrivate(true);
356 return plan;
358 return SBThreadPlan();
361 SBThreadPlan
362 SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name) {
363 LLDB_INSTRUMENT_VA(this, script_class_name);
365 SBError error;
366 return QueueThreadPlanForStepScripted(script_class_name, error);
369 SBThreadPlan
370 SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name,
371 SBError &error) {
372 LLDB_INSTRUMENT_VA(this, script_class_name, error);
374 ThreadPlanSP thread_plan_sp(GetSP());
375 if (thread_plan_sp) {
376 Status plan_status;
377 StructuredData::ObjectSP empty_args;
378 SBThreadPlan plan =
379 SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForStepScripted(
380 false, script_class_name, empty_args, false, plan_status));
382 if (plan_status.Fail())
383 error.SetErrorString(plan_status.AsCString());
384 else
385 plan.GetSP()->SetPrivate(true);
387 return plan;
389 return SBThreadPlan();
392 SBThreadPlan
393 SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name,
394 lldb::SBStructuredData &args_data,
395 SBError &error) {
396 LLDB_INSTRUMENT_VA(this, script_class_name, args_data, error);
398 ThreadPlanSP thread_plan_sp(GetSP());
399 if (thread_plan_sp) {
400 Status plan_status;
401 StructuredData::ObjectSP args_obj = args_data.m_impl_up->GetObjectSP();
402 SBThreadPlan plan =
403 SBThreadPlan(thread_plan_sp->GetThread().QueueThreadPlanForStepScripted(
404 false, script_class_name, args_obj, false, plan_status));
406 if (plan_status.Fail())
407 error.SetErrorString(plan_status.AsCString());
408 else
409 plan.GetSP()->SetPrivate(true);
411 return plan;
412 } else {
413 return SBThreadPlan();