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