1 //===-- SBBlock.cpp -------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "lldb/API/SBBlock.h"
10 #include "lldb/API/SBAddress.h"
11 #include "lldb/API/SBFileSpec.h"
12 #include "lldb/API/SBFrame.h"
13 #include "lldb/API/SBStream.h"
14 #include "lldb/API/SBValue.h"
15 #include "lldb/Core/AddressRange.h"
16 #include "lldb/Core/AddressRangeListImpl.h"
17 #include "lldb/Symbol/Block.h"
18 #include "lldb/Symbol/Function.h"
19 #include "lldb/Symbol/SymbolContext.h"
20 #include "lldb/Symbol/VariableList.h"
21 #include "lldb/Target/StackFrame.h"
22 #include "lldb/Target/Target.h"
23 #include "lldb/Utility/Instrumentation.h"
24 #include "lldb/ValueObject/ValueObjectVariable.h"
27 using namespace lldb_private
;
29 SBBlock::SBBlock() { LLDB_INSTRUMENT_VA(this); }
31 SBBlock::SBBlock(lldb_private::Block
*lldb_object_ptr
)
32 : m_opaque_ptr(lldb_object_ptr
) {}
34 SBBlock::SBBlock(const SBBlock
&rhs
) : m_opaque_ptr(rhs
.m_opaque_ptr
) {
35 LLDB_INSTRUMENT_VA(this, rhs
);
38 const SBBlock
&SBBlock::operator=(const SBBlock
&rhs
) {
39 LLDB_INSTRUMENT_VA(this, rhs
);
41 m_opaque_ptr
= rhs
.m_opaque_ptr
;
45 SBBlock::~SBBlock() { m_opaque_ptr
= nullptr; }
47 bool SBBlock::IsValid() const {
48 LLDB_INSTRUMENT_VA(this);
49 return this->operator bool();
51 SBBlock::operator bool() const {
52 LLDB_INSTRUMENT_VA(this);
54 return m_opaque_ptr
!= nullptr;
57 bool SBBlock::IsInlined() const {
58 LLDB_INSTRUMENT_VA(this);
61 return m_opaque_ptr
->GetInlinedFunctionInfo() != nullptr;
65 const char *SBBlock::GetInlinedName() const {
66 LLDB_INSTRUMENT_VA(this);
69 const InlineFunctionInfo
*inlined_info
=
70 m_opaque_ptr
->GetInlinedFunctionInfo();
72 return inlined_info
->GetName().AsCString(nullptr);
78 SBFileSpec
SBBlock::GetInlinedCallSiteFile() const {
79 LLDB_INSTRUMENT_VA(this);
83 const InlineFunctionInfo
*inlined_info
=
84 m_opaque_ptr
->GetInlinedFunctionInfo();
86 sb_file
.SetFileSpec(inlined_info
->GetCallSite().GetFile());
91 uint32_t SBBlock::GetInlinedCallSiteLine() const {
92 LLDB_INSTRUMENT_VA(this);
95 const InlineFunctionInfo
*inlined_info
=
96 m_opaque_ptr
->GetInlinedFunctionInfo();
98 return inlined_info
->GetCallSite().GetLine();
103 uint32_t SBBlock::GetInlinedCallSiteColumn() const {
104 LLDB_INSTRUMENT_VA(this);
107 const InlineFunctionInfo
*inlined_info
=
108 m_opaque_ptr
->GetInlinedFunctionInfo();
110 return inlined_info
->GetCallSite().GetColumn();
115 void SBBlock::AppendVariables(bool can_create
, bool get_parent_variables
,
116 lldb_private::VariableList
*var_list
) {
118 bool show_inline
= true;
119 m_opaque_ptr
->AppendVariables(can_create
, get_parent_variables
, show_inline
,
120 [](Variable
*) { return true; }, var_list
);
124 SBBlock
SBBlock::GetParent() {
125 LLDB_INSTRUMENT_VA(this);
129 sb_block
.m_opaque_ptr
= m_opaque_ptr
->GetParent();
133 lldb::SBBlock
SBBlock::GetContainingInlinedBlock() {
134 LLDB_INSTRUMENT_VA(this);
138 sb_block
.m_opaque_ptr
= m_opaque_ptr
->GetContainingInlinedBlock();
142 SBBlock
SBBlock::GetSibling() {
143 LLDB_INSTRUMENT_VA(this);
147 sb_block
.m_opaque_ptr
= m_opaque_ptr
->GetSibling();
151 SBBlock
SBBlock::GetFirstChild() {
152 LLDB_INSTRUMENT_VA(this);
156 sb_block
.m_opaque_ptr
= m_opaque_ptr
->GetFirstChild();
160 lldb_private::Block
*SBBlock::GetPtr() { return m_opaque_ptr
; }
162 void SBBlock::SetPtr(lldb_private::Block
*block
) { m_opaque_ptr
= block
; }
164 bool SBBlock::GetDescription(SBStream
&description
) {
165 LLDB_INSTRUMENT_VA(this, description
);
167 Stream
&strm
= description
.ref();
170 lldb::user_id_t id
= m_opaque_ptr
->GetID();
171 strm
.Printf("Block: {id: %" PRIu64
"} ", id
);
173 strm
.Printf(" (inlined, '%s') ", GetInlinedName());
175 lldb_private::SymbolContext sc
;
176 m_opaque_ptr
->CalculateSymbolContext(&sc
);
178 m_opaque_ptr
->DumpAddressRanges(
180 sc
.function
->GetAddressRange().GetBaseAddress().GetFileAddress());
183 strm
.PutCString("No value");
188 uint32_t SBBlock::GetNumRanges() {
189 LLDB_INSTRUMENT_VA(this);
192 return m_opaque_ptr
->GetNumRanges();
196 lldb::SBAddress
SBBlock::GetRangeStartAddress(uint32_t idx
) {
197 LLDB_INSTRUMENT_VA(this, idx
);
199 lldb::SBAddress sb_addr
;
202 if (m_opaque_ptr
->GetRangeAtIndex(idx
, range
)) {
203 sb_addr
.ref() = range
.GetBaseAddress();
209 lldb::SBAddress
SBBlock::GetRangeEndAddress(uint32_t idx
) {
210 LLDB_INSTRUMENT_VA(this, idx
);
212 lldb::SBAddress sb_addr
;
215 if (m_opaque_ptr
->GetRangeAtIndex(idx
, range
)) {
216 sb_addr
.ref() = range
.GetBaseAddress();
217 sb_addr
.ref().Slide(range
.GetByteSize());
223 lldb::SBAddressRangeList
SBBlock::GetRanges() {
224 LLDB_INSTRUMENT_VA(this);
226 lldb::SBAddressRangeList sb_ranges
;
228 sb_ranges
.m_opaque_up
->ref() = m_opaque_ptr
->GetRanges();
232 uint32_t SBBlock::GetRangeIndexForBlockAddress(lldb::SBAddress block_addr
) {
233 LLDB_INSTRUMENT_VA(this, block_addr
);
235 if (m_opaque_ptr
&& block_addr
.IsValid()) {
236 return m_opaque_ptr
->GetRangeIndexContainingAddress(block_addr
.ref());
242 lldb::SBValueList
SBBlock::GetVariables(lldb::SBFrame
&frame
, bool arguments
,
243 bool locals
, bool statics
,
244 lldb::DynamicValueType use_dynamic
) {
245 LLDB_INSTRUMENT_VA(this, frame
, arguments
, locals
, statics
, use_dynamic
);
247 Block
*block
= GetPtr();
248 SBValueList value_list
;
250 StackFrameSP
frame_sp(frame
.GetFrameSP());
251 VariableListSP
variable_list_sp(block
->GetBlockVariableList(true));
253 if (variable_list_sp
) {
254 const size_t num_variables
= variable_list_sp
->GetSize();
256 for (size_t i
= 0; i
< num_variables
; ++i
) {
257 VariableSP
variable_sp(variable_list_sp
->GetVariableAtIndex(i
));
259 bool add_variable
= false;
260 switch (variable_sp
->GetScope()) {
261 case eValueTypeVariableGlobal
:
262 case eValueTypeVariableStatic
:
263 case eValueTypeVariableThreadLocal
:
264 add_variable
= statics
;
267 case eValueTypeVariableArgument
:
268 add_variable
= arguments
;
271 case eValueTypeVariableLocal
:
272 add_variable
= locals
;
280 lldb::ValueObjectSP
valobj_sp(
281 frame_sp
->GetValueObjectForFrameVariable(variable_sp
,
284 value_sb
.SetSP(valobj_sp
, use_dynamic
);
285 value_list
.Append(value_sb
);
296 lldb::SBValueList
SBBlock::GetVariables(lldb::SBTarget
&target
, bool arguments
,
297 bool locals
, bool statics
) {
298 LLDB_INSTRUMENT_VA(this, target
, arguments
, locals
, statics
);
300 Block
*block
= GetPtr();
302 SBValueList value_list
;
304 TargetSP
target_sp(target
.GetSP());
306 VariableListSP
variable_list_sp(block
->GetBlockVariableList(true));
308 if (variable_list_sp
) {
309 const size_t num_variables
= variable_list_sp
->GetSize();
311 for (size_t i
= 0; i
< num_variables
; ++i
) {
312 VariableSP
variable_sp(variable_list_sp
->GetVariableAtIndex(i
));
314 bool add_variable
= false;
315 switch (variable_sp
->GetScope()) {
316 case eValueTypeVariableGlobal
:
317 case eValueTypeVariableStatic
:
318 case eValueTypeVariableThreadLocal
:
319 add_variable
= statics
;
322 case eValueTypeVariableArgument
:
323 add_variable
= arguments
;
326 case eValueTypeVariableLocal
:
327 add_variable
= locals
;
336 ValueObjectVariable::Create(target_sp
.get(), variable_sp
));