SBBlock.cpp revision 3d656c729a1ed0abad4e5a2d76f6e8a6904f66aa
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
26using namespace lldb;
27using namespace lldb_private;
28
29
30SBBlock::SBBlock () :
31    m_opaque_ptr (NULL)
32{
33}
34
35SBBlock::SBBlock (lldb_private::Block *lldb_object_ptr) :
36    m_opaque_ptr (lldb_object_ptr)
37{
38}
39
40SBBlock::SBBlock(const SBBlock &rhs) :
41    m_opaque_ptr (rhs.m_opaque_ptr)
42{
43}
44
45const SBBlock &
46SBBlock::operator = (const SBBlock &rhs)
47{
48    m_opaque_ptr = rhs.m_opaque_ptr;
49    return *this;
50}
51
52SBBlock::~SBBlock ()
53{
54    m_opaque_ptr = NULL;
55}
56
57bool
58SBBlock::IsValid () const
59{
60    return m_opaque_ptr != NULL;
61}
62
63bool
64SBBlock::IsInlined () const
65{
66    if (m_opaque_ptr)
67        return m_opaque_ptr->GetInlinedFunctionInfo () != NULL;
68    return false;
69}
70
71const char *
72SBBlock::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
83SBFileSpec
84SBBlock::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
96uint32_t
97SBBlock::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
108uint32_t
109SBBlock::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
120void
121SBBlock::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
130SBBlock
131SBBlock::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
139lldb::SBBlock
140SBBlock::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
148SBBlock
149SBBlock::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
157SBBlock
158SBBlock::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
166lldb_private::Block *
167SBBlock::GetPtr ()
168{
169    return m_opaque_ptr;
170}
171
172void
173SBBlock::SetPtr (lldb_private::Block *block)
174{
175    m_opaque_ptr = block;
176}
177
178bool
179SBBlock::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: %llu} ", 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
205uint32_t
206SBBlock::GetNumRanges ()
207{
208    if (m_opaque_ptr)
209        return m_opaque_ptr->GetNumRanges();
210    return 0;
211}
212
213lldb::SBAddress
214SBBlock::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
228lldb::SBAddress
229SBBlock::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
244uint32_t
245SBBlock::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
256lldb::SBValueList
257SBBlock::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
317lldb::SBValueList
318SBBlock::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