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, get_parent_variables, show_inline, var_list); 135 } 136 } 137 138 SBBlock 139 SBBlock::GetParent () 140 { 141 SBBlock sb_block; 142 if (m_opaque_ptr) 143 sb_block.m_opaque_ptr = m_opaque_ptr->GetParent(); 144 return sb_block; 145 } 146 147 lldb::SBBlock 148 SBBlock::GetContainingInlinedBlock () 149 { 150 SBBlock sb_block; 151 if (m_opaque_ptr) 152 sb_block.m_opaque_ptr = m_opaque_ptr->GetContainingInlinedBlock (); 153 return sb_block; 154 } 155 156 SBBlock 157 SBBlock::GetSibling () 158 { 159 SBBlock sb_block; 160 if (m_opaque_ptr) 161 sb_block.m_opaque_ptr = m_opaque_ptr->GetSibling(); 162 return sb_block; 163 } 164 165 SBBlock 166 SBBlock::GetFirstChild () 167 { 168 SBBlock sb_block; 169 if (m_opaque_ptr) 170 sb_block.m_opaque_ptr = m_opaque_ptr->GetFirstChild(); 171 return sb_block; 172 } 173 174 lldb_private::Block * 175 SBBlock::GetPtr () 176 { 177 return m_opaque_ptr; 178 } 179 180 void 181 SBBlock::SetPtr (lldb_private::Block *block) 182 { 183 m_opaque_ptr = block; 184 } 185 186 bool 187 SBBlock::GetDescription (SBStream &description) 188 { 189 Stream &strm = description.ref(); 190 191 if (m_opaque_ptr) 192 { 193 lldb::user_id_t id = m_opaque_ptr->GetID(); 194 strm.Printf ("Block: {id: %" PRIu64 "} ", id); 195 if (IsInlined()) 196 { 197 strm.Printf (" (inlined, '%s') ", GetInlinedName()); 198 } 199 lldb_private::SymbolContext sc; 200 m_opaque_ptr->CalculateSymbolContext (&sc); 201 if (sc.function) 202 { 203 m_opaque_ptr->DumpAddressRanges (&strm, 204 sc.function->GetAddressRange().GetBaseAddress().GetFileAddress()); 205 } 206 } 207 else 208 strm.PutCString ("No value"); 209 210 return true; 211 } 212 213 uint32_t 214 SBBlock::GetNumRanges () 215 { 216 if (m_opaque_ptr) 217 return m_opaque_ptr->GetNumRanges(); 218 return 0; 219 } 220 221 lldb::SBAddress 222 SBBlock::GetRangeStartAddress (uint32_t idx) 223 { 224 lldb::SBAddress sb_addr; 225 if (m_opaque_ptr) 226 { 227 AddressRange range; 228 if (m_opaque_ptr->GetRangeAtIndex(idx, range)) 229 { 230 sb_addr.ref() = range.GetBaseAddress(); 231 } 232 } 233 return sb_addr; 234 } 235 236 lldb::SBAddress 237 SBBlock::GetRangeEndAddress (uint32_t idx) 238 { 239 lldb::SBAddress sb_addr; 240 if (m_opaque_ptr) 241 { 242 AddressRange range; 243 if (m_opaque_ptr->GetRangeAtIndex(idx, range)) 244 { 245 sb_addr.ref() = range.GetBaseAddress(); 246 sb_addr.ref().Slide(range.GetByteSize()); 247 } 248 } 249 return sb_addr; 250 } 251 252 uint32_t 253 SBBlock::GetRangeIndexForBlockAddress (lldb::SBAddress block_addr) 254 { 255 if (m_opaque_ptr && block_addr.IsValid()) 256 { 257 return m_opaque_ptr->GetRangeIndexContainingAddress (block_addr.ref()); 258 } 259 260 return UINT32_MAX; 261 } 262 263 264 lldb::SBValueList 265 SBBlock::GetVariables (lldb::SBFrame& frame, 266 bool arguments, 267 bool locals, 268 bool statics, 269 lldb::DynamicValueType use_dynamic) 270 { 271 Block *block = GetPtr(); 272 SBValueList value_list; 273 if (block) 274 { 275 StackFrameSP frame_sp(frame.GetFrameSP()); 276 VariableListSP variable_list_sp (block->GetBlockVariableList (true)); 277 278 if (variable_list_sp) 279 { 280 const size_t num_variables = variable_list_sp->GetSize(); 281 if (num_variables) 282 { 283 for (size_t i = 0; i < num_variables; ++i) 284 { 285 VariableSP variable_sp (variable_list_sp->GetVariableAtIndex(i)); 286 if (variable_sp) 287 { 288 bool add_variable = false; 289 switch (variable_sp->GetScope()) 290 { 291 case eValueTypeVariableGlobal: 292 case eValueTypeVariableStatic: 293 add_variable = statics; 294 break; 295 296 case eValueTypeVariableArgument: 297 add_variable = arguments; 298 break; 299 300 case eValueTypeVariableLocal: 301 add_variable = locals; 302 break; 303 304 default: 305 break; 306 } 307 if (add_variable) 308 { 309 if (frame_sp) 310 { 311 lldb::ValueObjectSP valobj_sp(frame_sp->GetValueObjectForFrameVariable (variable_sp,eNoDynamicValues)); 312 SBValue value_sb; 313 value_sb.SetSP(valobj_sp, use_dynamic); 314 value_list.Append (value_sb); 315 } 316 } 317 } 318 } 319 } 320 } 321 } 322 return value_list; 323 } 324 325 lldb::SBValueList 326 SBBlock::GetVariables (lldb::SBTarget& target, 327 bool arguments, 328 bool locals, 329 bool statics) 330 { 331 Block *block = GetPtr(); 332 333 SBValueList value_list; 334 if (block) 335 { 336 TargetSP target_sp(target.GetSP()); 337 338 VariableListSP variable_list_sp (block->GetBlockVariableList (true)); 339 340 if (variable_list_sp) 341 { 342 const size_t num_variables = variable_list_sp->GetSize(); 343 if (num_variables) 344 { 345 for (size_t i = 0; i < num_variables; ++i) 346 { 347 VariableSP variable_sp (variable_list_sp->GetVariableAtIndex(i)); 348 if (variable_sp) 349 { 350 bool add_variable = false; 351 switch (variable_sp->GetScope()) 352 { 353 case eValueTypeVariableGlobal: 354 case eValueTypeVariableStatic: 355 add_variable = statics; 356 break; 357 358 case eValueTypeVariableArgument: 359 add_variable = arguments; 360 break; 361 362 case eValueTypeVariableLocal: 363 add_variable = locals; 364 break; 365 366 default: 367 break; 368 } 369 if (add_variable) 370 { 371 if (target_sp) 372 value_list.Append (ValueObjectVariable::Create (target_sp.get(), variable_sp)); 373 } 374 } 375 } 376 } 377 } 378 } 379 return value_list; 380 } 381 382