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/ValueObjectVariable.h"
18 #include "lldb/Symbol/Block.h"
19 #include "lldb/Symbol/Function.h"
20 #include "lldb/Symbol/SymbolContext.h"
21 #include "lldb/Symbol/VariableList.h"
22 #include "lldb/Target/StackFrame.h"
23 #include "lldb/Target/Target.h"
24 #include "lldb/Utility/Log.h"
25
26 using namespace lldb;
27 using namespace lldb_private;
28
SBBlock()29 SBBlock::SBBlock() : m_opaque_ptr(NULL) {}
30
SBBlock(lldb_private::Block * lldb_object_ptr)31 SBBlock::SBBlock(lldb_private::Block *lldb_object_ptr)
32 : m_opaque_ptr(lldb_object_ptr) {}
33
SBBlock(const SBBlock & rhs)34 SBBlock::SBBlock(const SBBlock &rhs) : m_opaque_ptr(rhs.m_opaque_ptr) {}
35
operator =(const SBBlock & rhs)36 const SBBlock &SBBlock::operator=(const SBBlock &rhs) {
37 m_opaque_ptr = rhs.m_opaque_ptr;
38 return *this;
39 }
40
~SBBlock()41 SBBlock::~SBBlock() { m_opaque_ptr = NULL; }
42
IsValid() const43 bool SBBlock::IsValid() const { return m_opaque_ptr != NULL; }
44
IsInlined() const45 bool SBBlock::IsInlined() const {
46 if (m_opaque_ptr)
47 return m_opaque_ptr->GetInlinedFunctionInfo() != NULL;
48 return false;
49 }
50
GetInlinedName() const51 const char *SBBlock::GetInlinedName() const {
52 if (m_opaque_ptr) {
53 const InlineFunctionInfo *inlined_info =
54 m_opaque_ptr->GetInlinedFunctionInfo();
55 if (inlined_info) {
56 Function *function = m_opaque_ptr->CalculateSymbolContextFunction();
57 LanguageType language;
58 if (function)
59 language = function->GetLanguage();
60 else
61 language = lldb::eLanguageTypeUnknown;
62 return inlined_info->GetName(language).AsCString(NULL);
63 }
64 }
65 return NULL;
66 }
67
GetInlinedCallSiteFile() const68 SBFileSpec SBBlock::GetInlinedCallSiteFile() const {
69 SBFileSpec sb_file;
70 if (m_opaque_ptr) {
71 const InlineFunctionInfo *inlined_info =
72 m_opaque_ptr->GetInlinedFunctionInfo();
73 if (inlined_info)
74 sb_file.SetFileSpec(inlined_info->GetCallSite().GetFile());
75 }
76 return sb_file;
77 }
78
GetInlinedCallSiteLine() const79 uint32_t SBBlock::GetInlinedCallSiteLine() const {
80 if (m_opaque_ptr) {
81 const InlineFunctionInfo *inlined_info =
82 m_opaque_ptr->GetInlinedFunctionInfo();
83 if (inlined_info)
84 return inlined_info->GetCallSite().GetLine();
85 }
86 return 0;
87 }
88
GetInlinedCallSiteColumn() const89 uint32_t SBBlock::GetInlinedCallSiteColumn() const {
90 if (m_opaque_ptr) {
91 const InlineFunctionInfo *inlined_info =
92 m_opaque_ptr->GetInlinedFunctionInfo();
93 if (inlined_info)
94 return inlined_info->GetCallSite().GetColumn();
95 }
96 return 0;
97 }
98
AppendVariables(bool can_create,bool get_parent_variables,lldb_private::VariableList * var_list)99 void SBBlock::AppendVariables(bool can_create, bool get_parent_variables,
100 lldb_private::VariableList *var_list) {
101 if (IsValid()) {
102 bool show_inline = true;
103 m_opaque_ptr->AppendVariables(can_create, get_parent_variables, show_inline,
104 [](Variable *) { return true; }, var_list);
105 }
106 }
107
GetParent()108 SBBlock SBBlock::GetParent() {
109 SBBlock sb_block;
110 if (m_opaque_ptr)
111 sb_block.m_opaque_ptr = m_opaque_ptr->GetParent();
112 return sb_block;
113 }
114
GetContainingInlinedBlock()115 lldb::SBBlock SBBlock::GetContainingInlinedBlock() {
116 SBBlock sb_block;
117 if (m_opaque_ptr)
118 sb_block.m_opaque_ptr = m_opaque_ptr->GetContainingInlinedBlock();
119 return sb_block;
120 }
121
GetSibling()122 SBBlock SBBlock::GetSibling() {
123 SBBlock sb_block;
124 if (m_opaque_ptr)
125 sb_block.m_opaque_ptr = m_opaque_ptr->GetSibling();
126 return sb_block;
127 }
128
GetFirstChild()129 SBBlock SBBlock::GetFirstChild() {
130 SBBlock sb_block;
131 if (m_opaque_ptr)
132 sb_block.m_opaque_ptr = m_opaque_ptr->GetFirstChild();
133 return sb_block;
134 }
135
GetPtr()136 lldb_private::Block *SBBlock::GetPtr() { return m_opaque_ptr; }
137
SetPtr(lldb_private::Block * block)138 void SBBlock::SetPtr(lldb_private::Block *block) { m_opaque_ptr = block; }
139
GetDescription(SBStream & description)140 bool SBBlock::GetDescription(SBStream &description) {
141 Stream &strm = description.ref();
142
143 if (m_opaque_ptr) {
144 lldb::user_id_t id = m_opaque_ptr->GetID();
145 strm.Printf("Block: {id: %" PRIu64 "} ", id);
146 if (IsInlined()) {
147 strm.Printf(" (inlined, '%s') ", GetInlinedName());
148 }
149 lldb_private::SymbolContext sc;
150 m_opaque_ptr->CalculateSymbolContext(&sc);
151 if (sc.function) {
152 m_opaque_ptr->DumpAddressRanges(
153 &strm,
154 sc.function->GetAddressRange().GetBaseAddress().GetFileAddress());
155 }
156 } else
157 strm.PutCString("No value");
158
159 return true;
160 }
161
GetNumRanges()162 uint32_t SBBlock::GetNumRanges() {
163 if (m_opaque_ptr)
164 return m_opaque_ptr->GetNumRanges();
165 return 0;
166 }
167
GetRangeStartAddress(uint32_t idx)168 lldb::SBAddress SBBlock::GetRangeStartAddress(uint32_t idx) {
169 lldb::SBAddress sb_addr;
170 if (m_opaque_ptr) {
171 AddressRange range;
172 if (m_opaque_ptr->GetRangeAtIndex(idx, range)) {
173 sb_addr.ref() = range.GetBaseAddress();
174 }
175 }
176 return sb_addr;
177 }
178
GetRangeEndAddress(uint32_t idx)179 lldb::SBAddress SBBlock::GetRangeEndAddress(uint32_t idx) {
180 lldb::SBAddress sb_addr;
181 if (m_opaque_ptr) {
182 AddressRange range;
183 if (m_opaque_ptr->GetRangeAtIndex(idx, range)) {
184 sb_addr.ref() = range.GetBaseAddress();
185 sb_addr.ref().Slide(range.GetByteSize());
186 }
187 }
188 return sb_addr;
189 }
190
GetRangeIndexForBlockAddress(lldb::SBAddress block_addr)191 uint32_t SBBlock::GetRangeIndexForBlockAddress(lldb::SBAddress block_addr) {
192 if (m_opaque_ptr && block_addr.IsValid()) {
193 return m_opaque_ptr->GetRangeIndexContainingAddress(block_addr.ref());
194 }
195
196 return UINT32_MAX;
197 }
198
GetVariables(lldb::SBFrame & frame,bool arguments,bool locals,bool statics,lldb::DynamicValueType use_dynamic)199 lldb::SBValueList SBBlock::GetVariables(lldb::SBFrame &frame, bool arguments,
200 bool locals, bool statics,
201 lldb::DynamicValueType use_dynamic) {
202 Block *block = GetPtr();
203 SBValueList value_list;
204 if (block) {
205 StackFrameSP frame_sp(frame.GetFrameSP());
206 VariableListSP variable_list_sp(block->GetBlockVariableList(true));
207
208 if (variable_list_sp) {
209 const size_t num_variables = variable_list_sp->GetSize();
210 if (num_variables) {
211 for (size_t i = 0; i < num_variables; ++i) {
212 VariableSP variable_sp(variable_list_sp->GetVariableAtIndex(i));
213 if (variable_sp) {
214 bool add_variable = false;
215 switch (variable_sp->GetScope()) {
216 case eValueTypeVariableGlobal:
217 case eValueTypeVariableStatic:
218 case eValueTypeVariableThreadLocal:
219 add_variable = statics;
220 break;
221
222 case eValueTypeVariableArgument:
223 add_variable = arguments;
224 break;
225
226 case eValueTypeVariableLocal:
227 add_variable = locals;
228 break;
229
230 default:
231 break;
232 }
233 if (add_variable) {
234 if (frame_sp) {
235 lldb::ValueObjectSP valobj_sp(
236 frame_sp->GetValueObjectForFrameVariable(variable_sp,
237 eNoDynamicValues));
238 SBValue value_sb;
239 value_sb.SetSP(valobj_sp, use_dynamic);
240 value_list.Append(value_sb);
241 }
242 }
243 }
244 }
245 }
246 }
247 }
248 return value_list;
249 }
250
GetVariables(lldb::SBTarget & target,bool arguments,bool locals,bool statics)251 lldb::SBValueList SBBlock::GetVariables(lldb::SBTarget &target, bool arguments,
252 bool locals, bool statics) {
253 Block *block = GetPtr();
254
255 SBValueList value_list;
256 if (block) {
257 TargetSP target_sp(target.GetSP());
258
259 VariableListSP variable_list_sp(block->GetBlockVariableList(true));
260
261 if (variable_list_sp) {
262 const size_t num_variables = variable_list_sp->GetSize();
263 if (num_variables) {
264 for (size_t i = 0; i < num_variables; ++i) {
265 VariableSP variable_sp(variable_list_sp->GetVariableAtIndex(i));
266 if (variable_sp) {
267 bool add_variable = false;
268 switch (variable_sp->GetScope()) {
269 case eValueTypeVariableGlobal:
270 case eValueTypeVariableStatic:
271 case eValueTypeVariableThreadLocal:
272 add_variable = statics;
273 break;
274
275 case eValueTypeVariableArgument:
276 add_variable = arguments;
277 break;
278
279 case eValueTypeVariableLocal:
280 add_variable = locals;
281 break;
282
283 default:
284 break;
285 }
286 if (add_variable) {
287 if (target_sp)
288 value_list.Append(
289 ValueObjectVariable::Create(target_sp.get(), variable_sp));
290 }
291 }
292 }
293 }
294 }
295 }
296 return value_list;
297 }
298