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 
30 SBBlock::SBBlock () :
31     m_opaque_ptr (NULL)
32 {
33 }
34 
35 SBBlock::SBBlock (lldb_private::Block *lldb_object_ptr) :
36     m_opaque_ptr (lldb_object_ptr)
37 {
38 }
39 
40 SBBlock::SBBlock(const SBBlock &rhs) :
41     m_opaque_ptr (rhs.m_opaque_ptr)
42 {
43 }
44 
45 const SBBlock &
46 SBBlock::operator = (const SBBlock &rhs)
47 {
48     m_opaque_ptr = rhs.m_opaque_ptr;
49     return *this;
50 }
51 
52 SBBlock::~SBBlock ()
53 {
54     m_opaque_ptr = NULL;
55 }
56 
57 bool
58 SBBlock::IsValid () const
59 {
60     return m_opaque_ptr != NULL;
61 }
62 
63 bool
64 SBBlock::IsInlined () const
65 {
66     if (m_opaque_ptr)
67         return m_opaque_ptr->GetInlinedFunctionInfo () != NULL;
68     return false;
69 }
70 
71 const char *
72 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
92 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
105 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
117 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
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
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
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
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
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 *
175 SBBlock::GetPtr ()
176 {
177     return m_opaque_ptr;
178 }
179 
180 void
181 SBBlock::SetPtr (lldb_private::Block *block)
182 {
183     m_opaque_ptr = block;
184 }
185 
186 bool
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
214 SBBlock::GetNumRanges ()
215 {
216     if (m_opaque_ptr)
217         return m_opaque_ptr->GetNumRanges();
218     return 0;
219 }
220 
221 lldb::SBAddress
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
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
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
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
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