xref: /src/contrib/llvm-project/lldb/source/API/SBBlock.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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