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