1cfca06d7SDimitry Andric //===-- SBBlock.cpp -------------------------------------------------------===//
2f034231aSEd Maste //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f034231aSEd Maste //
7f034231aSEd Maste //===----------------------------------------------------------------------===//
8f034231aSEd Maste
9f034231aSEd Maste #include "lldb/API/SBBlock.h"
10f034231aSEd Maste #include "lldb/API/SBAddress.h"
11f034231aSEd Maste #include "lldb/API/SBFileSpec.h"
12f034231aSEd Maste #include "lldb/API/SBFrame.h"
13f034231aSEd Maste #include "lldb/API/SBStream.h"
14f034231aSEd Maste #include "lldb/API/SBValue.h"
15f034231aSEd Maste #include "lldb/Core/AddressRange.h"
16ac9a064cSDimitry Andric #include "lldb/Core/AddressRangeListImpl.h"
17f034231aSEd Maste #include "lldb/Core/ValueObjectVariable.h"
18f034231aSEd Maste #include "lldb/Symbol/Block.h"
19f034231aSEd Maste #include "lldb/Symbol/Function.h"
20f034231aSEd Maste #include "lldb/Symbol/SymbolContext.h"
21f034231aSEd Maste #include "lldb/Symbol/VariableList.h"
22f034231aSEd Maste #include "lldb/Target/StackFrame.h"
23f034231aSEd Maste #include "lldb/Target/Target.h"
246f8fc217SDimitry Andric #include "lldb/Utility/Instrumentation.h"
25f034231aSEd Maste
26f034231aSEd Maste using namespace lldb;
27f034231aSEd Maste using namespace lldb_private;
28f034231aSEd Maste
SBBlock()296f8fc217SDimitry Andric SBBlock::SBBlock() { LLDB_INSTRUMENT_VA(this); }
30f034231aSEd Maste
SBBlock(lldb_private::Block * lldb_object_ptr)3114f1b3e8SDimitry Andric SBBlock::SBBlock(lldb_private::Block *lldb_object_ptr)
3214f1b3e8SDimitry Andric : m_opaque_ptr(lldb_object_ptr) {}
33f034231aSEd Maste
SBBlock(const SBBlock & rhs)345f29bb8aSDimitry Andric SBBlock::SBBlock(const SBBlock &rhs) : m_opaque_ptr(rhs.m_opaque_ptr) {
356f8fc217SDimitry Andric LLDB_INSTRUMENT_VA(this, rhs);
36f034231aSEd Maste }
37f034231aSEd Maste
operator =(const SBBlock & rhs)385f29bb8aSDimitry Andric const SBBlock &SBBlock::operator=(const SBBlock &rhs) {
396f8fc217SDimitry Andric LLDB_INSTRUMENT_VA(this, rhs);
40f034231aSEd Maste
415f29bb8aSDimitry Andric m_opaque_ptr = rhs.m_opaque_ptr;
426f8fc217SDimitry Andric return *this;
435f29bb8aSDimitry Andric }
445f29bb8aSDimitry Andric
~SBBlock()455f29bb8aSDimitry Andric SBBlock::~SBBlock() { m_opaque_ptr = nullptr; }
465f29bb8aSDimitry Andric
IsValid() const475f29bb8aSDimitry Andric bool SBBlock::IsValid() const {
486f8fc217SDimitry Andric LLDB_INSTRUMENT_VA(this);
495f29bb8aSDimitry Andric return this->operator bool();
505f29bb8aSDimitry Andric }
operator bool() const515f29bb8aSDimitry Andric SBBlock::operator bool() const {
526f8fc217SDimitry Andric LLDB_INSTRUMENT_VA(this);
535f29bb8aSDimitry Andric
545f29bb8aSDimitry Andric return m_opaque_ptr != nullptr;
555f29bb8aSDimitry Andric }
56f034231aSEd Maste
IsInlined() const5714f1b3e8SDimitry Andric bool SBBlock::IsInlined() const {
586f8fc217SDimitry Andric LLDB_INSTRUMENT_VA(this);
595f29bb8aSDimitry Andric
60f034231aSEd Maste if (m_opaque_ptr)
615f29bb8aSDimitry Andric return m_opaque_ptr->GetInlinedFunctionInfo() != nullptr;
62f034231aSEd Maste return false;
63f034231aSEd Maste }
64f034231aSEd Maste
GetInlinedName() const6514f1b3e8SDimitry Andric const char *SBBlock::GetInlinedName() const {
666f8fc217SDimitry Andric LLDB_INSTRUMENT_VA(this);
675f29bb8aSDimitry Andric
6814f1b3e8SDimitry Andric if (m_opaque_ptr) {
6914f1b3e8SDimitry Andric const InlineFunctionInfo *inlined_info =
7014f1b3e8SDimitry Andric m_opaque_ptr->GetInlinedFunctionInfo();
7114f1b3e8SDimitry Andric if (inlined_info) {
72cfca06d7SDimitry Andric return inlined_info->GetName().AsCString(nullptr);
73027f1c96SDimitry Andric }
74f034231aSEd Maste }
755f29bb8aSDimitry Andric return nullptr;
76f034231aSEd Maste }
77f034231aSEd Maste
GetInlinedCallSiteFile() const7814f1b3e8SDimitry Andric SBFileSpec SBBlock::GetInlinedCallSiteFile() const {
796f8fc217SDimitry Andric LLDB_INSTRUMENT_VA(this);
805f29bb8aSDimitry Andric
81f034231aSEd Maste SBFileSpec sb_file;
8214f1b3e8SDimitry Andric if (m_opaque_ptr) {
8314f1b3e8SDimitry Andric const InlineFunctionInfo *inlined_info =
8414f1b3e8SDimitry Andric m_opaque_ptr->GetInlinedFunctionInfo();
85f034231aSEd Maste if (inlined_info)
86f034231aSEd Maste sb_file.SetFileSpec(inlined_info->GetCallSite().GetFile());
87f034231aSEd Maste }
886f8fc217SDimitry Andric return sb_file;
89f034231aSEd Maste }
90f034231aSEd Maste
GetInlinedCallSiteLine() const9114f1b3e8SDimitry Andric uint32_t SBBlock::GetInlinedCallSiteLine() const {
926f8fc217SDimitry Andric LLDB_INSTRUMENT_VA(this);
935f29bb8aSDimitry Andric
9414f1b3e8SDimitry Andric if (m_opaque_ptr) {
9514f1b3e8SDimitry Andric const InlineFunctionInfo *inlined_info =
9614f1b3e8SDimitry Andric m_opaque_ptr->GetInlinedFunctionInfo();
97f034231aSEd Maste if (inlined_info)
98f034231aSEd Maste return inlined_info->GetCallSite().GetLine();
99f034231aSEd Maste }
100f034231aSEd Maste return 0;
101f034231aSEd Maste }
102f034231aSEd Maste
GetInlinedCallSiteColumn() const10314f1b3e8SDimitry Andric uint32_t SBBlock::GetInlinedCallSiteColumn() const {
1046f8fc217SDimitry Andric LLDB_INSTRUMENT_VA(this);
1055f29bb8aSDimitry Andric
10614f1b3e8SDimitry Andric if (m_opaque_ptr) {
10714f1b3e8SDimitry Andric const InlineFunctionInfo *inlined_info =
10814f1b3e8SDimitry Andric m_opaque_ptr->GetInlinedFunctionInfo();
109f034231aSEd Maste if (inlined_info)
110f034231aSEd Maste return inlined_info->GetCallSite().GetColumn();
111f034231aSEd Maste }
112f034231aSEd Maste return 0;
113f034231aSEd Maste }
114f034231aSEd Maste
AppendVariables(bool can_create,bool get_parent_variables,lldb_private::VariableList * var_list)11514f1b3e8SDimitry Andric void SBBlock::AppendVariables(bool can_create, bool get_parent_variables,
11614f1b3e8SDimitry Andric lldb_private::VariableList *var_list) {
11714f1b3e8SDimitry Andric if (IsValid()) {
118f034231aSEd Maste bool show_inline = true;
11914f1b3e8SDimitry Andric m_opaque_ptr->AppendVariables(can_create, get_parent_variables, show_inline,
12014f1b3e8SDimitry Andric [](Variable *) { return true; }, var_list);
121f034231aSEd Maste }
122f034231aSEd Maste }
123f034231aSEd Maste
GetParent()12414f1b3e8SDimitry Andric SBBlock SBBlock::GetParent() {
1256f8fc217SDimitry Andric LLDB_INSTRUMENT_VA(this);
1265f29bb8aSDimitry Andric
127f034231aSEd Maste SBBlock sb_block;
128f034231aSEd Maste if (m_opaque_ptr)
129f034231aSEd Maste sb_block.m_opaque_ptr = m_opaque_ptr->GetParent();
1306f8fc217SDimitry Andric return sb_block;
131f034231aSEd Maste }
132f034231aSEd Maste
GetContainingInlinedBlock()13314f1b3e8SDimitry Andric lldb::SBBlock SBBlock::GetContainingInlinedBlock() {
1346f8fc217SDimitry Andric LLDB_INSTRUMENT_VA(this);
1355f29bb8aSDimitry Andric
136f034231aSEd Maste SBBlock sb_block;
137f034231aSEd Maste if (m_opaque_ptr)
138f034231aSEd Maste sb_block.m_opaque_ptr = m_opaque_ptr->GetContainingInlinedBlock();
1396f8fc217SDimitry Andric return sb_block;
140f034231aSEd Maste }
141f034231aSEd Maste
GetSibling()14214f1b3e8SDimitry Andric SBBlock SBBlock::GetSibling() {
1436f8fc217SDimitry Andric LLDB_INSTRUMENT_VA(this);
1445f29bb8aSDimitry Andric
145f034231aSEd Maste SBBlock sb_block;
146f034231aSEd Maste if (m_opaque_ptr)
147f034231aSEd Maste sb_block.m_opaque_ptr = m_opaque_ptr->GetSibling();
1486f8fc217SDimitry Andric return sb_block;
149f034231aSEd Maste }
150f034231aSEd Maste
GetFirstChild()15114f1b3e8SDimitry Andric SBBlock SBBlock::GetFirstChild() {
1526f8fc217SDimitry Andric LLDB_INSTRUMENT_VA(this);
1535f29bb8aSDimitry Andric
154f034231aSEd Maste SBBlock sb_block;
155f034231aSEd Maste if (m_opaque_ptr)
156f034231aSEd Maste sb_block.m_opaque_ptr = m_opaque_ptr->GetFirstChild();
1576f8fc217SDimitry Andric return sb_block;
158f034231aSEd Maste }
159f034231aSEd Maste
GetPtr()16014f1b3e8SDimitry Andric lldb_private::Block *SBBlock::GetPtr() { return m_opaque_ptr; }
161f034231aSEd Maste
SetPtr(lldb_private::Block * block)16214f1b3e8SDimitry Andric void SBBlock::SetPtr(lldb_private::Block *block) { m_opaque_ptr = block; }
163f034231aSEd Maste
GetDescription(SBStream & description)16414f1b3e8SDimitry Andric bool SBBlock::GetDescription(SBStream &description) {
1656f8fc217SDimitry Andric LLDB_INSTRUMENT_VA(this, description);
1665f29bb8aSDimitry Andric
167f034231aSEd Maste Stream &strm = description.ref();
168f034231aSEd Maste
16914f1b3e8SDimitry Andric if (m_opaque_ptr) {
170f034231aSEd Maste lldb::user_id_t id = m_opaque_ptr->GetID();
171f034231aSEd Maste strm.Printf("Block: {id: %" PRIu64 "} ", id);
17214f1b3e8SDimitry Andric if (IsInlined()) {
173f034231aSEd Maste strm.Printf(" (inlined, '%s') ", GetInlinedName());
174f034231aSEd Maste }
175f034231aSEd Maste lldb_private::SymbolContext sc;
176f034231aSEd Maste m_opaque_ptr->CalculateSymbolContext(&sc);
17714f1b3e8SDimitry Andric if (sc.function) {
17814f1b3e8SDimitry Andric m_opaque_ptr->DumpAddressRanges(
17914f1b3e8SDimitry Andric &strm,
180f034231aSEd Maste sc.function->GetAddressRange().GetBaseAddress().GetFileAddress());
181f034231aSEd Maste }
18214f1b3e8SDimitry Andric } else
183f034231aSEd Maste strm.PutCString("No value");
184f034231aSEd Maste
185f034231aSEd Maste return true;
186f034231aSEd Maste }
187f034231aSEd Maste
GetNumRanges()18814f1b3e8SDimitry Andric uint32_t SBBlock::GetNumRanges() {
1896f8fc217SDimitry Andric LLDB_INSTRUMENT_VA(this);
1905f29bb8aSDimitry Andric
191f034231aSEd Maste if (m_opaque_ptr)
192f034231aSEd Maste return m_opaque_ptr->GetNumRanges();
193f034231aSEd Maste return 0;
194f034231aSEd Maste }
195f034231aSEd Maste
GetRangeStartAddress(uint32_t idx)19614f1b3e8SDimitry Andric lldb::SBAddress SBBlock::GetRangeStartAddress(uint32_t idx) {
1976f8fc217SDimitry Andric LLDB_INSTRUMENT_VA(this, idx);
1985f29bb8aSDimitry Andric
199f034231aSEd Maste lldb::SBAddress sb_addr;
20014f1b3e8SDimitry Andric if (m_opaque_ptr) {
201f034231aSEd Maste AddressRange range;
20214f1b3e8SDimitry Andric if (m_opaque_ptr->GetRangeAtIndex(idx, range)) {
203f034231aSEd Maste sb_addr.ref() = range.GetBaseAddress();
204f034231aSEd Maste }
205f034231aSEd Maste }
2066f8fc217SDimitry Andric return sb_addr;
207f034231aSEd Maste }
208f034231aSEd Maste
GetRangeEndAddress(uint32_t idx)20914f1b3e8SDimitry Andric lldb::SBAddress SBBlock::GetRangeEndAddress(uint32_t idx) {
2106f8fc217SDimitry Andric LLDB_INSTRUMENT_VA(this, idx);
2115f29bb8aSDimitry Andric
212f034231aSEd Maste lldb::SBAddress sb_addr;
21314f1b3e8SDimitry Andric if (m_opaque_ptr) {
214f034231aSEd Maste AddressRange range;
21514f1b3e8SDimitry Andric if (m_opaque_ptr->GetRangeAtIndex(idx, range)) {
216f034231aSEd Maste sb_addr.ref() = range.GetBaseAddress();
217f034231aSEd Maste sb_addr.ref().Slide(range.GetByteSize());
218f034231aSEd Maste }
219f034231aSEd Maste }
2206f8fc217SDimitry Andric return sb_addr;
221f034231aSEd Maste }
222f034231aSEd Maste
GetRanges()223ac9a064cSDimitry Andric lldb::SBAddressRangeList SBBlock::GetRanges() {
224ac9a064cSDimitry Andric LLDB_INSTRUMENT_VA(this);
225ac9a064cSDimitry Andric
226ac9a064cSDimitry Andric lldb::SBAddressRangeList sb_ranges;
227ac9a064cSDimitry Andric if (m_opaque_ptr)
228ac9a064cSDimitry Andric sb_ranges.m_opaque_up->ref() = m_opaque_ptr->GetRanges();
229ac9a064cSDimitry Andric return sb_ranges;
230ac9a064cSDimitry Andric }
231ac9a064cSDimitry Andric
GetRangeIndexForBlockAddress(lldb::SBAddress block_addr)23214f1b3e8SDimitry Andric uint32_t SBBlock::GetRangeIndexForBlockAddress(lldb::SBAddress block_addr) {
2336f8fc217SDimitry Andric LLDB_INSTRUMENT_VA(this, block_addr);
2345f29bb8aSDimitry Andric
23514f1b3e8SDimitry Andric if (m_opaque_ptr && block_addr.IsValid()) {
236f034231aSEd Maste return m_opaque_ptr->GetRangeIndexContainingAddress(block_addr.ref());
237f034231aSEd Maste }
238f034231aSEd Maste
239f034231aSEd Maste return UINT32_MAX;
240f034231aSEd Maste }
241f034231aSEd Maste
GetVariables(lldb::SBFrame & frame,bool arguments,bool locals,bool statics,lldb::DynamicValueType use_dynamic)24214f1b3e8SDimitry Andric lldb::SBValueList SBBlock::GetVariables(lldb::SBFrame &frame, bool arguments,
24314f1b3e8SDimitry Andric bool locals, bool statics,
24414f1b3e8SDimitry Andric lldb::DynamicValueType use_dynamic) {
2456f8fc217SDimitry Andric LLDB_INSTRUMENT_VA(this, frame, arguments, locals, statics, use_dynamic);
2465f29bb8aSDimitry Andric
247f034231aSEd Maste Block *block = GetPtr();
248f034231aSEd Maste SBValueList value_list;
24914f1b3e8SDimitry Andric if (block) {
250f034231aSEd Maste StackFrameSP frame_sp(frame.GetFrameSP());
251f034231aSEd Maste VariableListSP variable_list_sp(block->GetBlockVariableList(true));
252f034231aSEd Maste
25314f1b3e8SDimitry Andric if (variable_list_sp) {
254f034231aSEd Maste const size_t num_variables = variable_list_sp->GetSize();
25514f1b3e8SDimitry Andric if (num_variables) {
25614f1b3e8SDimitry Andric for (size_t i = 0; i < num_variables; ++i) {
257f034231aSEd Maste VariableSP variable_sp(variable_list_sp->GetVariableAtIndex(i));
25814f1b3e8SDimitry Andric if (variable_sp) {
259f034231aSEd Maste bool add_variable = false;
26014f1b3e8SDimitry Andric switch (variable_sp->GetScope()) {
261f034231aSEd Maste case eValueTypeVariableGlobal:
262f034231aSEd Maste case eValueTypeVariableStatic:
263f3fbd1c0SDimitry Andric case eValueTypeVariableThreadLocal:
264f034231aSEd Maste add_variable = statics;
265f034231aSEd Maste break;
266f034231aSEd Maste
267f034231aSEd Maste case eValueTypeVariableArgument:
268f034231aSEd Maste add_variable = arguments;
269f034231aSEd Maste break;
270f034231aSEd Maste
271f034231aSEd Maste case eValueTypeVariableLocal:
272f034231aSEd Maste add_variable = locals;
273f034231aSEd Maste break;
274f034231aSEd Maste
275f034231aSEd Maste default:
276f034231aSEd Maste break;
277f034231aSEd Maste }
27814f1b3e8SDimitry Andric if (add_variable) {
27914f1b3e8SDimitry Andric if (frame_sp) {
28014f1b3e8SDimitry Andric lldb::ValueObjectSP valobj_sp(
28114f1b3e8SDimitry Andric frame_sp->GetValueObjectForFrameVariable(variable_sp,
28214f1b3e8SDimitry Andric eNoDynamicValues));
283f034231aSEd Maste SBValue value_sb;
284f034231aSEd Maste value_sb.SetSP(valobj_sp, use_dynamic);
285f034231aSEd Maste value_list.Append(value_sb);
286f034231aSEd Maste }
287f034231aSEd Maste }
288f034231aSEd Maste }
289f034231aSEd Maste }
290f034231aSEd Maste }
291f034231aSEd Maste }
292f034231aSEd Maste }
2936f8fc217SDimitry Andric return value_list;
294f034231aSEd Maste }
295f034231aSEd Maste
GetVariables(lldb::SBTarget & target,bool arguments,bool locals,bool statics)29614f1b3e8SDimitry Andric lldb::SBValueList SBBlock::GetVariables(lldb::SBTarget &target, bool arguments,
29714f1b3e8SDimitry Andric bool locals, bool statics) {
2986f8fc217SDimitry Andric LLDB_INSTRUMENT_VA(this, target, arguments, locals, statics);
2995f29bb8aSDimitry Andric
300f034231aSEd Maste Block *block = GetPtr();
301f034231aSEd Maste
302f034231aSEd Maste SBValueList value_list;
30314f1b3e8SDimitry Andric if (block) {
304f034231aSEd Maste TargetSP target_sp(target.GetSP());
305f034231aSEd Maste
306f034231aSEd Maste VariableListSP variable_list_sp(block->GetBlockVariableList(true));
307f034231aSEd Maste
30814f1b3e8SDimitry Andric if (variable_list_sp) {
309f034231aSEd Maste const size_t num_variables = variable_list_sp->GetSize();
31014f1b3e8SDimitry Andric if (num_variables) {
31114f1b3e8SDimitry Andric for (size_t i = 0; i < num_variables; ++i) {
312f034231aSEd Maste VariableSP variable_sp(variable_list_sp->GetVariableAtIndex(i));
31314f1b3e8SDimitry Andric if (variable_sp) {
314f034231aSEd Maste bool add_variable = false;
31514f1b3e8SDimitry Andric switch (variable_sp->GetScope()) {
316f034231aSEd Maste case eValueTypeVariableGlobal:
317f034231aSEd Maste case eValueTypeVariableStatic:
318f3fbd1c0SDimitry Andric case eValueTypeVariableThreadLocal:
319f034231aSEd Maste add_variable = statics;
320f034231aSEd Maste break;
321f034231aSEd Maste
322f034231aSEd Maste case eValueTypeVariableArgument:
323f034231aSEd Maste add_variable = arguments;
324f034231aSEd Maste break;
325f034231aSEd Maste
326f034231aSEd Maste case eValueTypeVariableLocal:
327f034231aSEd Maste add_variable = locals;
328f034231aSEd Maste break;
329f034231aSEd Maste
330f034231aSEd Maste default:
331f034231aSEd Maste break;
332f034231aSEd Maste }
33314f1b3e8SDimitry Andric if (add_variable) {
334f034231aSEd Maste if (target_sp)
33514f1b3e8SDimitry Andric value_list.Append(
33614f1b3e8SDimitry Andric ValueObjectVariable::Create(target_sp.get(), variable_sp));
337f034231aSEd Maste }
338f034231aSEd Maste }
339f034231aSEd Maste }
340f034231aSEd Maste }
341f034231aSEd Maste }
342f034231aSEd Maste }
3436f8fc217SDimitry Andric return value_list;
344f034231aSEd Maste }
345