1254721Semaste//===-- SymbolContext.cpp ---------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/Symbol/SymbolContext.h" 11254721Semaste 12254721Semaste#include "lldb/Core/Log.h" 13254721Semaste#include "lldb/Core/Module.h" 14254721Semaste#include "lldb/Core/ModuleSpec.h" 15254721Semaste#include "lldb/Host/Host.h" 16254721Semaste#include "lldb/Interpreter/Args.h" 17254721Semaste#include "lldb/Symbol/Block.h" 18254721Semaste#include "lldb/Symbol/ClangASTContext.h" 19254721Semaste#include "lldb/Symbol/CompileUnit.h" 20254721Semaste#include "lldb/Symbol/ObjectFile.h" 21254721Semaste#include "lldb/Symbol/Symbol.h" 22254721Semaste#include "lldb/Symbol/SymbolFile.h" 23254721Semaste#include "lldb/Symbol/SymbolVendor.h" 24254721Semaste#include "lldb/Target/Target.h" 25254721Semaste 26254721Semasteusing namespace lldb; 27254721Semasteusing namespace lldb_private; 28254721Semaste 29254721SemasteSymbolContext::SymbolContext() : 30254721Semaste target_sp (), 31254721Semaste module_sp (), 32254721Semaste comp_unit (NULL), 33254721Semaste function (NULL), 34254721Semaste block (NULL), 35254721Semaste line_entry (), 36254721Semaste symbol (NULL) 37254721Semaste{ 38254721Semaste} 39254721Semaste 40254721SemasteSymbolContext::SymbolContext(const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) : 41254721Semaste target_sp (), 42254721Semaste module_sp (m), 43254721Semaste comp_unit (cu), 44254721Semaste function (f), 45254721Semaste block (b), 46254721Semaste line_entry (), 47254721Semaste symbol (s) 48254721Semaste{ 49254721Semaste if (le) 50254721Semaste line_entry = *le; 51254721Semaste} 52254721Semaste 53254721SemasteSymbolContext::SymbolContext(const TargetSP &t, const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) : 54254721Semaste target_sp (t), 55254721Semaste module_sp (m), 56254721Semaste comp_unit (cu), 57254721Semaste function (f), 58254721Semaste block (b), 59254721Semaste line_entry (), 60254721Semaste symbol (s) 61254721Semaste{ 62254721Semaste if (le) 63254721Semaste line_entry = *le; 64254721Semaste} 65254721Semaste 66254721SemasteSymbolContext::SymbolContext(const SymbolContext& rhs) : 67254721Semaste target_sp (rhs.target_sp), 68254721Semaste module_sp (rhs.module_sp), 69254721Semaste comp_unit (rhs.comp_unit), 70254721Semaste function (rhs.function), 71254721Semaste block (rhs.block), 72254721Semaste line_entry (rhs.line_entry), 73254721Semaste symbol (rhs.symbol) 74254721Semaste{ 75254721Semaste} 76254721Semaste 77254721Semaste 78254721SemasteSymbolContext::SymbolContext (SymbolContextScope *sc_scope) : 79254721Semaste target_sp (), 80254721Semaste module_sp (), 81254721Semaste comp_unit (NULL), 82254721Semaste function (NULL), 83254721Semaste block (NULL), 84254721Semaste line_entry (), 85254721Semaste symbol (NULL) 86254721Semaste{ 87254721Semaste sc_scope->CalculateSymbolContext (this); 88254721Semaste} 89254721Semaste 90254721SemasteSymbolContext::~SymbolContext () 91254721Semaste{ 92254721Semaste} 93254721Semaste 94254721Semasteconst SymbolContext& 95254721SemasteSymbolContext::operator= (const SymbolContext& rhs) 96254721Semaste{ 97254721Semaste if (this != &rhs) 98254721Semaste { 99254721Semaste target_sp = rhs.target_sp; 100254721Semaste module_sp = rhs.module_sp; 101254721Semaste comp_unit = rhs.comp_unit; 102254721Semaste function = rhs.function; 103254721Semaste block = rhs.block; 104254721Semaste line_entry = rhs.line_entry; 105254721Semaste symbol = rhs.symbol; 106254721Semaste } 107254721Semaste return *this; 108254721Semaste} 109254721Semaste 110254721Semastevoid 111254721SemasteSymbolContext::Clear(bool clear_target) 112254721Semaste{ 113254721Semaste if (clear_target) 114254721Semaste target_sp.reset(); 115254721Semaste module_sp.reset(); 116254721Semaste comp_unit = NULL; 117254721Semaste function = NULL; 118254721Semaste block = NULL; 119254721Semaste line_entry.Clear(); 120254721Semaste symbol = NULL; 121254721Semaste} 122254721Semaste 123254721Semastebool 124254721SemasteSymbolContext::DumpStopContext 125254721Semaste( 126254721Semaste Stream *s, 127254721Semaste ExecutionContextScope *exe_scope, 128254721Semaste const Address &addr, 129254721Semaste bool show_fullpaths, 130254721Semaste bool show_module, 131254721Semaste bool show_inlined_frames 132254721Semaste) const 133254721Semaste{ 134254721Semaste bool dumped_something = false; 135254721Semaste if (show_module && module_sp) 136254721Semaste { 137254721Semaste if (show_fullpaths) 138254721Semaste *s << module_sp->GetFileSpec(); 139254721Semaste else 140254721Semaste *s << module_sp->GetFileSpec().GetFilename(); 141254721Semaste s->PutChar('`'); 142254721Semaste dumped_something = true; 143254721Semaste } 144254721Semaste 145254721Semaste if (function != NULL) 146254721Semaste { 147254721Semaste SymbolContext inline_parent_sc; 148254721Semaste Address inline_parent_addr; 149254721Semaste if (function->GetMangled().GetName()) 150254721Semaste { 151254721Semaste dumped_something = true; 152254721Semaste function->GetMangled().GetName().Dump(s); 153254721Semaste } 154254721Semaste 155254721Semaste if (addr.IsValid()) 156254721Semaste { 157254721Semaste const addr_t function_offset = addr.GetOffset() - function->GetAddressRange().GetBaseAddress().GetOffset(); 158254721Semaste if (function_offset) 159254721Semaste { 160254721Semaste dumped_something = true; 161254721Semaste s->Printf(" + %" PRIu64, function_offset); 162254721Semaste } 163254721Semaste } 164254721Semaste 165254721Semaste if (GetParentOfInlinedScope (addr, inline_parent_sc, inline_parent_addr)) 166254721Semaste { 167254721Semaste dumped_something = true; 168254721Semaste Block *inlined_block = block->GetContainingInlinedBlock(); 169254721Semaste const InlineFunctionInfo* inlined_block_info = inlined_block->GetInlinedFunctionInfo(); 170254721Semaste s->Printf (" [inlined] %s", inlined_block_info->GetName().GetCString()); 171254721Semaste 172254721Semaste lldb_private::AddressRange block_range; 173254721Semaste if (inlined_block->GetRangeContainingAddress(addr, block_range)) 174254721Semaste { 175254721Semaste const addr_t inlined_function_offset = addr.GetOffset() - block_range.GetBaseAddress().GetOffset(); 176254721Semaste if (inlined_function_offset) 177254721Semaste { 178254721Semaste s->Printf(" + %" PRIu64, inlined_function_offset); 179254721Semaste } 180254721Semaste } 181254721Semaste const Declaration &call_site = inlined_block_info->GetCallSite(); 182254721Semaste if (call_site.IsValid()) 183254721Semaste { 184254721Semaste s->PutCString(" at "); 185254721Semaste call_site.DumpStopContext (s, show_fullpaths); 186254721Semaste } 187254721Semaste if (show_inlined_frames) 188254721Semaste { 189254721Semaste s->EOL(); 190254721Semaste s->Indent(); 191254721Semaste return inline_parent_sc.DumpStopContext (s, exe_scope, inline_parent_addr, show_fullpaths, show_module, show_inlined_frames); 192254721Semaste } 193254721Semaste } 194254721Semaste else 195254721Semaste { 196254721Semaste if (line_entry.IsValid()) 197254721Semaste { 198254721Semaste dumped_something = true; 199254721Semaste s->PutCString(" at "); 200254721Semaste if (line_entry.DumpStopContext(s, show_fullpaths)) 201254721Semaste dumped_something = true; 202254721Semaste } 203254721Semaste } 204254721Semaste } 205254721Semaste else if (symbol != NULL) 206254721Semaste { 207254721Semaste if (symbol->GetMangled().GetName()) 208254721Semaste { 209254721Semaste dumped_something = true; 210254721Semaste if (symbol->GetType() == eSymbolTypeTrampoline) 211254721Semaste s->PutCString("symbol stub for: "); 212254721Semaste symbol->GetMangled().GetName().Dump(s); 213254721Semaste } 214254721Semaste 215254721Semaste if (addr.IsValid() && symbol->ValueIsAddress()) 216254721Semaste { 217254721Semaste const addr_t symbol_offset = addr.GetOffset() - symbol->GetAddress().GetOffset(); 218254721Semaste if (symbol_offset) 219254721Semaste { 220254721Semaste dumped_something = true; 221254721Semaste s->Printf(" + %" PRIu64, symbol_offset); 222254721Semaste } 223254721Semaste } 224254721Semaste } 225254721Semaste else if (addr.IsValid()) 226254721Semaste { 227254721Semaste addr.Dump(s, exe_scope, Address::DumpStyleModuleWithFileAddress); 228254721Semaste dumped_something = true; 229254721Semaste } 230254721Semaste return dumped_something; 231254721Semaste} 232254721Semaste 233254721Semastevoid 234254721SemasteSymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target) const 235254721Semaste{ 236254721Semaste if (module_sp) 237254721Semaste { 238254721Semaste s->Indent(" Module: file = \""); 239254721Semaste module_sp->GetFileSpec().Dump(s); 240254721Semaste *s << '"'; 241254721Semaste if (module_sp->GetArchitecture().IsValid()) 242254721Semaste s->Printf (", arch = \"%s\"", module_sp->GetArchitecture().GetArchitectureName()); 243254721Semaste s->EOL(); 244254721Semaste } 245254721Semaste 246254721Semaste if (comp_unit != NULL) 247254721Semaste { 248254721Semaste s->Indent("CompileUnit: "); 249254721Semaste comp_unit->GetDescription (s, level); 250254721Semaste s->EOL(); 251254721Semaste } 252254721Semaste 253254721Semaste if (function != NULL) 254254721Semaste { 255254721Semaste s->Indent(" Function: "); 256254721Semaste function->GetDescription (s, level, target); 257254721Semaste s->EOL(); 258254721Semaste 259254721Semaste Type *func_type = function->GetType(); 260254721Semaste if (func_type) 261254721Semaste { 262254721Semaste s->Indent(" FuncType: "); 263254721Semaste func_type->GetDescription (s, level, false); 264254721Semaste s->EOL(); 265254721Semaste } 266254721Semaste } 267254721Semaste 268254721Semaste if (block != NULL) 269254721Semaste { 270254721Semaste std::vector<Block *> blocks; 271254721Semaste blocks.push_back (block); 272254721Semaste Block *parent_block = block->GetParent(); 273254721Semaste 274254721Semaste while (parent_block) 275254721Semaste { 276254721Semaste blocks.push_back (parent_block); 277254721Semaste parent_block = parent_block->GetParent(); 278254721Semaste } 279254721Semaste std::vector<Block *>::reverse_iterator pos; 280254721Semaste std::vector<Block *>::reverse_iterator begin = blocks.rbegin(); 281254721Semaste std::vector<Block *>::reverse_iterator end = blocks.rend(); 282254721Semaste for (pos = begin; pos != end; ++pos) 283254721Semaste { 284254721Semaste if (pos == begin) 285254721Semaste s->Indent(" Blocks: "); 286254721Semaste else 287254721Semaste s->Indent(" "); 288254721Semaste (*pos)->GetDescription(s, function, level, target); 289254721Semaste s->EOL(); 290254721Semaste } 291254721Semaste } 292254721Semaste 293254721Semaste if (line_entry.IsValid()) 294254721Semaste { 295254721Semaste s->Indent(" LineEntry: "); 296254721Semaste line_entry.GetDescription (s, level, comp_unit, target, false); 297254721Semaste s->EOL(); 298254721Semaste } 299254721Semaste 300254721Semaste if (symbol != NULL) 301254721Semaste { 302254721Semaste s->Indent(" Symbol: "); 303254721Semaste symbol->GetDescription(s, level, target); 304254721Semaste s->EOL(); 305254721Semaste } 306254721Semaste} 307254721Semaste 308254721Semasteuint32_t 309254721SemasteSymbolContext::GetResolvedMask () const 310254721Semaste{ 311254721Semaste uint32_t resolved_mask = 0; 312254721Semaste if (target_sp) resolved_mask |= eSymbolContextTarget; 313254721Semaste if (module_sp) resolved_mask |= eSymbolContextModule; 314254721Semaste if (comp_unit) resolved_mask |= eSymbolContextCompUnit; 315254721Semaste if (function) resolved_mask |= eSymbolContextFunction; 316254721Semaste if (block) resolved_mask |= eSymbolContextBlock; 317254721Semaste if (line_entry.IsValid()) resolved_mask |= eSymbolContextLineEntry; 318254721Semaste if (symbol) resolved_mask |= eSymbolContextSymbol; 319254721Semaste return resolved_mask; 320254721Semaste} 321254721Semaste 322254721Semastevoid 323254721SemasteSymbolContext::Dump(Stream *s, Target *target) const 324254721Semaste{ 325254721Semaste *s << (void *)this << ": "; 326254721Semaste s->Indent(); 327254721Semaste s->PutCString("SymbolContext"); 328254721Semaste s->IndentMore(); 329254721Semaste s->EOL(); 330254721Semaste s->IndentMore(); 331254721Semaste s->Indent(); 332254721Semaste *s << "Module = " << (void *)module_sp.get() << ' '; 333254721Semaste if (module_sp) 334254721Semaste module_sp->GetFileSpec().Dump(s); 335254721Semaste s->EOL(); 336254721Semaste s->Indent(); 337254721Semaste *s << "CompileUnit = " << (void *)comp_unit; 338254721Semaste if (comp_unit != NULL) 339254721Semaste *s << " {0x" << comp_unit->GetID() << "} " << *(static_cast<FileSpec*> (comp_unit)); 340254721Semaste s->EOL(); 341254721Semaste s->Indent(); 342254721Semaste *s << "Function = " << (void *)function; 343254721Semaste if (function != NULL) 344254721Semaste { 345254721Semaste *s << " {0x" << function->GetID() << "} " << function->GetType()->GetName() << ", address-range = "; 346254721Semaste function->GetAddressRange().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress); 347254721Semaste s->EOL(); 348254721Semaste s->Indent(); 349254721Semaste Type* func_type = function->GetType(); 350254721Semaste if (func_type) 351254721Semaste { 352254721Semaste *s << " Type = "; 353254721Semaste func_type->Dump (s, false); 354254721Semaste } 355254721Semaste } 356254721Semaste s->EOL(); 357254721Semaste s->Indent(); 358254721Semaste *s << "Block = " << (void *)block; 359254721Semaste if (block != NULL) 360254721Semaste *s << " {0x" << block->GetID() << '}'; 361254721Semaste // Dump the block and pass it a negative depth to we print all the parent blocks 362254721Semaste //if (block != NULL) 363254721Semaste // block->Dump(s, function->GetFileAddress(), INT_MIN); 364254721Semaste s->EOL(); 365254721Semaste s->Indent(); 366254721Semaste *s << "LineEntry = "; 367254721Semaste line_entry.Dump (s, target, true, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, true); 368254721Semaste s->EOL(); 369254721Semaste s->Indent(); 370254721Semaste *s << "Symbol = " << (void *)symbol; 371254721Semaste if (symbol != NULL && symbol->GetMangled()) 372254721Semaste *s << ' ' << symbol->GetMangled().GetName().AsCString(); 373254721Semaste s->EOL(); 374254721Semaste s->IndentLess(); 375254721Semaste s->IndentLess(); 376254721Semaste} 377254721Semaste 378254721Semastebool 379254721Semastelldb_private::operator== (const SymbolContext& lhs, const SymbolContext& rhs) 380254721Semaste{ 381254721Semaste return lhs.function == rhs.function 382254721Semaste && lhs.symbol == rhs.symbol 383254721Semaste && lhs.module_sp.get() == rhs.module_sp.get() 384254721Semaste && lhs.comp_unit == rhs.comp_unit 385254721Semaste && lhs.target_sp.get() == rhs.target_sp.get() 386254721Semaste && LineEntry::Compare(lhs.line_entry, rhs.line_entry) == 0; 387254721Semaste} 388254721Semaste 389254721Semastebool 390254721Semastelldb_private::operator!= (const SymbolContext& lhs, const SymbolContext& rhs) 391254721Semaste{ 392254721Semaste return lhs.function != rhs.function 393254721Semaste || lhs.symbol != rhs.symbol 394254721Semaste || lhs.module_sp.get() != rhs.module_sp.get() 395254721Semaste || lhs.comp_unit != rhs.comp_unit 396254721Semaste || lhs.target_sp.get() != rhs.target_sp.get() 397254721Semaste || LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0; 398254721Semaste} 399254721Semaste 400254721Semastebool 401254721SemasteSymbolContext::GetAddressRange (uint32_t scope, 402254721Semaste uint32_t range_idx, 403254721Semaste bool use_inline_block_range, 404254721Semaste AddressRange &range) const 405254721Semaste{ 406254721Semaste if ((scope & eSymbolContextLineEntry) && line_entry.IsValid()) 407254721Semaste { 408254721Semaste range = line_entry.range; 409254721Semaste return true; 410254721Semaste } 411254721Semaste 412254721Semaste if ((scope & eSymbolContextBlock) && (block != NULL)) 413254721Semaste { 414254721Semaste if (use_inline_block_range) 415254721Semaste { 416254721Semaste Block *inline_block = block->GetContainingInlinedBlock(); 417254721Semaste if (inline_block) 418254721Semaste return inline_block->GetRangeAtIndex (range_idx, range); 419254721Semaste } 420254721Semaste else 421254721Semaste { 422254721Semaste return block->GetRangeAtIndex (range_idx, range); 423254721Semaste } 424254721Semaste } 425254721Semaste 426254721Semaste if ((scope & eSymbolContextFunction) && (function != NULL)) 427254721Semaste { 428254721Semaste if (range_idx == 0) 429254721Semaste { 430254721Semaste range = function->GetAddressRange(); 431254721Semaste return true; 432254721Semaste } 433254721Semaste } 434254721Semaste 435254721Semaste if ((scope & eSymbolContextSymbol) && (symbol != NULL)) 436254721Semaste { 437254721Semaste if (range_idx == 0) 438254721Semaste { 439254721Semaste if (symbol->ValueIsAddress()) 440254721Semaste { 441254721Semaste range.GetBaseAddress() = symbol->GetAddress(); 442254721Semaste range.SetByteSize (symbol->GetByteSize()); 443254721Semaste return true; 444254721Semaste } 445254721Semaste } 446254721Semaste } 447254721Semaste range.Clear(); 448254721Semaste return false; 449254721Semaste} 450254721Semaste 451254721Semastebool 452254721SemasteSymbolContext::GetParentOfInlinedScope (const Address &curr_frame_pc, 453254721Semaste SymbolContext &next_frame_sc, 454254721Semaste Address &next_frame_pc) const 455254721Semaste{ 456254721Semaste next_frame_sc.Clear(false); 457254721Semaste next_frame_pc.Clear(); 458254721Semaste 459254721Semaste if (block) 460254721Semaste { 461254721Semaste //const addr_t curr_frame_file_addr = curr_frame_pc.GetFileAddress(); 462254721Semaste 463254721Semaste // In order to get the parent of an inlined function we first need to 464254721Semaste // see if we are in an inlined block as "this->block" could be an 465254721Semaste // inlined block, or a parent of "block" could be. So lets check if 466254721Semaste // this block or one of this blocks parents is an inlined function. 467254721Semaste Block *curr_inlined_block = block->GetContainingInlinedBlock(); 468254721Semaste if (curr_inlined_block) 469254721Semaste { 470254721Semaste // "this->block" is contained in an inline function block, so to 471254721Semaste // get the scope above the inlined block, we get the parent of the 472254721Semaste // inlined block itself 473254721Semaste Block *next_frame_block = curr_inlined_block->GetParent(); 474254721Semaste // Now calculate the symbol context of the containing block 475254721Semaste next_frame_block->CalculateSymbolContext (&next_frame_sc); 476254721Semaste 477254721Semaste // If we get here we weren't able to find the return line entry using the nesting of the blocks and 478254721Semaste // the line table. So just use the call site info from our inlined block. 479254721Semaste 480254721Semaste AddressRange range; 481254721Semaste if (curr_inlined_block->GetRangeContainingAddress (curr_frame_pc, range)) 482254721Semaste { 483254721Semaste // To see there this new frame block it, we need to look at the 484254721Semaste // call site information from 485254721Semaste const InlineFunctionInfo* curr_inlined_block_inlined_info = curr_inlined_block->GetInlinedFunctionInfo(); 486254721Semaste next_frame_pc = range.GetBaseAddress(); 487254721Semaste next_frame_sc.line_entry.range.GetBaseAddress() = next_frame_pc; 488254721Semaste next_frame_sc.line_entry.file = curr_inlined_block_inlined_info->GetCallSite().GetFile(); 489254721Semaste next_frame_sc.line_entry.line = curr_inlined_block_inlined_info->GetCallSite().GetLine(); 490254721Semaste next_frame_sc.line_entry.column = curr_inlined_block_inlined_info->GetCallSite().GetColumn(); 491254721Semaste return true; 492254721Semaste } 493254721Semaste else 494254721Semaste { 495254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS)); 496254721Semaste 497254721Semaste if (log) 498254721Semaste { 499254721Semaste log->Printf ("warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64, 500254721Semaste curr_inlined_block->GetID(), curr_frame_pc.GetFileAddress()); 501254721Semaste } 502254721Semaste#ifdef LLDB_CONFIGURATION_DEBUG 503254721Semaste else 504254721Semaste { 505254721Semaste ObjectFile *objfile = NULL; 506254721Semaste if (module_sp) 507254721Semaste { 508254721Semaste SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(); 509254721Semaste if (symbol_vendor) 510254721Semaste { 511254721Semaste SymbolFile *symbol_file = symbol_vendor->GetSymbolFile(); 512254721Semaste if (symbol_file) 513254721Semaste objfile = symbol_file->GetObjectFile(); 514254721Semaste } 515254721Semaste } 516254721Semaste if (objfile) 517254721Semaste { 518254721Semaste Host::SystemLog (Host::eSystemLogWarning, 519254721Semaste "warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64 " in %s\n", 520254721Semaste curr_inlined_block->GetID(), 521254721Semaste curr_frame_pc.GetFileAddress(), 522254721Semaste objfile->GetFileSpec().GetPath().c_str()); 523254721Semaste } 524254721Semaste else 525254721Semaste { 526254721Semaste Host::SystemLog (Host::eSystemLogWarning, 527254721Semaste "warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64 "\n", 528254721Semaste curr_inlined_block->GetID(), 529254721Semaste curr_frame_pc.GetFileAddress()); 530254721Semaste } 531254721Semaste } 532254721Semaste#endif 533254721Semaste } 534254721Semaste } 535254721Semaste } 536254721Semaste 537254721Semaste return false; 538254721Semaste} 539254721Semaste 540254721SemasteBlock * 541254721SemasteSymbolContext::GetFunctionBlock () 542254721Semaste{ 543254721Semaste if (function) 544254721Semaste { 545254721Semaste if (block) 546254721Semaste { 547254721Semaste // If this symbol context has a block, check to see if this block 548254721Semaste // is itself, or is contained within a block with inlined function 549254721Semaste // information. If so, then the inlined block is the block that 550254721Semaste // defines the function. 551254721Semaste Block *inlined_block = block->GetContainingInlinedBlock(); 552254721Semaste if (inlined_block) 553254721Semaste return inlined_block; 554254721Semaste 555254721Semaste // The block in this symbol context is not inside an inlined 556254721Semaste // block, so the block that defines the function is the function's 557254721Semaste // top level block, which is returned below. 558254721Semaste } 559254721Semaste 560254721Semaste // There is no block information in this symbol context, so we must 561254721Semaste // assume that the block that is desired is the top level block of 562254721Semaste // the function itself. 563254721Semaste return &function->GetBlock(true); 564254721Semaste } 565254721Semaste return NULL; 566254721Semaste} 567254721Semaste 568254721Semastebool 569254721SemasteSymbolContext::GetFunctionMethodInfo (lldb::LanguageType &language, 570254721Semaste bool &is_instance_method, 571254721Semaste ConstString &language_object_name) 572254721Semaste 573254721Semaste 574254721Semaste{ 575254721Semaste Block *function_block = GetFunctionBlock (); 576254721Semaste if (function_block) 577254721Semaste { 578254721Semaste clang::DeclContext *decl_context = function_block->GetClangDeclContext(); 579254721Semaste 580254721Semaste if (decl_context) 581254721Semaste { 582254721Semaste return ClangASTContext::GetClassMethodInfoForDeclContext (decl_context, 583254721Semaste language, 584254721Semaste is_instance_method, 585254721Semaste language_object_name); 586254721Semaste } 587254721Semaste } 588254721Semaste language = eLanguageTypeUnknown; 589254721Semaste is_instance_method = false; 590254721Semaste language_object_name.Clear(); 591254721Semaste return false; 592254721Semaste} 593254721Semaste 594254721SemasteConstString 595254721SemasteSymbolContext::GetFunctionName (Mangled::NamePreference preference) const 596254721Semaste{ 597254721Semaste if (function) 598254721Semaste { 599254721Semaste if (block) 600254721Semaste { 601254721Semaste Block *inlined_block = block->GetContainingInlinedBlock(); 602254721Semaste 603254721Semaste if (inlined_block) 604254721Semaste { 605254721Semaste const InlineFunctionInfo *inline_info = inlined_block->GetInlinedFunctionInfo(); 606254721Semaste if (inline_info) 607254721Semaste return inline_info->GetName(); 608254721Semaste } 609254721Semaste } 610254721Semaste return function->GetMangled().GetName(preference); 611254721Semaste } 612254721Semaste else if (symbol && symbol->ValueIsAddress()) 613254721Semaste { 614254721Semaste return symbol->GetMangled().GetName(preference); 615254721Semaste } 616254721Semaste else 617254721Semaste { 618254721Semaste // No function, return an empty string. 619254721Semaste return ConstString(); 620254721Semaste } 621254721Semaste} 622254721Semaste 623254721SemasteLineEntry 624254721SemasteSymbolContext::GetFunctionStartLineEntry () const 625254721Semaste{ 626254721Semaste LineEntry line_entry; 627254721Semaste Address start_addr; 628254721Semaste if (block) 629254721Semaste { 630254721Semaste Block *inlined_block = block->GetContainingInlinedBlock(); 631254721Semaste if (inlined_block) 632254721Semaste { 633254721Semaste if (inlined_block->GetStartAddress (start_addr)) 634254721Semaste { 635254721Semaste if (start_addr.CalculateSymbolContextLineEntry (line_entry)) 636254721Semaste return line_entry; 637254721Semaste } 638254721Semaste return LineEntry(); 639254721Semaste } 640254721Semaste } 641254721Semaste 642254721Semaste if (function) 643254721Semaste { 644254721Semaste if (function->GetAddressRange().GetBaseAddress().CalculateSymbolContextLineEntry(line_entry)) 645254721Semaste return line_entry; 646254721Semaste } 647254721Semaste return LineEntry(); 648254721Semaste} 649254721Semaste 650254721Semaste//---------------------------------------------------------------------- 651254721Semaste// 652254721Semaste// SymbolContextSpecifier 653254721Semaste// 654254721Semaste//---------------------------------------------------------------------- 655254721Semaste 656254721SemasteSymbolContextSpecifier::SymbolContextSpecifier (const TargetSP &target_sp) : 657254721Semaste m_target_sp (target_sp), 658254721Semaste m_module_spec (), 659254721Semaste m_module_sp (), 660254721Semaste m_file_spec_ap (), 661254721Semaste m_start_line (0), 662254721Semaste m_end_line (0), 663254721Semaste m_function_spec (), 664254721Semaste m_class_name (), 665254721Semaste m_address_range_ap (), 666254721Semaste m_type (eNothingSpecified) 667254721Semaste{ 668254721Semaste} 669254721Semaste 670254721SemasteSymbolContextSpecifier::~SymbolContextSpecifier() 671254721Semaste{ 672254721Semaste} 673254721Semaste 674254721Semastebool 675254721SemasteSymbolContextSpecifier::AddLineSpecification (uint32_t line_no, SpecificationType type) 676254721Semaste{ 677254721Semaste bool return_value = true; 678254721Semaste switch (type) 679254721Semaste { 680254721Semaste case eNothingSpecified: 681254721Semaste Clear(); 682254721Semaste break; 683254721Semaste case eLineStartSpecified: 684254721Semaste m_start_line = line_no; 685254721Semaste m_type |= eLineStartSpecified; 686254721Semaste break; 687254721Semaste case eLineEndSpecified: 688254721Semaste m_end_line = line_no; 689254721Semaste m_type |= eLineEndSpecified; 690254721Semaste break; 691254721Semaste default: 692254721Semaste return_value = false; 693254721Semaste break; 694254721Semaste } 695254721Semaste return return_value; 696254721Semaste} 697254721Semaste 698254721Semastebool 699254721SemasteSymbolContextSpecifier::AddSpecification (const char *spec_string, SpecificationType type) 700254721Semaste{ 701254721Semaste bool return_value = true; 702254721Semaste switch (type) 703254721Semaste { 704254721Semaste case eNothingSpecified: 705254721Semaste Clear(); 706254721Semaste break; 707254721Semaste case eModuleSpecified: 708254721Semaste { 709254721Semaste // See if we can find the Module, if so stick it in the SymbolContext. 710254721Semaste FileSpec module_file_spec(spec_string, false); 711254721Semaste ModuleSpec module_spec (module_file_spec); 712254721Semaste lldb::ModuleSP module_sp (m_target_sp->GetImages().FindFirstModule (module_spec)); 713254721Semaste m_type |= eModuleSpecified; 714254721Semaste if (module_sp) 715254721Semaste m_module_sp = module_sp; 716254721Semaste else 717254721Semaste m_module_spec.assign (spec_string); 718254721Semaste } 719254721Semaste break; 720254721Semaste case eFileSpecified: 721254721Semaste // CompUnits can't necessarily be resolved here, since an inlined function might show up in 722254721Semaste // a number of CompUnits. Instead we just convert to a FileSpec and store it away. 723254721Semaste m_file_spec_ap.reset (new FileSpec (spec_string, false)); 724254721Semaste m_type |= eFileSpecified; 725254721Semaste break; 726254721Semaste case eLineStartSpecified: 727254721Semaste m_start_line = Args::StringToSInt32(spec_string, 0, 0, &return_value); 728254721Semaste if (return_value) 729254721Semaste m_type |= eLineStartSpecified; 730254721Semaste break; 731254721Semaste case eLineEndSpecified: 732254721Semaste m_end_line = Args::StringToSInt32(spec_string, 0, 0, &return_value); 733254721Semaste if (return_value) 734254721Semaste m_type |= eLineEndSpecified; 735254721Semaste break; 736254721Semaste case eFunctionSpecified: 737254721Semaste m_function_spec.assign(spec_string); 738254721Semaste m_type |= eFunctionSpecified; 739254721Semaste break; 740254721Semaste case eClassOrNamespaceSpecified: 741254721Semaste Clear(); 742254721Semaste m_class_name.assign (spec_string); 743254721Semaste m_type = eClassOrNamespaceSpecified; 744254721Semaste break; 745254721Semaste case eAddressRangeSpecified: 746254721Semaste // Not specified yet... 747254721Semaste break; 748254721Semaste } 749254721Semaste 750254721Semaste return return_value; 751254721Semaste} 752254721Semaste 753254721Semastevoid 754254721SemasteSymbolContextSpecifier::Clear() 755254721Semaste{ 756254721Semaste m_module_spec.clear(); 757254721Semaste m_file_spec_ap.reset(); 758254721Semaste m_function_spec.clear(); 759254721Semaste m_class_name.clear(); 760254721Semaste m_start_line = 0; 761254721Semaste m_end_line = 0; 762254721Semaste m_address_range_ap.reset(); 763254721Semaste 764254721Semaste m_type = eNothingSpecified; 765254721Semaste} 766254721Semaste 767254721Semastebool 768254721SemasteSymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc) 769254721Semaste{ 770254721Semaste if (m_type == eNothingSpecified) 771254721Semaste return true; 772254721Semaste 773254721Semaste if (m_target_sp.get() != sc.target_sp.get()) 774254721Semaste return false; 775254721Semaste 776254721Semaste if (m_type & eModuleSpecified) 777254721Semaste { 778254721Semaste if (sc.module_sp) 779254721Semaste { 780254721Semaste if (m_module_sp.get() != NULL) 781254721Semaste { 782254721Semaste if (m_module_sp.get() != sc.module_sp.get()) 783254721Semaste return false; 784254721Semaste } 785254721Semaste else 786254721Semaste { 787254721Semaste FileSpec module_file_spec (m_module_spec.c_str(), false); 788254721Semaste if (!FileSpec::Equal (module_file_spec, sc.module_sp->GetFileSpec(), false)) 789254721Semaste return false; 790254721Semaste } 791254721Semaste } 792254721Semaste } 793254721Semaste if (m_type & eFileSpecified) 794254721Semaste { 795254721Semaste if (m_file_spec_ap.get()) 796254721Semaste { 797254721Semaste // If we don't have a block or a comp_unit, then we aren't going to match a source file. 798254721Semaste if (sc.block == NULL && sc.comp_unit == NULL) 799254721Semaste return false; 800254721Semaste 801254721Semaste // Check if the block is present, and if so is it inlined: 802254721Semaste bool was_inlined = false; 803254721Semaste if (sc.block != NULL) 804254721Semaste { 805254721Semaste const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo(); 806254721Semaste if (inline_info != NULL) 807254721Semaste { 808254721Semaste was_inlined = true; 809254721Semaste if (!FileSpec::Equal (inline_info->GetDeclaration().GetFile(), *(m_file_spec_ap.get()), false)) 810254721Semaste return false; 811254721Semaste } 812254721Semaste } 813254721Semaste 814254721Semaste // Next check the comp unit, but only if the SymbolContext was not inlined. 815254721Semaste if (!was_inlined && sc.comp_unit != NULL) 816254721Semaste { 817254721Semaste if (!FileSpec::Equal (*(sc.comp_unit), *(m_file_spec_ap.get()), false)) 818254721Semaste return false; 819254721Semaste } 820254721Semaste } 821254721Semaste } 822254721Semaste if (m_type & eLineStartSpecified 823254721Semaste || m_type & eLineEndSpecified) 824254721Semaste { 825254721Semaste if (sc.line_entry.line < m_start_line || sc.line_entry.line > m_end_line) 826254721Semaste return false; 827254721Semaste } 828254721Semaste 829254721Semaste if (m_type & eFunctionSpecified) 830254721Semaste { 831254721Semaste // First check the current block, and if it is inlined, get the inlined function name: 832254721Semaste bool was_inlined = false; 833254721Semaste ConstString func_name(m_function_spec.c_str()); 834254721Semaste 835254721Semaste if (sc.block != NULL) 836254721Semaste { 837254721Semaste const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo(); 838254721Semaste if (inline_info != NULL) 839254721Semaste { 840254721Semaste was_inlined = true; 841254721Semaste const Mangled &name = inline_info->GetMangled(); 842254721Semaste if (!name.NameMatches (func_name)) 843254721Semaste return false; 844254721Semaste } 845254721Semaste } 846254721Semaste // If it wasn't inlined, check the name in the function or symbol: 847254721Semaste if (!was_inlined) 848254721Semaste { 849254721Semaste if (sc.function != NULL) 850254721Semaste { 851254721Semaste if (!sc.function->GetMangled().NameMatches(func_name)) 852254721Semaste return false; 853254721Semaste } 854254721Semaste else if (sc.symbol != NULL) 855254721Semaste { 856254721Semaste if (!sc.symbol->GetMangled().NameMatches(func_name)) 857254721Semaste return false; 858254721Semaste } 859254721Semaste } 860254721Semaste 861254721Semaste 862254721Semaste } 863254721Semaste 864254721Semaste return true; 865254721Semaste} 866254721Semaste 867254721Semastebool 868254721SemasteSymbolContextSpecifier::AddressMatches(lldb::addr_t addr) 869254721Semaste{ 870254721Semaste if (m_type & eAddressRangeSpecified) 871254721Semaste { 872254721Semaste 873254721Semaste } 874254721Semaste else 875254721Semaste { 876254721Semaste Address match_address (addr, NULL); 877254721Semaste SymbolContext sc; 878254721Semaste m_target_sp->GetImages().ResolveSymbolContextForAddress(match_address, eSymbolContextEverything, sc); 879254721Semaste return SymbolContextMatches(sc); 880254721Semaste } 881254721Semaste return true; 882254721Semaste} 883254721Semaste 884254721Semastevoid 885254721SemasteSymbolContextSpecifier::GetDescription (Stream *s, lldb::DescriptionLevel level) const 886254721Semaste{ 887254721Semaste char path_str[PATH_MAX + 1]; 888254721Semaste 889254721Semaste if (m_type == eNothingSpecified) 890254721Semaste { 891254721Semaste s->Printf ("Nothing specified.\n"); 892254721Semaste } 893254721Semaste 894254721Semaste if (m_type == eModuleSpecified) 895254721Semaste { 896254721Semaste s->Indent(); 897254721Semaste if (m_module_sp) 898254721Semaste { 899254721Semaste m_module_sp->GetFileSpec().GetPath (path_str, PATH_MAX); 900254721Semaste s->Printf ("Module: %s\n", path_str); 901254721Semaste } 902254721Semaste else 903254721Semaste s->Printf ("Module: %s\n", m_module_spec.c_str()); 904254721Semaste } 905254721Semaste 906254721Semaste if (m_type == eFileSpecified && m_file_spec_ap.get() != NULL) 907254721Semaste { 908254721Semaste m_file_spec_ap->GetPath (path_str, PATH_MAX); 909254721Semaste s->Indent(); 910254721Semaste s->Printf ("File: %s", path_str); 911254721Semaste if (m_type == eLineStartSpecified) 912254721Semaste { 913263363Semaste s->Printf (" from line %zu", m_start_line); 914254721Semaste if (m_type == eLineEndSpecified) 915263363Semaste s->Printf ("to line %zu", m_end_line); 916254721Semaste else 917254721Semaste s->Printf ("to end"); 918254721Semaste } 919254721Semaste else if (m_type == eLineEndSpecified) 920254721Semaste { 921263363Semaste s->Printf (" from start to line %zu", m_end_line); 922254721Semaste } 923254721Semaste s->Printf (".\n"); 924254721Semaste } 925254721Semaste 926254721Semaste if (m_type == eLineStartSpecified) 927254721Semaste { 928254721Semaste s->Indent(); 929263363Semaste s->Printf ("From line %zu", m_start_line); 930254721Semaste if (m_type == eLineEndSpecified) 931263363Semaste s->Printf ("to line %zu", m_end_line); 932254721Semaste else 933254721Semaste s->Printf ("to end"); 934254721Semaste s->Printf (".\n"); 935254721Semaste } 936254721Semaste else if (m_type == eLineEndSpecified) 937254721Semaste { 938263363Semaste s->Printf ("From start to line %zu.\n", m_end_line); 939254721Semaste } 940254721Semaste 941254721Semaste if (m_type == eFunctionSpecified) 942254721Semaste { 943254721Semaste s->Indent(); 944254721Semaste s->Printf ("Function: %s.\n", m_function_spec.c_str()); 945254721Semaste } 946254721Semaste 947254721Semaste if (m_type == eClassOrNamespaceSpecified) 948254721Semaste { 949254721Semaste s->Indent(); 950254721Semaste s->Printf ("Class name: %s.\n", m_class_name.c_str()); 951254721Semaste } 952254721Semaste 953254721Semaste if (m_type == eAddressRangeSpecified && m_address_range_ap.get() != NULL) 954254721Semaste { 955254721Semaste s->Indent(); 956254721Semaste s->PutCString ("Address range: "); 957254721Semaste m_address_range_ap->Dump (s, m_target_sp.get(), Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress); 958254721Semaste s->PutCString ("\n"); 959254721Semaste } 960254721Semaste} 961254721Semaste 962254721Semaste//---------------------------------------------------------------------- 963254721Semaste// 964254721Semaste// SymbolContextList 965254721Semaste// 966254721Semaste//---------------------------------------------------------------------- 967254721Semaste 968254721Semaste 969254721SemasteSymbolContextList::SymbolContextList() : 970254721Semaste m_symbol_contexts() 971254721Semaste{ 972254721Semaste} 973254721Semaste 974254721SemasteSymbolContextList::~SymbolContextList() 975254721Semaste{ 976254721Semaste} 977254721Semaste 978254721Semastevoid 979254721SemasteSymbolContextList::Append(const SymbolContext& sc) 980254721Semaste{ 981254721Semaste m_symbol_contexts.push_back(sc); 982254721Semaste} 983254721Semaste 984254721Semastevoid 985254721SemasteSymbolContextList::Append (const SymbolContextList& sc_list) 986254721Semaste{ 987254721Semaste collection::const_iterator pos, end = sc_list.m_symbol_contexts.end(); 988254721Semaste for (pos = sc_list.m_symbol_contexts.begin(); pos != end; ++pos) 989254721Semaste m_symbol_contexts.push_back (*pos); 990254721Semaste} 991254721Semaste 992254721Semaste 993254721Semasteuint32_t 994254721SemasteSymbolContextList::AppendIfUnique (const SymbolContextList& sc_list, bool merge_symbol_into_function) 995254721Semaste{ 996254721Semaste uint32_t unique_sc_add_count = 0; 997254721Semaste collection::const_iterator pos, end = sc_list.m_symbol_contexts.end(); 998254721Semaste for (pos = sc_list.m_symbol_contexts.begin(); pos != end; ++pos) 999254721Semaste { 1000254721Semaste if (AppendIfUnique (*pos, merge_symbol_into_function)) 1001254721Semaste ++unique_sc_add_count; 1002254721Semaste } 1003254721Semaste return unique_sc_add_count; 1004254721Semaste} 1005254721Semaste 1006254721Semastebool 1007254721SemasteSymbolContextList::AppendIfUnique (const SymbolContext& sc, bool merge_symbol_into_function) 1008254721Semaste{ 1009254721Semaste collection::iterator pos, end = m_symbol_contexts.end(); 1010254721Semaste for (pos = m_symbol_contexts.begin(); pos != end; ++pos) 1011254721Semaste { 1012254721Semaste if (*pos == sc) 1013254721Semaste return false; 1014254721Semaste } 1015254721Semaste if (merge_symbol_into_function 1016254721Semaste && sc.symbol != NULL 1017254721Semaste && sc.comp_unit == NULL 1018254721Semaste && sc.function == NULL 1019254721Semaste && sc.block == NULL 1020254721Semaste && sc.line_entry.IsValid() == false) 1021254721Semaste { 1022254721Semaste if (sc.symbol->ValueIsAddress()) 1023254721Semaste { 1024254721Semaste for (pos = m_symbol_contexts.begin(); pos != end; ++pos) 1025254721Semaste { 1026254721Semaste // Don't merge symbols into inlined function symbol contexts 1027254721Semaste if (pos->block && pos->block->GetContainingInlinedBlock()) 1028254721Semaste continue; 1029254721Semaste 1030254721Semaste if (pos->function) 1031254721Semaste { 1032254721Semaste if (pos->function->GetAddressRange().GetBaseAddress() == sc.symbol->GetAddress()) 1033254721Semaste { 1034254721Semaste // Do we already have a function with this symbol? 1035254721Semaste if (pos->symbol == sc.symbol) 1036254721Semaste return false; 1037254721Semaste if (pos->symbol == NULL) 1038254721Semaste { 1039254721Semaste pos->symbol = sc.symbol; 1040254721Semaste return false; 1041254721Semaste } 1042254721Semaste } 1043254721Semaste } 1044254721Semaste } 1045254721Semaste } 1046254721Semaste } 1047254721Semaste m_symbol_contexts.push_back(sc); 1048254721Semaste return true; 1049254721Semaste} 1050254721Semaste 1051254721Semastebool 1052254721SemasteSymbolContextList::MergeSymbolContextIntoFunctionContext (const SymbolContext& symbol_sc, 1053254721Semaste uint32_t start_idx, 1054254721Semaste uint32_t stop_idx) 1055254721Semaste{ 1056254721Semaste if (symbol_sc.symbol != NULL 1057254721Semaste && symbol_sc.comp_unit == NULL 1058254721Semaste && symbol_sc.function == NULL 1059254721Semaste && symbol_sc.block == NULL 1060254721Semaste && symbol_sc.line_entry.IsValid() == false) 1061254721Semaste { 1062254721Semaste if (symbol_sc.symbol->ValueIsAddress()) 1063254721Semaste { 1064254721Semaste const size_t end = std::min<size_t>(m_symbol_contexts.size(), stop_idx); 1065254721Semaste for (size_t i=start_idx; i<end; ++i) 1066254721Semaste { 1067254721Semaste const SymbolContext &function_sc = m_symbol_contexts[i]; 1068254721Semaste // Don't merge symbols into inlined function symbol contexts 1069254721Semaste if (function_sc.block && function_sc.block->GetContainingInlinedBlock()) 1070254721Semaste continue; 1071254721Semaste 1072254721Semaste if (function_sc.function) 1073254721Semaste { 1074254721Semaste if (function_sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddress()) 1075254721Semaste { 1076254721Semaste // Do we already have a function with this symbol? 1077254721Semaste if (function_sc.symbol == symbol_sc.symbol) 1078254721Semaste return true; // Already have a symbol context with this symbol, return true 1079254721Semaste 1080254721Semaste if (function_sc.symbol == NULL) 1081254721Semaste { 1082254721Semaste // We successfully merged this symbol into an existing symbol context 1083254721Semaste m_symbol_contexts[i].symbol = symbol_sc.symbol; 1084254721Semaste return true; 1085254721Semaste } 1086254721Semaste } 1087254721Semaste } 1088254721Semaste } 1089254721Semaste } 1090254721Semaste } 1091254721Semaste return false; 1092254721Semaste} 1093254721Semaste 1094254721Semastevoid 1095254721SemasteSymbolContextList::Clear() 1096254721Semaste{ 1097254721Semaste m_symbol_contexts.clear(); 1098254721Semaste} 1099254721Semaste 1100254721Semastevoid 1101254721SemasteSymbolContextList::Dump(Stream *s, Target *target) const 1102254721Semaste{ 1103254721Semaste 1104254721Semaste *s << (void *)this << ": "; 1105254721Semaste s->Indent(); 1106254721Semaste s->PutCString("SymbolContextList"); 1107254721Semaste s->EOL(); 1108254721Semaste s->IndentMore(); 1109254721Semaste 1110254721Semaste collection::const_iterator pos, end = m_symbol_contexts.end(); 1111254721Semaste for (pos = m_symbol_contexts.begin(); pos != end; ++pos) 1112254721Semaste { 1113254721Semaste //pos->Dump(s, target); 1114254721Semaste pos->GetDescription(s, eDescriptionLevelVerbose, target); 1115254721Semaste } 1116254721Semaste s->IndentLess(); 1117254721Semaste} 1118254721Semaste 1119254721Semastebool 1120254721SemasteSymbolContextList::GetContextAtIndex(size_t idx, SymbolContext& sc) const 1121254721Semaste{ 1122254721Semaste if (idx < m_symbol_contexts.size()) 1123254721Semaste { 1124254721Semaste sc = m_symbol_contexts[idx]; 1125254721Semaste return true; 1126254721Semaste } 1127254721Semaste return false; 1128254721Semaste} 1129254721Semaste 1130254721Semastebool 1131254721SemasteSymbolContextList::GetLastContext(SymbolContext& sc) const 1132254721Semaste{ 1133254721Semaste if (!m_symbol_contexts.empty()) 1134254721Semaste { 1135254721Semaste sc = m_symbol_contexts.back(); 1136254721Semaste return true; 1137254721Semaste } 1138254721Semaste return false; 1139254721Semaste} 1140254721Semaste 1141254721Semastebool 1142254721SemasteSymbolContextList::RemoveContextAtIndex (size_t idx) 1143254721Semaste{ 1144254721Semaste if (idx < m_symbol_contexts.size()) 1145254721Semaste { 1146254721Semaste m_symbol_contexts.erase(m_symbol_contexts.begin() + idx); 1147254721Semaste return true; 1148254721Semaste } 1149254721Semaste return false; 1150254721Semaste} 1151254721Semaste 1152254721Semasteuint32_t 1153254721SemasteSymbolContextList::GetSize() const 1154254721Semaste{ 1155254721Semaste return m_symbol_contexts.size(); 1156254721Semaste} 1157254721Semaste 1158254721Semasteuint32_t 1159254721SemasteSymbolContextList::NumLineEntriesWithLine (uint32_t line) const 1160254721Semaste{ 1161254721Semaste uint32_t match_count = 0; 1162254721Semaste const size_t size = m_symbol_contexts.size(); 1163254721Semaste for (size_t idx = 0; idx<size; ++idx) 1164254721Semaste { 1165254721Semaste if (m_symbol_contexts[idx].line_entry.line == line) 1166254721Semaste ++match_count; 1167254721Semaste } 1168254721Semaste return match_count; 1169254721Semaste} 1170254721Semaste 1171254721Semastevoid 1172254721SemasteSymbolContextList::GetDescription(Stream *s, 1173254721Semaste lldb::DescriptionLevel level, 1174254721Semaste Target *target) const 1175254721Semaste{ 1176254721Semaste const size_t size = m_symbol_contexts.size(); 1177254721Semaste for (size_t idx = 0; idx<size; ++idx) 1178254721Semaste m_symbol_contexts[idx].GetDescription (s, level, target); 1179254721Semaste} 1180254721Semaste 1181254721Semastebool 1182254721Semastelldb_private::operator== (const SymbolContextList& lhs, const SymbolContextList& rhs) 1183254721Semaste{ 1184254721Semaste const uint32_t size = lhs.GetSize(); 1185254721Semaste if (size != rhs.GetSize()) 1186254721Semaste return false; 1187254721Semaste 1188254721Semaste SymbolContext lhs_sc; 1189254721Semaste SymbolContext rhs_sc; 1190254721Semaste for (uint32_t i=0; i<size; ++i) 1191254721Semaste { 1192254721Semaste lhs.GetContextAtIndex(i, lhs_sc); 1193254721Semaste rhs.GetContextAtIndex(i, rhs_sc); 1194254721Semaste if (lhs_sc != rhs_sc) 1195254721Semaste return false; 1196254721Semaste } 1197254721Semaste return true; 1198254721Semaste} 1199254721Semaste 1200254721Semastebool 1201254721Semastelldb_private::operator!= (const SymbolContextList& lhs, const SymbolContextList& rhs) 1202254721Semaste{ 1203254721Semaste return !(lhs == rhs); 1204254721Semaste} 1205254721Semaste 1206