1ac7ddfbfSEd Maste //===-- SBBlock.cpp ---------------------------------------------*- C++ -*-===//
2ac7ddfbfSEd Maste //
3ac7ddfbfSEd Maste //                     The LLVM Compiler Infrastructure
4ac7ddfbfSEd Maste //
5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source
6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details.
7ac7ddfbfSEd Maste //
8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===//
9ac7ddfbfSEd Maste 
10ac7ddfbfSEd Maste #include "lldb/API/SBBlock.h"
11ac7ddfbfSEd Maste #include "lldb/API/SBAddress.h"
12ac7ddfbfSEd Maste #include "lldb/API/SBFileSpec.h"
13ac7ddfbfSEd Maste #include "lldb/API/SBFrame.h"
14ac7ddfbfSEd Maste #include "lldb/API/SBStream.h"
15ac7ddfbfSEd Maste #include "lldb/API/SBValue.h"
16ac7ddfbfSEd Maste #include "lldb/Core/AddressRange.h"
17ac7ddfbfSEd Maste #include "lldb/Core/ValueObjectVariable.h"
18ac7ddfbfSEd Maste #include "lldb/Symbol/Block.h"
19ac7ddfbfSEd Maste #include "lldb/Symbol/Function.h"
20ac7ddfbfSEd Maste #include "lldb/Symbol/SymbolContext.h"
21ac7ddfbfSEd Maste #include "lldb/Symbol/VariableList.h"
22ac7ddfbfSEd Maste #include "lldb/Target/StackFrame.h"
23ac7ddfbfSEd Maste #include "lldb/Target/Target.h"
24*f678e45dSDimitry Andric #include "lldb/Utility/Log.h"
25ac7ddfbfSEd Maste 
26ac7ddfbfSEd Maste using namespace lldb;
27ac7ddfbfSEd Maste using namespace lldb_private;
28ac7ddfbfSEd Maste 
SBBlock()29435933ddSDimitry Andric SBBlock::SBBlock() : m_opaque_ptr(NULL) {}
30ac7ddfbfSEd Maste 
SBBlock(lldb_private::Block * lldb_object_ptr)31435933ddSDimitry Andric SBBlock::SBBlock(lldb_private::Block *lldb_object_ptr)
32435933ddSDimitry Andric     : m_opaque_ptr(lldb_object_ptr) {}
33ac7ddfbfSEd Maste 
SBBlock(const SBBlock & rhs)34435933ddSDimitry Andric SBBlock::SBBlock(const SBBlock &rhs) : m_opaque_ptr(rhs.m_opaque_ptr) {}
35ac7ddfbfSEd Maste 
operator =(const SBBlock & rhs)36435933ddSDimitry Andric const SBBlock &SBBlock::operator=(const SBBlock &rhs) {
37ac7ddfbfSEd Maste   m_opaque_ptr = rhs.m_opaque_ptr;
38ac7ddfbfSEd Maste   return *this;
39ac7ddfbfSEd Maste }
40ac7ddfbfSEd Maste 
~SBBlock()41435933ddSDimitry Andric SBBlock::~SBBlock() { m_opaque_ptr = NULL; }
42ac7ddfbfSEd Maste 
IsValid() const43435933ddSDimitry Andric bool SBBlock::IsValid() const { return m_opaque_ptr != NULL; }
44ac7ddfbfSEd Maste 
IsInlined() const45435933ddSDimitry Andric bool SBBlock::IsInlined() const {
46ac7ddfbfSEd Maste   if (m_opaque_ptr)
47ac7ddfbfSEd Maste     return m_opaque_ptr->GetInlinedFunctionInfo() != NULL;
48ac7ddfbfSEd Maste   return false;
49ac7ddfbfSEd Maste }
50ac7ddfbfSEd Maste 
GetInlinedName() const51435933ddSDimitry Andric const char *SBBlock::GetInlinedName() const {
52435933ddSDimitry Andric   if (m_opaque_ptr) {
53435933ddSDimitry Andric     const InlineFunctionInfo *inlined_info =
54435933ddSDimitry Andric         m_opaque_ptr->GetInlinedFunctionInfo();
55435933ddSDimitry Andric     if (inlined_info) {
56b91a7dfcSDimitry Andric       Function *function = m_opaque_ptr->CalculateSymbolContextFunction();
57b91a7dfcSDimitry Andric       LanguageType language;
58b91a7dfcSDimitry Andric       if (function)
59b91a7dfcSDimitry Andric         language = function->GetLanguage();
60b91a7dfcSDimitry Andric       else
61b91a7dfcSDimitry Andric         language = lldb::eLanguageTypeUnknown;
62b91a7dfcSDimitry Andric       return inlined_info->GetName(language).AsCString(NULL);
63b91a7dfcSDimitry Andric     }
64ac7ddfbfSEd Maste   }
65ac7ddfbfSEd Maste   return NULL;
66ac7ddfbfSEd Maste }
67ac7ddfbfSEd Maste 
GetInlinedCallSiteFile() const68435933ddSDimitry Andric SBFileSpec SBBlock::GetInlinedCallSiteFile() const {
69ac7ddfbfSEd Maste   SBFileSpec sb_file;
70435933ddSDimitry Andric   if (m_opaque_ptr) {
71435933ddSDimitry Andric     const InlineFunctionInfo *inlined_info =
72435933ddSDimitry Andric         m_opaque_ptr->GetInlinedFunctionInfo();
73ac7ddfbfSEd Maste     if (inlined_info)
74ac7ddfbfSEd Maste       sb_file.SetFileSpec(inlined_info->GetCallSite().GetFile());
75ac7ddfbfSEd Maste   }
76ac7ddfbfSEd Maste   return sb_file;
77ac7ddfbfSEd Maste }
78ac7ddfbfSEd Maste 
GetInlinedCallSiteLine() const79435933ddSDimitry Andric uint32_t SBBlock::GetInlinedCallSiteLine() const {
80435933ddSDimitry Andric   if (m_opaque_ptr) {
81435933ddSDimitry Andric     const InlineFunctionInfo *inlined_info =
82435933ddSDimitry Andric         m_opaque_ptr->GetInlinedFunctionInfo();
83ac7ddfbfSEd Maste     if (inlined_info)
84ac7ddfbfSEd Maste       return inlined_info->GetCallSite().GetLine();
85ac7ddfbfSEd Maste   }
86ac7ddfbfSEd Maste   return 0;
87ac7ddfbfSEd Maste }
88ac7ddfbfSEd Maste 
GetInlinedCallSiteColumn() const89435933ddSDimitry Andric uint32_t SBBlock::GetInlinedCallSiteColumn() const {
90435933ddSDimitry Andric   if (m_opaque_ptr) {
91435933ddSDimitry Andric     const InlineFunctionInfo *inlined_info =
92435933ddSDimitry Andric         m_opaque_ptr->GetInlinedFunctionInfo();
93ac7ddfbfSEd Maste     if (inlined_info)
94ac7ddfbfSEd Maste       return inlined_info->GetCallSite().GetColumn();
95ac7ddfbfSEd Maste   }
96ac7ddfbfSEd Maste   return 0;
97ac7ddfbfSEd Maste }
98ac7ddfbfSEd Maste 
AppendVariables(bool can_create,bool get_parent_variables,lldb_private::VariableList * var_list)99435933ddSDimitry Andric void SBBlock::AppendVariables(bool can_create, bool get_parent_variables,
100435933ddSDimitry Andric                               lldb_private::VariableList *var_list) {
101435933ddSDimitry Andric   if (IsValid()) {
102ac7ddfbfSEd Maste     bool show_inline = true;
103435933ddSDimitry Andric     m_opaque_ptr->AppendVariables(can_create, get_parent_variables, show_inline,
104435933ddSDimitry Andric                                   [](Variable *) { return true; }, var_list);
105ac7ddfbfSEd Maste   }
106ac7ddfbfSEd Maste }
107ac7ddfbfSEd Maste 
GetParent()108435933ddSDimitry Andric SBBlock SBBlock::GetParent() {
109ac7ddfbfSEd Maste   SBBlock sb_block;
110ac7ddfbfSEd Maste   if (m_opaque_ptr)
111ac7ddfbfSEd Maste     sb_block.m_opaque_ptr = m_opaque_ptr->GetParent();
112ac7ddfbfSEd Maste   return sb_block;
113ac7ddfbfSEd Maste }
114ac7ddfbfSEd Maste 
GetContainingInlinedBlock()115435933ddSDimitry Andric lldb::SBBlock SBBlock::GetContainingInlinedBlock() {
116ac7ddfbfSEd Maste   SBBlock sb_block;
117ac7ddfbfSEd Maste   if (m_opaque_ptr)
118ac7ddfbfSEd Maste     sb_block.m_opaque_ptr = m_opaque_ptr->GetContainingInlinedBlock();
119ac7ddfbfSEd Maste   return sb_block;
120ac7ddfbfSEd Maste }
121ac7ddfbfSEd Maste 
GetSibling()122435933ddSDimitry Andric SBBlock SBBlock::GetSibling() {
123ac7ddfbfSEd Maste   SBBlock sb_block;
124ac7ddfbfSEd Maste   if (m_opaque_ptr)
125ac7ddfbfSEd Maste     sb_block.m_opaque_ptr = m_opaque_ptr->GetSibling();
126ac7ddfbfSEd Maste   return sb_block;
127ac7ddfbfSEd Maste }
128ac7ddfbfSEd Maste 
GetFirstChild()129435933ddSDimitry Andric SBBlock SBBlock::GetFirstChild() {
130ac7ddfbfSEd Maste   SBBlock sb_block;
131ac7ddfbfSEd Maste   if (m_opaque_ptr)
132ac7ddfbfSEd Maste     sb_block.m_opaque_ptr = m_opaque_ptr->GetFirstChild();
133ac7ddfbfSEd Maste   return sb_block;
134ac7ddfbfSEd Maste }
135ac7ddfbfSEd Maste 
GetPtr()136435933ddSDimitry Andric lldb_private::Block *SBBlock::GetPtr() { return m_opaque_ptr; }
137ac7ddfbfSEd Maste 
SetPtr(lldb_private::Block * block)138435933ddSDimitry Andric void SBBlock::SetPtr(lldb_private::Block *block) { m_opaque_ptr = block; }
139ac7ddfbfSEd Maste 
GetDescription(SBStream & description)140435933ddSDimitry Andric bool SBBlock::GetDescription(SBStream &description) {
141ac7ddfbfSEd Maste   Stream &strm = description.ref();
142ac7ddfbfSEd Maste 
143435933ddSDimitry Andric   if (m_opaque_ptr) {
144ac7ddfbfSEd Maste     lldb::user_id_t id = m_opaque_ptr->GetID();
145ac7ddfbfSEd Maste     strm.Printf("Block: {id: %" PRIu64 "} ", id);
146435933ddSDimitry Andric     if (IsInlined()) {
147ac7ddfbfSEd Maste       strm.Printf(" (inlined, '%s') ", GetInlinedName());
148ac7ddfbfSEd Maste     }
149ac7ddfbfSEd Maste     lldb_private::SymbolContext sc;
150ac7ddfbfSEd Maste     m_opaque_ptr->CalculateSymbolContext(&sc);
151435933ddSDimitry Andric     if (sc.function) {
152435933ddSDimitry Andric       m_opaque_ptr->DumpAddressRanges(
153435933ddSDimitry Andric           &strm,
154ac7ddfbfSEd Maste           sc.function->GetAddressRange().GetBaseAddress().GetFileAddress());
155ac7ddfbfSEd Maste     }
156435933ddSDimitry Andric   } else
157ac7ddfbfSEd Maste     strm.PutCString("No value");
158ac7ddfbfSEd Maste 
159ac7ddfbfSEd Maste   return true;
160ac7ddfbfSEd Maste }
161ac7ddfbfSEd Maste 
GetNumRanges()162435933ddSDimitry Andric uint32_t SBBlock::GetNumRanges() {
163ac7ddfbfSEd Maste   if (m_opaque_ptr)
164ac7ddfbfSEd Maste     return m_opaque_ptr->GetNumRanges();
165ac7ddfbfSEd Maste   return 0;
166ac7ddfbfSEd Maste }
167ac7ddfbfSEd Maste 
GetRangeStartAddress(uint32_t idx)168435933ddSDimitry Andric lldb::SBAddress SBBlock::GetRangeStartAddress(uint32_t idx) {
169ac7ddfbfSEd Maste   lldb::SBAddress sb_addr;
170435933ddSDimitry Andric   if (m_opaque_ptr) {
171ac7ddfbfSEd Maste     AddressRange range;
172435933ddSDimitry Andric     if (m_opaque_ptr->GetRangeAtIndex(idx, range)) {
173ac7ddfbfSEd Maste       sb_addr.ref() = range.GetBaseAddress();
174ac7ddfbfSEd Maste     }
175ac7ddfbfSEd Maste   }
176ac7ddfbfSEd Maste   return sb_addr;
177ac7ddfbfSEd Maste }
178ac7ddfbfSEd Maste 
GetRangeEndAddress(uint32_t idx)179435933ddSDimitry Andric lldb::SBAddress SBBlock::GetRangeEndAddress(uint32_t idx) {
180ac7ddfbfSEd Maste   lldb::SBAddress sb_addr;
181435933ddSDimitry Andric   if (m_opaque_ptr) {
182ac7ddfbfSEd Maste     AddressRange range;
183435933ddSDimitry Andric     if (m_opaque_ptr->GetRangeAtIndex(idx, range)) {
184ac7ddfbfSEd Maste       sb_addr.ref() = range.GetBaseAddress();
185ac7ddfbfSEd Maste       sb_addr.ref().Slide(range.GetByteSize());
186ac7ddfbfSEd Maste     }
187ac7ddfbfSEd Maste   }
188ac7ddfbfSEd Maste   return sb_addr;
189ac7ddfbfSEd Maste }
190ac7ddfbfSEd Maste 
GetRangeIndexForBlockAddress(lldb::SBAddress block_addr)191435933ddSDimitry Andric uint32_t SBBlock::GetRangeIndexForBlockAddress(lldb::SBAddress block_addr) {
192435933ddSDimitry Andric   if (m_opaque_ptr && block_addr.IsValid()) {
193ac7ddfbfSEd Maste     return m_opaque_ptr->GetRangeIndexContainingAddress(block_addr.ref());
194ac7ddfbfSEd Maste   }
195ac7ddfbfSEd Maste 
196ac7ddfbfSEd Maste   return UINT32_MAX;
197ac7ddfbfSEd Maste }
198ac7ddfbfSEd Maste 
GetVariables(lldb::SBFrame & frame,bool arguments,bool locals,bool statics,lldb::DynamicValueType use_dynamic)199435933ddSDimitry Andric lldb::SBValueList SBBlock::GetVariables(lldb::SBFrame &frame, bool arguments,
200435933ddSDimitry Andric                                         bool locals, bool statics,
201435933ddSDimitry Andric                                         lldb::DynamicValueType use_dynamic) {
202ac7ddfbfSEd Maste   Block *block = GetPtr();
203ac7ddfbfSEd Maste   SBValueList value_list;
204435933ddSDimitry Andric   if (block) {
205ac7ddfbfSEd Maste     StackFrameSP frame_sp(frame.GetFrameSP());
206ac7ddfbfSEd Maste     VariableListSP variable_list_sp(block->GetBlockVariableList(true));
207ac7ddfbfSEd Maste 
208435933ddSDimitry Andric     if (variable_list_sp) {
209ac7ddfbfSEd Maste       const size_t num_variables = variable_list_sp->GetSize();
210435933ddSDimitry Andric       if (num_variables) {
211435933ddSDimitry Andric         for (size_t i = 0; i < num_variables; ++i) {
212ac7ddfbfSEd Maste           VariableSP variable_sp(variable_list_sp->GetVariableAtIndex(i));
213435933ddSDimitry Andric           if (variable_sp) {
214ac7ddfbfSEd Maste             bool add_variable = false;
215435933ddSDimitry Andric             switch (variable_sp->GetScope()) {
216ac7ddfbfSEd Maste             case eValueTypeVariableGlobal:
217ac7ddfbfSEd Maste             case eValueTypeVariableStatic:
2184bb0738eSEd Maste             case eValueTypeVariableThreadLocal:
219ac7ddfbfSEd Maste               add_variable = statics;
220ac7ddfbfSEd Maste               break;
221ac7ddfbfSEd Maste 
222ac7ddfbfSEd Maste             case eValueTypeVariableArgument:
223ac7ddfbfSEd Maste               add_variable = arguments;
224ac7ddfbfSEd Maste               break;
225ac7ddfbfSEd Maste 
226ac7ddfbfSEd Maste             case eValueTypeVariableLocal:
227ac7ddfbfSEd Maste               add_variable = locals;
228ac7ddfbfSEd Maste               break;
229ac7ddfbfSEd Maste 
230ac7ddfbfSEd Maste             default:
231ac7ddfbfSEd Maste               break;
232ac7ddfbfSEd Maste             }
233435933ddSDimitry Andric             if (add_variable) {
234435933ddSDimitry Andric               if (frame_sp) {
235435933ddSDimitry Andric                 lldb::ValueObjectSP valobj_sp(
236435933ddSDimitry Andric                     frame_sp->GetValueObjectForFrameVariable(variable_sp,
237435933ddSDimitry Andric                                                              eNoDynamicValues));
238ac7ddfbfSEd Maste                 SBValue value_sb;
239ac7ddfbfSEd Maste                 value_sb.SetSP(valobj_sp, use_dynamic);
240ac7ddfbfSEd Maste                 value_list.Append(value_sb);
241ac7ddfbfSEd Maste               }
242ac7ddfbfSEd Maste             }
243ac7ddfbfSEd Maste           }
244ac7ddfbfSEd Maste         }
245ac7ddfbfSEd Maste       }
246ac7ddfbfSEd Maste     }
247ac7ddfbfSEd Maste   }
248ac7ddfbfSEd Maste   return value_list;
249ac7ddfbfSEd Maste }
250ac7ddfbfSEd Maste 
GetVariables(lldb::SBTarget & target,bool arguments,bool locals,bool statics)251435933ddSDimitry Andric lldb::SBValueList SBBlock::GetVariables(lldb::SBTarget &target, bool arguments,
252435933ddSDimitry Andric                                         bool locals, bool statics) {
253ac7ddfbfSEd Maste   Block *block = GetPtr();
254ac7ddfbfSEd Maste 
255ac7ddfbfSEd Maste   SBValueList value_list;
256435933ddSDimitry Andric   if (block) {
257ac7ddfbfSEd Maste     TargetSP target_sp(target.GetSP());
258ac7ddfbfSEd Maste 
259ac7ddfbfSEd Maste     VariableListSP variable_list_sp(block->GetBlockVariableList(true));
260ac7ddfbfSEd Maste 
261435933ddSDimitry Andric     if (variable_list_sp) {
262ac7ddfbfSEd Maste       const size_t num_variables = variable_list_sp->GetSize();
263435933ddSDimitry Andric       if (num_variables) {
264435933ddSDimitry Andric         for (size_t i = 0; i < num_variables; ++i) {
265ac7ddfbfSEd Maste           VariableSP variable_sp(variable_list_sp->GetVariableAtIndex(i));
266435933ddSDimitry Andric           if (variable_sp) {
267ac7ddfbfSEd Maste             bool add_variable = false;
268435933ddSDimitry Andric             switch (variable_sp->GetScope()) {
269ac7ddfbfSEd Maste             case eValueTypeVariableGlobal:
270ac7ddfbfSEd Maste             case eValueTypeVariableStatic:
2714bb0738eSEd Maste             case eValueTypeVariableThreadLocal:
272ac7ddfbfSEd Maste               add_variable = statics;
273ac7ddfbfSEd Maste               break;
274ac7ddfbfSEd Maste 
275ac7ddfbfSEd Maste             case eValueTypeVariableArgument:
276ac7ddfbfSEd Maste               add_variable = arguments;
277ac7ddfbfSEd Maste               break;
278ac7ddfbfSEd Maste 
279ac7ddfbfSEd Maste             case eValueTypeVariableLocal:
280ac7ddfbfSEd Maste               add_variable = locals;
281ac7ddfbfSEd Maste               break;
282ac7ddfbfSEd Maste 
283ac7ddfbfSEd Maste             default:
284ac7ddfbfSEd Maste               break;
285ac7ddfbfSEd Maste             }
286435933ddSDimitry Andric             if (add_variable) {
287ac7ddfbfSEd Maste               if (target_sp)
288435933ddSDimitry Andric                 value_list.Append(
289435933ddSDimitry Andric                     ValueObjectVariable::Create(target_sp.get(), variable_sp));
290ac7ddfbfSEd Maste             }
291ac7ddfbfSEd Maste           }
292ac7ddfbfSEd Maste         }
293ac7ddfbfSEd Maste       }
294ac7ddfbfSEd Maste     }
295ac7ddfbfSEd Maste   }
296ac7ddfbfSEd Maste   return value_list;
297ac7ddfbfSEd Maste }
298