xref: /freebsd/contrib/llvm-project/lldb/source/API/SBBlock.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 //===-- SBBlock.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 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/API/SBBlock.h"
10 #include "lldb/API/SBAddress.h"
11 #include "lldb/API/SBFileSpec.h"
12 #include "lldb/API/SBFrame.h"
13 #include "lldb/API/SBStream.h"
14 #include "lldb/API/SBValue.h"
15 #include "lldb/Core/AddressRange.h"
16 #include "lldb/Core/AddressRangeListImpl.h"
17 #include "lldb/Core/ValueObjectVariable.h"
18 #include "lldb/Symbol/Block.h"
19 #include "lldb/Symbol/Function.h"
20 #include "lldb/Symbol/SymbolContext.h"
21 #include "lldb/Symbol/VariableList.h"
22 #include "lldb/Target/StackFrame.h"
23 #include "lldb/Target/Target.h"
24 #include "lldb/Utility/Instrumentation.h"
25 
26 using namespace lldb;
27 using namespace lldb_private;
28 
SBBlock()29 SBBlock::SBBlock() { LLDB_INSTRUMENT_VA(this); }
30 
SBBlock(lldb_private::Block * lldb_object_ptr)31 SBBlock::SBBlock(lldb_private::Block *lldb_object_ptr)
32     : m_opaque_ptr(lldb_object_ptr) {}
33 
SBBlock(const SBBlock & rhs)34 SBBlock::SBBlock(const SBBlock &rhs) : m_opaque_ptr(rhs.m_opaque_ptr) {
35   LLDB_INSTRUMENT_VA(this, rhs);
36 }
37 
operator =(const SBBlock & rhs)38 const SBBlock &SBBlock::operator=(const SBBlock &rhs) {
39   LLDB_INSTRUMENT_VA(this, rhs);
40 
41   m_opaque_ptr = rhs.m_opaque_ptr;
42   return *this;
43 }
44 
~SBBlock()45 SBBlock::~SBBlock() { m_opaque_ptr = nullptr; }
46 
IsValid() const47 bool SBBlock::IsValid() const {
48   LLDB_INSTRUMENT_VA(this);
49   return this->operator bool();
50 }
operator bool() const51 SBBlock::operator bool() const {
52   LLDB_INSTRUMENT_VA(this);
53 
54   return m_opaque_ptr != nullptr;
55 }
56 
IsInlined() const57 bool SBBlock::IsInlined() const {
58   LLDB_INSTRUMENT_VA(this);
59 
60   if (m_opaque_ptr)
61     return m_opaque_ptr->GetInlinedFunctionInfo() != nullptr;
62   return false;
63 }
64 
GetInlinedName() const65 const char *SBBlock::GetInlinedName() const {
66   LLDB_INSTRUMENT_VA(this);
67 
68   if (m_opaque_ptr) {
69     const InlineFunctionInfo *inlined_info =
70         m_opaque_ptr->GetInlinedFunctionInfo();
71     if (inlined_info) {
72       return inlined_info->GetName().AsCString(nullptr);
73     }
74   }
75   return nullptr;
76 }
77 
GetInlinedCallSiteFile() const78 SBFileSpec SBBlock::GetInlinedCallSiteFile() const {
79   LLDB_INSTRUMENT_VA(this);
80 
81   SBFileSpec sb_file;
82   if (m_opaque_ptr) {
83     const InlineFunctionInfo *inlined_info =
84         m_opaque_ptr->GetInlinedFunctionInfo();
85     if (inlined_info)
86       sb_file.SetFileSpec(inlined_info->GetCallSite().GetFile());
87   }
88   return sb_file;
89 }
90 
GetInlinedCallSiteLine() const91 uint32_t SBBlock::GetInlinedCallSiteLine() const {
92   LLDB_INSTRUMENT_VA(this);
93 
94   if (m_opaque_ptr) {
95     const InlineFunctionInfo *inlined_info =
96         m_opaque_ptr->GetInlinedFunctionInfo();
97     if (inlined_info)
98       return inlined_info->GetCallSite().GetLine();
99   }
100   return 0;
101 }
102 
GetInlinedCallSiteColumn() const103 uint32_t SBBlock::GetInlinedCallSiteColumn() const {
104   LLDB_INSTRUMENT_VA(this);
105 
106   if (m_opaque_ptr) {
107     const InlineFunctionInfo *inlined_info =
108         m_opaque_ptr->GetInlinedFunctionInfo();
109     if (inlined_info)
110       return inlined_info->GetCallSite().GetColumn();
111   }
112   return 0;
113 }
114 
AppendVariables(bool can_create,bool get_parent_variables,lldb_private::VariableList * var_list)115 void SBBlock::AppendVariables(bool can_create, bool get_parent_variables,
116                               lldb_private::VariableList *var_list) {
117   if (IsValid()) {
118     bool show_inline = true;
119     m_opaque_ptr->AppendVariables(can_create, get_parent_variables, show_inline,
120                                   [](Variable *) { return true; }, var_list);
121   }
122 }
123 
GetParent()124 SBBlock SBBlock::GetParent() {
125   LLDB_INSTRUMENT_VA(this);
126 
127   SBBlock sb_block;
128   if (m_opaque_ptr)
129     sb_block.m_opaque_ptr = m_opaque_ptr->GetParent();
130   return sb_block;
131 }
132 
GetContainingInlinedBlock()133 lldb::SBBlock SBBlock::GetContainingInlinedBlock() {
134   LLDB_INSTRUMENT_VA(this);
135 
136   SBBlock sb_block;
137   if (m_opaque_ptr)
138     sb_block.m_opaque_ptr = m_opaque_ptr->GetContainingInlinedBlock();
139   return sb_block;
140 }
141 
GetSibling()142 SBBlock SBBlock::GetSibling() {
143   LLDB_INSTRUMENT_VA(this);
144 
145   SBBlock sb_block;
146   if (m_opaque_ptr)
147     sb_block.m_opaque_ptr = m_opaque_ptr->GetSibling();
148   return sb_block;
149 }
150 
GetFirstChild()151 SBBlock SBBlock::GetFirstChild() {
152   LLDB_INSTRUMENT_VA(this);
153 
154   SBBlock sb_block;
155   if (m_opaque_ptr)
156     sb_block.m_opaque_ptr = m_opaque_ptr->GetFirstChild();
157   return sb_block;
158 }
159 
GetPtr()160 lldb_private::Block *SBBlock::GetPtr() { return m_opaque_ptr; }
161 
SetPtr(lldb_private::Block * block)162 void SBBlock::SetPtr(lldb_private::Block *block) { m_opaque_ptr = block; }
163 
GetDescription(SBStream & description)164 bool SBBlock::GetDescription(SBStream &description) {
165   LLDB_INSTRUMENT_VA(this, description);
166 
167   Stream &strm = description.ref();
168 
169   if (m_opaque_ptr) {
170     lldb::user_id_t id = m_opaque_ptr->GetID();
171     strm.Printf("Block: {id: %" PRIu64 "} ", id);
172     if (IsInlined()) {
173       strm.Printf(" (inlined, '%s') ", GetInlinedName());
174     }
175     lldb_private::SymbolContext sc;
176     m_opaque_ptr->CalculateSymbolContext(&sc);
177     if (sc.function) {
178       m_opaque_ptr->DumpAddressRanges(
179           &strm,
180           sc.function->GetAddressRange().GetBaseAddress().GetFileAddress());
181     }
182   } else
183     strm.PutCString("No value");
184 
185   return true;
186 }
187 
GetNumRanges()188 uint32_t SBBlock::GetNumRanges() {
189   LLDB_INSTRUMENT_VA(this);
190 
191   if (m_opaque_ptr)
192     return m_opaque_ptr->GetNumRanges();
193   return 0;
194 }
195 
GetRangeStartAddress(uint32_t idx)196 lldb::SBAddress SBBlock::GetRangeStartAddress(uint32_t idx) {
197   LLDB_INSTRUMENT_VA(this, idx);
198 
199   lldb::SBAddress sb_addr;
200   if (m_opaque_ptr) {
201     AddressRange range;
202     if (m_opaque_ptr->GetRangeAtIndex(idx, range)) {
203       sb_addr.ref() = range.GetBaseAddress();
204     }
205   }
206   return sb_addr;
207 }
208 
GetRangeEndAddress(uint32_t idx)209 lldb::SBAddress SBBlock::GetRangeEndAddress(uint32_t idx) {
210   LLDB_INSTRUMENT_VA(this, idx);
211 
212   lldb::SBAddress sb_addr;
213   if (m_opaque_ptr) {
214     AddressRange range;
215     if (m_opaque_ptr->GetRangeAtIndex(idx, range)) {
216       sb_addr.ref() = range.GetBaseAddress();
217       sb_addr.ref().Slide(range.GetByteSize());
218     }
219   }
220   return sb_addr;
221 }
222 
GetRanges()223 lldb::SBAddressRangeList SBBlock::GetRanges() {
224   LLDB_INSTRUMENT_VA(this);
225 
226   lldb::SBAddressRangeList sb_ranges;
227   if (m_opaque_ptr)
228     sb_ranges.m_opaque_up->ref() = m_opaque_ptr->GetRanges();
229   return sb_ranges;
230 }
231 
GetRangeIndexForBlockAddress(lldb::SBAddress block_addr)232 uint32_t SBBlock::GetRangeIndexForBlockAddress(lldb::SBAddress block_addr) {
233   LLDB_INSTRUMENT_VA(this, block_addr);
234 
235   if (m_opaque_ptr && block_addr.IsValid()) {
236     return m_opaque_ptr->GetRangeIndexContainingAddress(block_addr.ref());
237   }
238 
239   return UINT32_MAX;
240 }
241 
GetVariables(lldb::SBFrame & frame,bool arguments,bool locals,bool statics,lldb::DynamicValueType use_dynamic)242 lldb::SBValueList SBBlock::GetVariables(lldb::SBFrame &frame, bool arguments,
243                                         bool locals, bool statics,
244                                         lldb::DynamicValueType use_dynamic) {
245   LLDB_INSTRUMENT_VA(this, frame, arguments, locals, statics, use_dynamic);
246 
247   Block *block = GetPtr();
248   SBValueList value_list;
249   if (block) {
250     StackFrameSP frame_sp(frame.GetFrameSP());
251     VariableListSP variable_list_sp(block->GetBlockVariableList(true));
252 
253     if (variable_list_sp) {
254       const size_t num_variables = variable_list_sp->GetSize();
255       if (num_variables) {
256         for (size_t i = 0; i < num_variables; ++i) {
257           VariableSP variable_sp(variable_list_sp->GetVariableAtIndex(i));
258           if (variable_sp) {
259             bool add_variable = false;
260             switch (variable_sp->GetScope()) {
261             case eValueTypeVariableGlobal:
262             case eValueTypeVariableStatic:
263             case eValueTypeVariableThreadLocal:
264               add_variable = statics;
265               break;
266 
267             case eValueTypeVariableArgument:
268               add_variable = arguments;
269               break;
270 
271             case eValueTypeVariableLocal:
272               add_variable = locals;
273               break;
274 
275             default:
276               break;
277             }
278             if (add_variable) {
279               if (frame_sp) {
280                 lldb::ValueObjectSP valobj_sp(
281                     frame_sp->GetValueObjectForFrameVariable(variable_sp,
282                                                              eNoDynamicValues));
283                 SBValue value_sb;
284                 value_sb.SetSP(valobj_sp, use_dynamic);
285                 value_list.Append(value_sb);
286               }
287             }
288           }
289         }
290       }
291     }
292   }
293   return value_list;
294 }
295 
GetVariables(lldb::SBTarget & target,bool arguments,bool locals,bool statics)296 lldb::SBValueList SBBlock::GetVariables(lldb::SBTarget &target, bool arguments,
297                                         bool locals, bool statics) {
298   LLDB_INSTRUMENT_VA(this, target, arguments, locals, statics);
299 
300   Block *block = GetPtr();
301 
302   SBValueList value_list;
303   if (block) {
304     TargetSP target_sp(target.GetSP());
305 
306     VariableListSP variable_list_sp(block->GetBlockVariableList(true));
307 
308     if (variable_list_sp) {
309       const size_t num_variables = variable_list_sp->GetSize();
310       if (num_variables) {
311         for (size_t i = 0; i < num_variables; ++i) {
312           VariableSP variable_sp(variable_list_sp->GetVariableAtIndex(i));
313           if (variable_sp) {
314             bool add_variable = false;
315             switch (variable_sp->GetScope()) {
316             case eValueTypeVariableGlobal:
317             case eValueTypeVariableStatic:
318             case eValueTypeVariableThreadLocal:
319               add_variable = statics;
320               break;
321 
322             case eValueTypeVariableArgument:
323               add_variable = arguments;
324               break;
325 
326             case eValueTypeVariableLocal:
327               add_variable = locals;
328               break;
329 
330             default:
331               break;
332             }
333             if (add_variable) {
334               if (target_sp)
335                 value_list.Append(
336                     ValueObjectVariable::Create(target_sp.get(), variable_sp));
337             }
338           }
339         }
340       }
341     }
342   }
343   return value_list;
344 }
345