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