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