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