1dda28197Spatrick //===-- SBBlock.cpp -------------------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick
9061da546Spatrick #include "lldb/API/SBBlock.h"
10061da546Spatrick #include "lldb/API/SBAddress.h"
11061da546Spatrick #include "lldb/API/SBFileSpec.h"
12061da546Spatrick #include "lldb/API/SBFrame.h"
13061da546Spatrick #include "lldb/API/SBStream.h"
14061da546Spatrick #include "lldb/API/SBValue.h"
15061da546Spatrick #include "lldb/Core/AddressRange.h"
16061da546Spatrick #include "lldb/Core/ValueObjectVariable.h"
17061da546Spatrick #include "lldb/Symbol/Block.h"
18061da546Spatrick #include "lldb/Symbol/Function.h"
19061da546Spatrick #include "lldb/Symbol/SymbolContext.h"
20061da546Spatrick #include "lldb/Symbol/VariableList.h"
21061da546Spatrick #include "lldb/Target/StackFrame.h"
22061da546Spatrick #include "lldb/Target/Target.h"
23*f6aab3d8Srobert #include "lldb/Utility/Instrumentation.h"
24061da546Spatrick
25061da546Spatrick using namespace lldb;
26061da546Spatrick using namespace lldb_private;
27061da546Spatrick
SBBlock()28*f6aab3d8Srobert SBBlock::SBBlock() { LLDB_INSTRUMENT_VA(this); }
29061da546Spatrick
SBBlock(lldb_private::Block * lldb_object_ptr)30061da546Spatrick SBBlock::SBBlock(lldb_private::Block *lldb_object_ptr)
31061da546Spatrick : m_opaque_ptr(lldb_object_ptr) {}
32061da546Spatrick
SBBlock(const SBBlock & rhs)33061da546Spatrick SBBlock::SBBlock(const SBBlock &rhs) : m_opaque_ptr(rhs.m_opaque_ptr) {
34*f6aab3d8Srobert LLDB_INSTRUMENT_VA(this, rhs);
35061da546Spatrick }
36061da546Spatrick
operator =(const SBBlock & rhs)37061da546Spatrick const SBBlock &SBBlock::operator=(const SBBlock &rhs) {
38*f6aab3d8Srobert LLDB_INSTRUMENT_VA(this, rhs);
39061da546Spatrick
40061da546Spatrick m_opaque_ptr = rhs.m_opaque_ptr;
41*f6aab3d8Srobert return *this;
42061da546Spatrick }
43061da546Spatrick
~SBBlock()44061da546Spatrick SBBlock::~SBBlock() { m_opaque_ptr = nullptr; }
45061da546Spatrick
IsValid() const46061da546Spatrick bool SBBlock::IsValid() const {
47*f6aab3d8Srobert LLDB_INSTRUMENT_VA(this);
48061da546Spatrick return this->operator bool();
49061da546Spatrick }
operator bool() const50061da546Spatrick SBBlock::operator bool() const {
51*f6aab3d8Srobert LLDB_INSTRUMENT_VA(this);
52061da546Spatrick
53061da546Spatrick return m_opaque_ptr != nullptr;
54061da546Spatrick }
55061da546Spatrick
IsInlined() const56061da546Spatrick bool SBBlock::IsInlined() const {
57*f6aab3d8Srobert LLDB_INSTRUMENT_VA(this);
58061da546Spatrick
59061da546Spatrick if (m_opaque_ptr)
60061da546Spatrick return m_opaque_ptr->GetInlinedFunctionInfo() != nullptr;
61061da546Spatrick return false;
62061da546Spatrick }
63061da546Spatrick
GetInlinedName() const64061da546Spatrick const char *SBBlock::GetInlinedName() const {
65*f6aab3d8Srobert LLDB_INSTRUMENT_VA(this);
66061da546Spatrick
67061da546Spatrick if (m_opaque_ptr) {
68061da546Spatrick const InlineFunctionInfo *inlined_info =
69061da546Spatrick m_opaque_ptr->GetInlinedFunctionInfo();
70061da546Spatrick if (inlined_info) {
71dda28197Spatrick return inlined_info->GetName().AsCString(nullptr);
72061da546Spatrick }
73061da546Spatrick }
74061da546Spatrick return nullptr;
75061da546Spatrick }
76061da546Spatrick
GetInlinedCallSiteFile() const77061da546Spatrick SBFileSpec SBBlock::GetInlinedCallSiteFile() const {
78*f6aab3d8Srobert LLDB_INSTRUMENT_VA(this);
79061da546Spatrick
80061da546Spatrick SBFileSpec sb_file;
81061da546Spatrick if (m_opaque_ptr) {
82061da546Spatrick const InlineFunctionInfo *inlined_info =
83061da546Spatrick m_opaque_ptr->GetInlinedFunctionInfo();
84061da546Spatrick if (inlined_info)
85061da546Spatrick sb_file.SetFileSpec(inlined_info->GetCallSite().GetFile());
86061da546Spatrick }
87*f6aab3d8Srobert return sb_file;
88061da546Spatrick }
89061da546Spatrick
GetInlinedCallSiteLine() const90061da546Spatrick uint32_t SBBlock::GetInlinedCallSiteLine() const {
91*f6aab3d8Srobert LLDB_INSTRUMENT_VA(this);
92061da546Spatrick
93061da546Spatrick if (m_opaque_ptr) {
94061da546Spatrick const InlineFunctionInfo *inlined_info =
95061da546Spatrick m_opaque_ptr->GetInlinedFunctionInfo();
96061da546Spatrick if (inlined_info)
97061da546Spatrick return inlined_info->GetCallSite().GetLine();
98061da546Spatrick }
99061da546Spatrick return 0;
100061da546Spatrick }
101061da546Spatrick
GetInlinedCallSiteColumn() const102061da546Spatrick uint32_t SBBlock::GetInlinedCallSiteColumn() const {
103*f6aab3d8Srobert LLDB_INSTRUMENT_VA(this);
104061da546Spatrick
105061da546Spatrick if (m_opaque_ptr) {
106061da546Spatrick const InlineFunctionInfo *inlined_info =
107061da546Spatrick m_opaque_ptr->GetInlinedFunctionInfo();
108061da546Spatrick if (inlined_info)
109061da546Spatrick return inlined_info->GetCallSite().GetColumn();
110061da546Spatrick }
111061da546Spatrick return 0;
112061da546Spatrick }
113061da546Spatrick
AppendVariables(bool can_create,bool get_parent_variables,lldb_private::VariableList * var_list)114061da546Spatrick void SBBlock::AppendVariables(bool can_create, bool get_parent_variables,
115061da546Spatrick lldb_private::VariableList *var_list) {
116061da546Spatrick if (IsValid()) {
117061da546Spatrick bool show_inline = true;
118061da546Spatrick m_opaque_ptr->AppendVariables(can_create, get_parent_variables, show_inline,
119061da546Spatrick [](Variable *) { return true; }, var_list);
120061da546Spatrick }
121061da546Spatrick }
122061da546Spatrick
GetParent()123061da546Spatrick SBBlock SBBlock::GetParent() {
124*f6aab3d8Srobert LLDB_INSTRUMENT_VA(this);
125061da546Spatrick
126061da546Spatrick SBBlock sb_block;
127061da546Spatrick if (m_opaque_ptr)
128061da546Spatrick sb_block.m_opaque_ptr = m_opaque_ptr->GetParent();
129*f6aab3d8Srobert return sb_block;
130061da546Spatrick }
131061da546Spatrick
GetContainingInlinedBlock()132061da546Spatrick lldb::SBBlock SBBlock::GetContainingInlinedBlock() {
133*f6aab3d8Srobert LLDB_INSTRUMENT_VA(this);
134061da546Spatrick
135061da546Spatrick SBBlock sb_block;
136061da546Spatrick if (m_opaque_ptr)
137061da546Spatrick sb_block.m_opaque_ptr = m_opaque_ptr->GetContainingInlinedBlock();
138*f6aab3d8Srobert return sb_block;
139061da546Spatrick }
140061da546Spatrick
GetSibling()141061da546Spatrick SBBlock SBBlock::GetSibling() {
142*f6aab3d8Srobert LLDB_INSTRUMENT_VA(this);
143061da546Spatrick
144061da546Spatrick SBBlock sb_block;
145061da546Spatrick if (m_opaque_ptr)
146061da546Spatrick sb_block.m_opaque_ptr = m_opaque_ptr->GetSibling();
147*f6aab3d8Srobert return sb_block;
148061da546Spatrick }
149061da546Spatrick
GetFirstChild()150061da546Spatrick SBBlock SBBlock::GetFirstChild() {
151*f6aab3d8Srobert LLDB_INSTRUMENT_VA(this);
152061da546Spatrick
153061da546Spatrick SBBlock sb_block;
154061da546Spatrick if (m_opaque_ptr)
155061da546Spatrick sb_block.m_opaque_ptr = m_opaque_ptr->GetFirstChild();
156*f6aab3d8Srobert return sb_block;
157061da546Spatrick }
158061da546Spatrick
GetPtr()159061da546Spatrick lldb_private::Block *SBBlock::GetPtr() { return m_opaque_ptr; }
160061da546Spatrick
SetPtr(lldb_private::Block * block)161061da546Spatrick void SBBlock::SetPtr(lldb_private::Block *block) { m_opaque_ptr = block; }
162061da546Spatrick
GetDescription(SBStream & description)163061da546Spatrick bool SBBlock::GetDescription(SBStream &description) {
164*f6aab3d8Srobert LLDB_INSTRUMENT_VA(this, description);
165061da546Spatrick
166061da546Spatrick Stream &strm = description.ref();
167061da546Spatrick
168061da546Spatrick if (m_opaque_ptr) {
169061da546Spatrick lldb::user_id_t id = m_opaque_ptr->GetID();
170061da546Spatrick strm.Printf("Block: {id: %" PRIu64 "} ", id);
171061da546Spatrick if (IsInlined()) {
172061da546Spatrick strm.Printf(" (inlined, '%s') ", GetInlinedName());
173061da546Spatrick }
174061da546Spatrick lldb_private::SymbolContext sc;
175061da546Spatrick m_opaque_ptr->CalculateSymbolContext(&sc);
176061da546Spatrick if (sc.function) {
177061da546Spatrick m_opaque_ptr->DumpAddressRanges(
178061da546Spatrick &strm,
179061da546Spatrick sc.function->GetAddressRange().GetBaseAddress().GetFileAddress());
180061da546Spatrick }
181061da546Spatrick } else
182061da546Spatrick strm.PutCString("No value");
183061da546Spatrick
184061da546Spatrick return true;
185061da546Spatrick }
186061da546Spatrick
GetNumRanges()187061da546Spatrick uint32_t SBBlock::GetNumRanges() {
188*f6aab3d8Srobert LLDB_INSTRUMENT_VA(this);
189061da546Spatrick
190061da546Spatrick if (m_opaque_ptr)
191061da546Spatrick return m_opaque_ptr->GetNumRanges();
192061da546Spatrick return 0;
193061da546Spatrick }
194061da546Spatrick
GetRangeStartAddress(uint32_t idx)195061da546Spatrick lldb::SBAddress SBBlock::GetRangeStartAddress(uint32_t idx) {
196*f6aab3d8Srobert LLDB_INSTRUMENT_VA(this, idx);
197061da546Spatrick
198061da546Spatrick lldb::SBAddress sb_addr;
199061da546Spatrick if (m_opaque_ptr) {
200061da546Spatrick AddressRange range;
201061da546Spatrick if (m_opaque_ptr->GetRangeAtIndex(idx, range)) {
202061da546Spatrick sb_addr.ref() = range.GetBaseAddress();
203061da546Spatrick }
204061da546Spatrick }
205*f6aab3d8Srobert return sb_addr;
206061da546Spatrick }
207061da546Spatrick
GetRangeEndAddress(uint32_t idx)208061da546Spatrick lldb::SBAddress SBBlock::GetRangeEndAddress(uint32_t idx) {
209*f6aab3d8Srobert LLDB_INSTRUMENT_VA(this, idx);
210061da546Spatrick
211061da546Spatrick lldb::SBAddress sb_addr;
212061da546Spatrick if (m_opaque_ptr) {
213061da546Spatrick AddressRange range;
214061da546Spatrick if (m_opaque_ptr->GetRangeAtIndex(idx, range)) {
215061da546Spatrick sb_addr.ref() = range.GetBaseAddress();
216061da546Spatrick sb_addr.ref().Slide(range.GetByteSize());
217061da546Spatrick }
218061da546Spatrick }
219*f6aab3d8Srobert return sb_addr;
220061da546Spatrick }
221061da546Spatrick
GetRangeIndexForBlockAddress(lldb::SBAddress block_addr)222061da546Spatrick uint32_t SBBlock::GetRangeIndexForBlockAddress(lldb::SBAddress block_addr) {
223*f6aab3d8Srobert LLDB_INSTRUMENT_VA(this, block_addr);
224061da546Spatrick
225061da546Spatrick if (m_opaque_ptr && block_addr.IsValid()) {
226061da546Spatrick return m_opaque_ptr->GetRangeIndexContainingAddress(block_addr.ref());
227061da546Spatrick }
228061da546Spatrick
229061da546Spatrick return UINT32_MAX;
230061da546Spatrick }
231061da546Spatrick
GetVariables(lldb::SBFrame & frame,bool arguments,bool locals,bool statics,lldb::DynamicValueType use_dynamic)232061da546Spatrick lldb::SBValueList SBBlock::GetVariables(lldb::SBFrame &frame, bool arguments,
233061da546Spatrick bool locals, bool statics,
234061da546Spatrick lldb::DynamicValueType use_dynamic) {
235*f6aab3d8Srobert LLDB_INSTRUMENT_VA(this, frame, arguments, locals, statics, use_dynamic);
236061da546Spatrick
237061da546Spatrick Block *block = GetPtr();
238061da546Spatrick SBValueList value_list;
239061da546Spatrick if (block) {
240061da546Spatrick StackFrameSP frame_sp(frame.GetFrameSP());
241061da546Spatrick VariableListSP variable_list_sp(block->GetBlockVariableList(true));
242061da546Spatrick
243061da546Spatrick if (variable_list_sp) {
244061da546Spatrick const size_t num_variables = variable_list_sp->GetSize();
245061da546Spatrick if (num_variables) {
246061da546Spatrick for (size_t i = 0; i < num_variables; ++i) {
247061da546Spatrick VariableSP variable_sp(variable_list_sp->GetVariableAtIndex(i));
248061da546Spatrick if (variable_sp) {
249061da546Spatrick bool add_variable = false;
250061da546Spatrick switch (variable_sp->GetScope()) {
251061da546Spatrick case eValueTypeVariableGlobal:
252061da546Spatrick case eValueTypeVariableStatic:
253061da546Spatrick case eValueTypeVariableThreadLocal:
254061da546Spatrick add_variable = statics;
255061da546Spatrick break;
256061da546Spatrick
257061da546Spatrick case eValueTypeVariableArgument:
258061da546Spatrick add_variable = arguments;
259061da546Spatrick break;
260061da546Spatrick
261061da546Spatrick case eValueTypeVariableLocal:
262061da546Spatrick add_variable = locals;
263061da546Spatrick break;
264061da546Spatrick
265061da546Spatrick default:
266061da546Spatrick break;
267061da546Spatrick }
268061da546Spatrick if (add_variable) {
269061da546Spatrick if (frame_sp) {
270061da546Spatrick lldb::ValueObjectSP valobj_sp(
271061da546Spatrick frame_sp->GetValueObjectForFrameVariable(variable_sp,
272061da546Spatrick eNoDynamicValues));
273061da546Spatrick SBValue value_sb;
274061da546Spatrick value_sb.SetSP(valobj_sp, use_dynamic);
275061da546Spatrick value_list.Append(value_sb);
276061da546Spatrick }
277061da546Spatrick }
278061da546Spatrick }
279061da546Spatrick }
280061da546Spatrick }
281061da546Spatrick }
282061da546Spatrick }
283*f6aab3d8Srobert return value_list;
284061da546Spatrick }
285061da546Spatrick
GetVariables(lldb::SBTarget & target,bool arguments,bool locals,bool statics)286061da546Spatrick lldb::SBValueList SBBlock::GetVariables(lldb::SBTarget &target, bool arguments,
287061da546Spatrick bool locals, bool statics) {
288*f6aab3d8Srobert LLDB_INSTRUMENT_VA(this, target, arguments, locals, statics);
289061da546Spatrick
290061da546Spatrick Block *block = GetPtr();
291061da546Spatrick
292061da546Spatrick SBValueList value_list;
293061da546Spatrick if (block) {
294061da546Spatrick TargetSP target_sp(target.GetSP());
295061da546Spatrick
296061da546Spatrick VariableListSP variable_list_sp(block->GetBlockVariableList(true));
297061da546Spatrick
298061da546Spatrick if (variable_list_sp) {
299061da546Spatrick const size_t num_variables = variable_list_sp->GetSize();
300061da546Spatrick if (num_variables) {
301061da546Spatrick for (size_t i = 0; i < num_variables; ++i) {
302061da546Spatrick VariableSP variable_sp(variable_list_sp->GetVariableAtIndex(i));
303061da546Spatrick if (variable_sp) {
304061da546Spatrick bool add_variable = false;
305061da546Spatrick switch (variable_sp->GetScope()) {
306061da546Spatrick case eValueTypeVariableGlobal:
307061da546Spatrick case eValueTypeVariableStatic:
308061da546Spatrick case eValueTypeVariableThreadLocal:
309061da546Spatrick add_variable = statics;
310061da546Spatrick break;
311061da546Spatrick
312061da546Spatrick case eValueTypeVariableArgument:
313061da546Spatrick add_variable = arguments;
314061da546Spatrick break;
315061da546Spatrick
316061da546Spatrick case eValueTypeVariableLocal:
317061da546Spatrick add_variable = locals;
318061da546Spatrick break;
319061da546Spatrick
320061da546Spatrick default:
321061da546Spatrick break;
322061da546Spatrick }
323061da546Spatrick if (add_variable) {
324061da546Spatrick if (target_sp)
325061da546Spatrick value_list.Append(
326061da546Spatrick ValueObjectVariable::Create(target_sp.get(), variable_sp));
327061da546Spatrick }
328061da546Spatrick }
329061da546Spatrick }
330061da546Spatrick }
331061da546Spatrick }
332061da546Spatrick }
333*f6aab3d8Srobert return value_list;
334061da546Spatrick }
335