1 //===-- SBBlock.cpp ---------------------------------------------*- C++ -*-===//
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 "SBReproducerPrivate.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"
26 using namespace lldb_private
;
28 SBBlock::SBBlock() : m_opaque_ptr(nullptr) {
29 LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBBlock
);
32 SBBlock::SBBlock(lldb_private::Block
*lldb_object_ptr
)
33 : m_opaque_ptr(lldb_object_ptr
) {}
35 SBBlock::SBBlock(const SBBlock
&rhs
) : m_opaque_ptr(rhs
.m_opaque_ptr
) {
36 LLDB_RECORD_CONSTRUCTOR(SBBlock
, (const lldb::SBBlock
&), rhs
);
39 const SBBlock
&SBBlock::operator=(const SBBlock
&rhs
) {
40 LLDB_RECORD_METHOD(const lldb::SBBlock
&,
41 SBBlock
, operator=,(const lldb::SBBlock
&), rhs
);
43 m_opaque_ptr
= rhs
.m_opaque_ptr
;
44 return LLDB_RECORD_RESULT(*this);
47 SBBlock::~SBBlock() { m_opaque_ptr
= nullptr; }
49 bool SBBlock::IsValid() const {
50 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBlock
, IsValid
);
51 return this->operator bool();
53 SBBlock::operator bool() const {
54 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBlock
, operator bool);
56 return m_opaque_ptr
!= nullptr;
59 bool SBBlock::IsInlined() const {
60 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBlock
, IsInlined
);
63 return m_opaque_ptr
->GetInlinedFunctionInfo() != nullptr;
67 const char *SBBlock::GetInlinedName() const {
68 LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBBlock
, GetInlinedName
);
71 const InlineFunctionInfo
*inlined_info
=
72 m_opaque_ptr
->GetInlinedFunctionInfo();
74 Function
*function
= m_opaque_ptr
->CalculateSymbolContextFunction();
75 LanguageType language
;
77 language
= function
->GetLanguage();
79 language
= lldb::eLanguageTypeUnknown
;
80 return inlined_info
->GetName(language
).AsCString(nullptr);
86 SBFileSpec
SBBlock::GetInlinedCallSiteFile() const {
87 LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBFileSpec
, SBBlock
,
88 GetInlinedCallSiteFile
);
92 const InlineFunctionInfo
*inlined_info
=
93 m_opaque_ptr
->GetInlinedFunctionInfo();
95 sb_file
.SetFileSpec(inlined_info
->GetCallSite().GetFile());
97 return LLDB_RECORD_RESULT(sb_file
);
100 uint32_t SBBlock::GetInlinedCallSiteLine() const {
101 LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBBlock
, GetInlinedCallSiteLine
);
104 const InlineFunctionInfo
*inlined_info
=
105 m_opaque_ptr
->GetInlinedFunctionInfo();
107 return inlined_info
->GetCallSite().GetLine();
112 uint32_t SBBlock::GetInlinedCallSiteColumn() const {
113 LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBBlock
, GetInlinedCallSiteColumn
);
116 const InlineFunctionInfo
*inlined_info
=
117 m_opaque_ptr
->GetInlinedFunctionInfo();
119 return inlined_info
->GetCallSite().GetColumn();
124 void SBBlock::AppendVariables(bool can_create
, bool get_parent_variables
,
125 lldb_private::VariableList
*var_list
) {
127 bool show_inline
= true;
128 m_opaque_ptr
->AppendVariables(can_create
, get_parent_variables
, show_inline
,
129 [](Variable
*) { return true; }, var_list
);
133 SBBlock
SBBlock::GetParent() {
134 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBBlock
, SBBlock
, GetParent
);
138 sb_block
.m_opaque_ptr
= m_opaque_ptr
->GetParent();
139 return LLDB_RECORD_RESULT(sb_block
);
142 lldb::SBBlock
SBBlock::GetContainingInlinedBlock() {
143 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBBlock
, SBBlock
, GetContainingInlinedBlock
);
147 sb_block
.m_opaque_ptr
= m_opaque_ptr
->GetContainingInlinedBlock();
148 return LLDB_RECORD_RESULT(sb_block
);
151 SBBlock
SBBlock::GetSibling() {
152 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBBlock
, SBBlock
, GetSibling
);
156 sb_block
.m_opaque_ptr
= m_opaque_ptr
->GetSibling();
157 return LLDB_RECORD_RESULT(sb_block
);
160 SBBlock
SBBlock::GetFirstChild() {
161 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBBlock
, SBBlock
, GetFirstChild
);
165 sb_block
.m_opaque_ptr
= m_opaque_ptr
->GetFirstChild();
166 return LLDB_RECORD_RESULT(sb_block
);
169 lldb_private::Block
*SBBlock::GetPtr() { return m_opaque_ptr
; }
171 void SBBlock::SetPtr(lldb_private::Block
*block
) { m_opaque_ptr
= block
; }
173 bool SBBlock::GetDescription(SBStream
&description
) {
174 LLDB_RECORD_METHOD(bool, SBBlock
, GetDescription
, (lldb::SBStream
&),
177 Stream
&strm
= description
.ref();
180 lldb::user_id_t id
= m_opaque_ptr
->GetID();
181 strm
.Printf("Block: {id: %" PRIu64
"} ", id
);
183 strm
.Printf(" (inlined, '%s') ", GetInlinedName());
185 lldb_private::SymbolContext sc
;
186 m_opaque_ptr
->CalculateSymbolContext(&sc
);
188 m_opaque_ptr
->DumpAddressRanges(
190 sc
.function
->GetAddressRange().GetBaseAddress().GetFileAddress());
193 strm
.PutCString("No value");
198 uint32_t SBBlock::GetNumRanges() {
199 LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBBlock
, GetNumRanges
);
202 return m_opaque_ptr
->GetNumRanges();
206 lldb::SBAddress
SBBlock::GetRangeStartAddress(uint32_t idx
) {
207 LLDB_RECORD_METHOD(lldb::SBAddress
, SBBlock
, GetRangeStartAddress
, (uint32_t),
210 lldb::SBAddress sb_addr
;
213 if (m_opaque_ptr
->GetRangeAtIndex(idx
, range
)) {
214 sb_addr
.ref() = range
.GetBaseAddress();
217 return LLDB_RECORD_RESULT(sb_addr
);
220 lldb::SBAddress
SBBlock::GetRangeEndAddress(uint32_t idx
) {
221 LLDB_RECORD_METHOD(lldb::SBAddress
, SBBlock
, GetRangeEndAddress
, (uint32_t),
224 lldb::SBAddress sb_addr
;
227 if (m_opaque_ptr
->GetRangeAtIndex(idx
, range
)) {
228 sb_addr
.ref() = range
.GetBaseAddress();
229 sb_addr
.ref().Slide(range
.GetByteSize());
232 return LLDB_RECORD_RESULT(sb_addr
);
235 uint32_t SBBlock::GetRangeIndexForBlockAddress(lldb::SBAddress block_addr
) {
236 LLDB_RECORD_METHOD(uint32_t, SBBlock
, GetRangeIndexForBlockAddress
,
237 (lldb::SBAddress
), block_addr
);
239 if (m_opaque_ptr
&& block_addr
.IsValid()) {
240 return m_opaque_ptr
->GetRangeIndexContainingAddress(block_addr
.ref());
246 lldb::SBValueList
SBBlock::GetVariables(lldb::SBFrame
&frame
, bool arguments
,
247 bool locals
, bool statics
,
248 lldb::DynamicValueType use_dynamic
) {
250 lldb::SBValueList
, SBBlock
, GetVariables
,
251 (lldb::SBFrame
&, bool, bool, bool, lldb::DynamicValueType
), frame
,
252 arguments
, locals
, statics
, use_dynamic
);
254 Block
*block
= GetPtr();
255 SBValueList value_list
;
257 StackFrameSP
frame_sp(frame
.GetFrameSP());
258 VariableListSP
variable_list_sp(block
->GetBlockVariableList(true));
260 if (variable_list_sp
) {
261 const size_t num_variables
= variable_list_sp
->GetSize();
263 for (size_t i
= 0; i
< num_variables
; ++i
) {
264 VariableSP
variable_sp(variable_list_sp
->GetVariableAtIndex(i
));
266 bool add_variable
= false;
267 switch (variable_sp
->GetScope()) {
268 case eValueTypeVariableGlobal
:
269 case eValueTypeVariableStatic
:
270 case eValueTypeVariableThreadLocal
:
271 add_variable
= statics
;
274 case eValueTypeVariableArgument
:
275 add_variable
= arguments
;
278 case eValueTypeVariableLocal
:
279 add_variable
= locals
;
287 lldb::ValueObjectSP
valobj_sp(
288 frame_sp
->GetValueObjectForFrameVariable(variable_sp
,
291 value_sb
.SetSP(valobj_sp
, use_dynamic
);
292 value_list
.Append(value_sb
);
300 return LLDB_RECORD_RESULT(value_list
);
303 lldb::SBValueList
SBBlock::GetVariables(lldb::SBTarget
&target
, bool arguments
,
304 bool locals
, bool statics
) {
305 LLDB_RECORD_METHOD(lldb::SBValueList
, SBBlock
, GetVariables
,
306 (lldb::SBTarget
&, bool, bool, bool), target
, arguments
,
309 Block
*block
= GetPtr();
311 SBValueList value_list
;
313 TargetSP
target_sp(target
.GetSP());
315 VariableListSP
variable_list_sp(block
->GetBlockVariableList(true));
317 if (variable_list_sp
) {
318 const size_t num_variables
= variable_list_sp
->GetSize();
320 for (size_t i
= 0; i
< num_variables
; ++i
) {
321 VariableSP
variable_sp(variable_list_sp
->GetVariableAtIndex(i
));
323 bool add_variable
= false;
324 switch (variable_sp
->GetScope()) {
325 case eValueTypeVariableGlobal
:
326 case eValueTypeVariableStatic
:
327 case eValueTypeVariableThreadLocal
:
328 add_variable
= statics
;
331 case eValueTypeVariableArgument
:
332 add_variable
= arguments
;
335 case eValueTypeVariableLocal
:
336 add_variable
= locals
;
345 ValueObjectVariable::Create(target_sp
.get(), variable_sp
));
352 return LLDB_RECORD_RESULT(value_list
);
355 namespace lldb_private
{
359 void RegisterMethods
<SBBlock
>(Registry
&R
) {
360 LLDB_REGISTER_CONSTRUCTOR(SBBlock
, ());
361 LLDB_REGISTER_CONSTRUCTOR(SBBlock
, (const lldb::SBBlock
&));
362 LLDB_REGISTER_METHOD(const lldb::SBBlock
&,
363 SBBlock
, operator=,(const lldb::SBBlock
&));
364 LLDB_REGISTER_METHOD_CONST(bool, SBBlock
, IsValid
, ());
365 LLDB_REGISTER_METHOD_CONST(bool, SBBlock
, operator bool, ());
366 LLDB_REGISTER_METHOD_CONST(bool, SBBlock
, IsInlined
, ());
367 LLDB_REGISTER_METHOD_CONST(const char *, SBBlock
, GetInlinedName
, ());
368 LLDB_REGISTER_METHOD_CONST(lldb::SBFileSpec
, SBBlock
,
369 GetInlinedCallSiteFile
, ());
370 LLDB_REGISTER_METHOD_CONST(uint32_t, SBBlock
, GetInlinedCallSiteLine
, ());
371 LLDB_REGISTER_METHOD_CONST(uint32_t, SBBlock
, GetInlinedCallSiteColumn
, ());
372 LLDB_REGISTER_METHOD(lldb::SBBlock
, SBBlock
, GetParent
, ());
373 LLDB_REGISTER_METHOD(lldb::SBBlock
, SBBlock
, GetContainingInlinedBlock
, ());
374 LLDB_REGISTER_METHOD(lldb::SBBlock
, SBBlock
, GetSibling
, ());
375 LLDB_REGISTER_METHOD(lldb::SBBlock
, SBBlock
, GetFirstChild
, ());
376 LLDB_REGISTER_METHOD(bool, SBBlock
, GetDescription
, (lldb::SBStream
&));
377 LLDB_REGISTER_METHOD(uint32_t, SBBlock
, GetNumRanges
, ());
378 LLDB_REGISTER_METHOD(lldb::SBAddress
, SBBlock
, GetRangeStartAddress
,
380 LLDB_REGISTER_METHOD(lldb::SBAddress
, SBBlock
, GetRangeEndAddress
,
382 LLDB_REGISTER_METHOD(uint32_t, SBBlock
, GetRangeIndexForBlockAddress
,
384 LLDB_REGISTER_METHOD(
385 lldb::SBValueList
, SBBlock
, GetVariables
,
386 (lldb::SBFrame
&, bool, bool, bool, lldb::DynamicValueType
));
387 LLDB_REGISTER_METHOD(lldb::SBValueList
, SBBlock
, GetVariables
,
388 (lldb::SBTarget
&, bool, bool, bool));