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 return inlined_info->GetName().AsCString (NULL);
79 }
80 return NULL;
81 }
82
83 SBFileSpec
GetInlinedCallSiteFile() const84 SBBlock::GetInlinedCallSiteFile () const
85 {
86 SBFileSpec sb_file;
87 if (m_opaque_ptr)
88 {
89 const InlineFunctionInfo* inlined_info = m_opaque_ptr->GetInlinedFunctionInfo ();
90 if (inlined_info)
91 sb_file.SetFileSpec (inlined_info->GetCallSite().GetFile());
92 }
93 return sb_file;
94 }
95
96 uint32_t
GetInlinedCallSiteLine() const97 SBBlock::GetInlinedCallSiteLine () const
98 {
99 if (m_opaque_ptr)
100 {
101 const InlineFunctionInfo* inlined_info = m_opaque_ptr->GetInlinedFunctionInfo ();
102 if (inlined_info)
103 return inlined_info->GetCallSite().GetLine();
104 }
105 return 0;
106 }
107
108 uint32_t
GetInlinedCallSiteColumn() const109 SBBlock::GetInlinedCallSiteColumn () const
110 {
111 if (m_opaque_ptr)
112 {
113 const InlineFunctionInfo* inlined_info = m_opaque_ptr->GetInlinedFunctionInfo ();
114 if (inlined_info)
115 return inlined_info->GetCallSite().GetColumn();
116 }
117 return 0;
118 }
119
120 void
AppendVariables(bool can_create,bool get_parent_variables,lldb_private::VariableList * var_list)121 SBBlock::AppendVariables (bool can_create, bool get_parent_variables, lldb_private::VariableList *var_list)
122 {
123 if (IsValid())
124 {
125 bool show_inline = true;
126 m_opaque_ptr->AppendVariables (can_create, get_parent_variables, show_inline, var_list);
127 }
128 }
129
130 SBBlock
GetParent()131 SBBlock::GetParent ()
132 {
133 SBBlock sb_block;
134 if (m_opaque_ptr)
135 sb_block.m_opaque_ptr = m_opaque_ptr->GetParent();
136 return sb_block;
137 }
138
139 lldb::SBBlock
GetContainingInlinedBlock()140 SBBlock::GetContainingInlinedBlock ()
141 {
142 SBBlock sb_block;
143 if (m_opaque_ptr)
144 sb_block.m_opaque_ptr = m_opaque_ptr->GetContainingInlinedBlock ();
145 return sb_block;
146 }
147
148 SBBlock
GetSibling()149 SBBlock::GetSibling ()
150 {
151 SBBlock sb_block;
152 if (m_opaque_ptr)
153 sb_block.m_opaque_ptr = m_opaque_ptr->GetSibling();
154 return sb_block;
155 }
156
157 SBBlock
GetFirstChild()158 SBBlock::GetFirstChild ()
159 {
160 SBBlock sb_block;
161 if (m_opaque_ptr)
162 sb_block.m_opaque_ptr = m_opaque_ptr->GetFirstChild();
163 return sb_block;
164 }
165
166 lldb_private::Block *
GetPtr()167 SBBlock::GetPtr ()
168 {
169 return m_opaque_ptr;
170 }
171
172 void
SetPtr(lldb_private::Block * block)173 SBBlock::SetPtr (lldb_private::Block *block)
174 {
175 m_opaque_ptr = block;
176 }
177
178 bool
GetDescription(SBStream & description)179 SBBlock::GetDescription (SBStream &description)
180 {
181 Stream &strm = description.ref();
182
183 if (m_opaque_ptr)
184 {
185 lldb::user_id_t id = m_opaque_ptr->GetID();
186 strm.Printf ("Block: {id: %" PRIu64 "} ", id);
187 if (IsInlined())
188 {
189 strm.Printf (" (inlined, '%s') ", GetInlinedName());
190 }
191 lldb_private::SymbolContext sc;
192 m_opaque_ptr->CalculateSymbolContext (&sc);
193 if (sc.function)
194 {
195 m_opaque_ptr->DumpAddressRanges (&strm,
196 sc.function->GetAddressRange().GetBaseAddress().GetFileAddress());
197 }
198 }
199 else
200 strm.PutCString ("No value");
201
202 return true;
203 }
204
205 uint32_t
GetNumRanges()206 SBBlock::GetNumRanges ()
207 {
208 if (m_opaque_ptr)
209 return m_opaque_ptr->GetNumRanges();
210 return 0;
211 }
212
213 lldb::SBAddress
GetRangeStartAddress(uint32_t idx)214 SBBlock::GetRangeStartAddress (uint32_t idx)
215 {
216 lldb::SBAddress sb_addr;
217 if (m_opaque_ptr)
218 {
219 AddressRange range;
220 if (m_opaque_ptr->GetRangeAtIndex(idx, range))
221 {
222 sb_addr.ref() = range.GetBaseAddress();
223 }
224 }
225 return sb_addr;
226 }
227
228 lldb::SBAddress
GetRangeEndAddress(uint32_t idx)229 SBBlock::GetRangeEndAddress (uint32_t idx)
230 {
231 lldb::SBAddress sb_addr;
232 if (m_opaque_ptr)
233 {
234 AddressRange range;
235 if (m_opaque_ptr->GetRangeAtIndex(idx, range))
236 {
237 sb_addr.ref() = range.GetBaseAddress();
238 sb_addr.ref().Slide(range.GetByteSize());
239 }
240 }
241 return sb_addr;
242 }
243
244 uint32_t
GetRangeIndexForBlockAddress(lldb::SBAddress block_addr)245 SBBlock::GetRangeIndexForBlockAddress (lldb::SBAddress block_addr)
246 {
247 if (m_opaque_ptr && block_addr.IsValid())
248 {
249 return m_opaque_ptr->GetRangeIndexContainingAddress (block_addr.ref());
250 }
251
252 return UINT32_MAX;
253 }
254
255
256 lldb::SBValueList
GetVariables(lldb::SBFrame & frame,bool arguments,bool locals,bool statics,lldb::DynamicValueType use_dynamic)257 SBBlock::GetVariables (lldb::SBFrame& frame,
258 bool arguments,
259 bool locals,
260 bool statics,
261 lldb::DynamicValueType use_dynamic)
262 {
263 Block *block = GetPtr();
264 SBValueList value_list;
265 if (block)
266 {
267 StackFrameSP frame_sp(frame.GetFrameSP());
268 VariableListSP variable_list_sp (block->GetBlockVariableList (true));
269
270 if (variable_list_sp)
271 {
272 const size_t num_variables = variable_list_sp->GetSize();
273 if (num_variables)
274 {
275 for (size_t i = 0; i < num_variables; ++i)
276 {
277 VariableSP variable_sp (variable_list_sp->GetVariableAtIndex(i));
278 if (variable_sp)
279 {
280 bool add_variable = false;
281 switch (variable_sp->GetScope())
282 {
283 case eValueTypeVariableGlobal:
284 case eValueTypeVariableStatic:
285 add_variable = statics;
286 break;
287
288 case eValueTypeVariableArgument:
289 add_variable = arguments;
290 break;
291
292 case eValueTypeVariableLocal:
293 add_variable = locals;
294 break;
295
296 default:
297 break;
298 }
299 if (add_variable)
300 {
301 if (frame_sp)
302 {
303 lldb::ValueObjectSP valobj_sp(frame_sp->GetValueObjectForFrameVariable (variable_sp,eNoDynamicValues));
304 SBValue value_sb;
305 value_sb.SetSP(valobj_sp, use_dynamic);
306 value_list.Append (value_sb);
307 }
308 }
309 }
310 }
311 }
312 }
313 }
314 return value_list;
315 }
316
317 lldb::SBValueList
GetVariables(lldb::SBTarget & target,bool arguments,bool locals,bool statics)318 SBBlock::GetVariables (lldb::SBTarget& target,
319 bool arguments,
320 bool locals,
321 bool statics)
322 {
323 Block *block = GetPtr();
324
325 SBValueList value_list;
326 if (block)
327 {
328 TargetSP target_sp(target.GetSP());
329
330 VariableListSP variable_list_sp (block->GetBlockVariableList (true));
331
332 if (variable_list_sp)
333 {
334 const size_t num_variables = variable_list_sp->GetSize();
335 if (num_variables)
336 {
337 for (size_t i = 0; i < num_variables; ++i)
338 {
339 VariableSP variable_sp (variable_list_sp->GetVariableAtIndex(i));
340 if (variable_sp)
341 {
342 bool add_variable = false;
343 switch (variable_sp->GetScope())
344 {
345 case eValueTypeVariableGlobal:
346 case eValueTypeVariableStatic:
347 add_variable = statics;
348 break;
349
350 case eValueTypeVariableArgument:
351 add_variable = arguments;
352 break;
353
354 case eValueTypeVariableLocal:
355 add_variable = locals;
356 break;
357
358 default:
359 break;
360 }
361 if (add_variable)
362 {
363 if (target_sp)
364 value_list.Append (ValueObjectVariable::Create (target_sp.get(), variable_sp));
365 }
366 }
367 }
368 }
369 }
370 }
371 return value_list;
372 }
373
374