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