SymbolContext.cpp revision 256281
1130803Smarcel//===-- SymbolContext.cpp ---------------------------------------*- C++ -*-===// 2130803Smarcel// 3130803Smarcel// The LLVM Compiler Infrastructure 4130803Smarcel// 5130803Smarcel// This file is distributed under the University of Illinois Open Source 6130803Smarcel// License. See LICENSE.TXT for details. 7130803Smarcel// 8130803Smarcel//===----------------------------------------------------------------------===// 9130803Smarcel 10130803Smarcel#include "lldb/Symbol/SymbolContext.h" 11130803Smarcel 12130803Smarcel#include "lldb/Core/Log.h" 13130803Smarcel#include "lldb/Core/Module.h" 14130803Smarcel#include "lldb/Core/ModuleSpec.h" 15130803Smarcel#include "lldb/Host/Host.h" 16130803Smarcel#include "lldb/Interpreter/Args.h" 17130803Smarcel#include "lldb/Symbol/Block.h" 18130803Smarcel#include "lldb/Symbol/ClangASTContext.h" 19130803Smarcel#include "lldb/Symbol/CompileUnit.h" 20130803Smarcel#include "lldb/Symbol/ObjectFile.h" 21130803Smarcel#include "lldb/Symbol/Symbol.h" 22130803Smarcel#include "lldb/Symbol/SymbolFile.h" 23130803Smarcel#include "lldb/Symbol/SymbolVendor.h" 24130803Smarcel#include "lldb/Target/Target.h" 25130803Smarcel 26130803Smarcelusing namespace lldb; 27130803Smarcelusing namespace lldb_private; 28130803Smarcel 29130803SmarcelSymbolContext::SymbolContext() : 30130803Smarcel target_sp (), 31130803Smarcel module_sp (), 32130803Smarcel comp_unit (NULL), 33130803Smarcel function (NULL), 34130803Smarcel block (NULL), 35130803Smarcel line_entry (), 36130803Smarcel symbol (NULL) 37130803Smarcel{ 38130803Smarcel} 39130803Smarcel 40130803SmarcelSymbolContext::SymbolContext(const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) : 41130803Smarcel target_sp (), 42130803Smarcel module_sp (m), 43130803Smarcel comp_unit (cu), 44130803Smarcel function (f), 45130803Smarcel block (b), 46130803Smarcel line_entry (), 47130803Smarcel symbol (s) 48130803Smarcel{ 49130803Smarcel if (le) 50130803Smarcel line_entry = *le; 51130803Smarcel} 52130803Smarcel 53130803SmarcelSymbolContext::SymbolContext(const TargetSP &t, const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) : 54130803Smarcel target_sp (t), 55130803Smarcel module_sp (m), 56130803Smarcel comp_unit (cu), 57130803Smarcel function (f), 58130803Smarcel block (b), 59130803Smarcel line_entry (), 60130803Smarcel symbol (s) 61130803Smarcel{ 62130803Smarcel if (le) 63130803Smarcel line_entry = *le; 64130803Smarcel} 65130803Smarcel 66130803SmarcelSymbolContext::SymbolContext(const SymbolContext& rhs) : 67130803Smarcel target_sp (rhs.target_sp), 68130803Smarcel module_sp (rhs.module_sp), 69130803Smarcel comp_unit (rhs.comp_unit), 70130803Smarcel function (rhs.function), 71130803Smarcel block (rhs.block), 72130803Smarcel line_entry (rhs.line_entry), 73130803Smarcel symbol (rhs.symbol) 74130803Smarcel{ 75130803Smarcel} 76130803Smarcel 77130803Smarcel 78130803SmarcelSymbolContext::SymbolContext (SymbolContextScope *sc_scope) : 79130803Smarcel target_sp (), 80130803Smarcel module_sp (), 81130803Smarcel comp_unit (NULL), 82130803Smarcel function (NULL), 83130803Smarcel block (NULL), 84130803Smarcel line_entry (), 85130803Smarcel symbol (NULL) 86130803Smarcel{ 87130803Smarcel sc_scope->CalculateSymbolContext (this); 88130803Smarcel} 89130803Smarcel 90130803SmarcelSymbolContext::~SymbolContext () 91130803Smarcel{ 92130803Smarcel} 93130803Smarcel 94130803Smarcelconst SymbolContext& 95130803SmarcelSymbolContext::operator= (const SymbolContext& rhs) 96130803Smarcel{ 97130803Smarcel if (this != &rhs) 98130803Smarcel { 99130803Smarcel target_sp = rhs.target_sp; 100130803Smarcel module_sp = rhs.module_sp; 101130803Smarcel comp_unit = rhs.comp_unit; 102130803Smarcel function = rhs.function; 103130803Smarcel block = rhs.block; 104130803Smarcel line_entry = rhs.line_entry; 105130803Smarcel symbol = rhs.symbol; 106130803Smarcel } 107130803Smarcel return *this; 108130803Smarcel} 109130803Smarcel 110130803Smarcelvoid 111130803SmarcelSymbolContext::Clear(bool clear_target) 112130803Smarcel{ 113130803Smarcel if (clear_target) 114130803Smarcel target_sp.reset(); 115130803Smarcel module_sp.reset(); 116130803Smarcel comp_unit = NULL; 117130803Smarcel function = NULL; 118130803Smarcel block = NULL; 119130803Smarcel line_entry.Clear(); 120130803Smarcel symbol = NULL; 121130803Smarcel} 122130803Smarcel 123130803Smarcelbool 124130803SmarcelSymbolContext::DumpStopContext 125130803Smarcel( 126130803Smarcel Stream *s, 127130803Smarcel ExecutionContextScope *exe_scope, 128130803Smarcel const Address &addr, 129130803Smarcel bool show_fullpaths, 130130803Smarcel bool show_module, 131130803Smarcel bool show_inlined_frames 132130803Smarcel) const 133130803Smarcel{ 134130803Smarcel bool dumped_something = false; 135130803Smarcel if (show_module && module_sp) 136130803Smarcel { 137130803Smarcel if (show_fullpaths) 138130803Smarcel *s << module_sp->GetFileSpec(); 139130803Smarcel else 140130803Smarcel *s << module_sp->GetFileSpec().GetFilename(); 141130803Smarcel s->PutChar('`'); 142130803Smarcel dumped_something = true; 143130803Smarcel } 144130803Smarcel 145130803Smarcel if (function != NULL) 146130803Smarcel { 147130803Smarcel SymbolContext inline_parent_sc; 148130803Smarcel Address inline_parent_addr; 149130803Smarcel if (function->GetMangled().GetName()) 150130803Smarcel { 151130803Smarcel dumped_something = true; 152130803Smarcel function->GetMangled().GetName().Dump(s); 153130803Smarcel } 154130803Smarcel 155130803Smarcel if (addr.IsValid()) 156130803Smarcel { 157130803Smarcel const addr_t function_offset = addr.GetOffset() - function->GetAddressRange().GetBaseAddress().GetOffset(); 158130803Smarcel if (function_offset) 159130803Smarcel { 160130803Smarcel dumped_something = true; 161130803Smarcel s->Printf(" + %" PRIu64, function_offset); 162130803Smarcel } 163130803Smarcel } 164130803Smarcel 165130803Smarcel if (GetParentOfInlinedScope (addr, inline_parent_sc, inline_parent_addr)) 166130803Smarcel { 167130803Smarcel dumped_something = true; 168130803Smarcel Block *inlined_block = block->GetContainingInlinedBlock(); 169130803Smarcel const InlineFunctionInfo* inlined_block_info = inlined_block->GetInlinedFunctionInfo(); 170130803Smarcel s->Printf (" [inlined] %s", inlined_block_info->GetName().GetCString()); 171130803Smarcel 172130803Smarcel lldb_private::AddressRange block_range; 173130803Smarcel if (inlined_block->GetRangeContainingAddress(addr, block_range)) 174130803Smarcel { 175130803Smarcel const addr_t inlined_function_offset = addr.GetOffset() - block_range.GetBaseAddress().GetOffset(); 176130803Smarcel if (inlined_function_offset) 177130803Smarcel { 178130803Smarcel s->Printf(" + %" PRIu64, inlined_function_offset); 179130803Smarcel } 180130803Smarcel } 181130803Smarcel const Declaration &call_site = inlined_block_info->GetCallSite(); 182130803Smarcel if (call_site.IsValid()) 183130803Smarcel { 184130803Smarcel s->PutCString(" at "); 185130803Smarcel call_site.DumpStopContext (s, show_fullpaths); 186130803Smarcel } 187130803Smarcel if (show_inlined_frames) 188130803Smarcel { 189130803Smarcel s->EOL(); 190130803Smarcel s->Indent(); 191130803Smarcel return inline_parent_sc.DumpStopContext (s, exe_scope, inline_parent_addr, show_fullpaths, show_module, show_inlined_frames); 192130803Smarcel } 193130803Smarcel } 194130803Smarcel else 195130803Smarcel { 196130803Smarcel if (line_entry.IsValid()) 197130803Smarcel { 198130803Smarcel dumped_something = true; 199130803Smarcel s->PutCString(" at "); 200130803Smarcel if (line_entry.DumpStopContext(s, show_fullpaths)) 201130803Smarcel dumped_something = true; 202130803Smarcel } 203130803Smarcel } 204130803Smarcel } 205130803Smarcel else if (symbol != NULL) 206130803Smarcel { 207130803Smarcel if (symbol->GetMangled().GetName()) 208130803Smarcel { 209130803Smarcel dumped_something = true; 210130803Smarcel if (symbol->GetType() == eSymbolTypeTrampoline) 211130803Smarcel s->PutCString("symbol stub for: "); 212130803Smarcel symbol->GetMangled().GetName().Dump(s); 213130803Smarcel } 214130803Smarcel 215130803Smarcel if (addr.IsValid() && symbol->ValueIsAddress()) 216130803Smarcel { 217130803Smarcel const addr_t symbol_offset = addr.GetOffset() - symbol->GetAddress().GetOffset(); 218130803Smarcel if (symbol_offset) 219130803Smarcel { 220130803Smarcel dumped_something = true; 221130803Smarcel s->Printf(" + %" PRIu64, symbol_offset); 222130803Smarcel } 223130803Smarcel } 224130803Smarcel } 225130803Smarcel else if (addr.IsValid()) 226130803Smarcel { 227130803Smarcel addr.Dump(s, exe_scope, Address::DumpStyleModuleWithFileAddress); 228130803Smarcel dumped_something = true; 229130803Smarcel } 230130803Smarcel return dumped_something; 231130803Smarcel} 232130803Smarcel 233130803Smarcelvoid 234130803SmarcelSymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target) const 235130803Smarcel{ 236130803Smarcel if (module_sp) 237130803Smarcel { 238130803Smarcel s->Indent(" Module: file = \""); 239130803Smarcel module_sp->GetFileSpec().Dump(s); 240130803Smarcel *s << '"'; 241130803Smarcel if (module_sp->GetArchitecture().IsValid()) 242130803Smarcel s->Printf (", arch = \"%s\"", module_sp->GetArchitecture().GetArchitectureName()); 243130803Smarcel s->EOL(); 244130803Smarcel } 245130803Smarcel 246130803Smarcel if (comp_unit != NULL) 247130803Smarcel { 248130803Smarcel s->Indent("CompileUnit: "); 249130803Smarcel comp_unit->GetDescription (s, level); 250130803Smarcel s->EOL(); 251130803Smarcel } 252130803Smarcel 253130803Smarcel if (function != NULL) 254130803Smarcel { 255130803Smarcel s->Indent(" Function: "); 256130803Smarcel function->GetDescription (s, level, target); 257130803Smarcel s->EOL(); 258130803Smarcel 259130803Smarcel Type *func_type = function->GetType(); 260130803Smarcel if (func_type) 261130803Smarcel { 262130803Smarcel s->Indent(" FuncType: "); 263130803Smarcel func_type->GetDescription (s, level, false); 264130803Smarcel s->EOL(); 265130803Smarcel } 266130803Smarcel } 267130803Smarcel 268130803Smarcel if (block != NULL) 269130803Smarcel { 270130803Smarcel std::vector<Block *> blocks; 271130803Smarcel blocks.push_back (block); 272130803Smarcel Block *parent_block = block->GetParent(); 273130803Smarcel 274130803Smarcel while (parent_block) 275130803Smarcel { 276130803Smarcel blocks.push_back (parent_block); 277130803Smarcel parent_block = parent_block->GetParent(); 278130803Smarcel } 279130803Smarcel std::vector<Block *>::reverse_iterator pos; 280130803Smarcel std::vector<Block *>::reverse_iterator begin = blocks.rbegin(); 281130803Smarcel std::vector<Block *>::reverse_iterator end = blocks.rend(); 282130803Smarcel for (pos = begin; pos != end; ++pos) 283130803Smarcel { 284130803Smarcel if (pos == begin) 285130803Smarcel s->Indent(" Blocks: "); 286130803Smarcel else 287130803Smarcel s->Indent(" "); 288130803Smarcel (*pos)->GetDescription(s, function, level, target); 289130803Smarcel s->EOL(); 290130803Smarcel } 291130803Smarcel } 292130803Smarcel 293130803Smarcel if (line_entry.IsValid()) 294130803Smarcel { 295130803Smarcel s->Indent(" LineEntry: "); 296130803Smarcel line_entry.GetDescription (s, level, comp_unit, target, false); 297130803Smarcel s->EOL(); 298130803Smarcel } 299130803Smarcel 300130803Smarcel if (symbol != NULL) 301130803Smarcel { 302130803Smarcel s->Indent(" Symbol: "); 303130803Smarcel symbol->GetDescription(s, level, target); 304130803Smarcel s->EOL(); 305130803Smarcel } 306130803Smarcel} 307130803Smarcel 308130803Smarceluint32_t 309130803SmarcelSymbolContext::GetResolvedMask () const 310130803Smarcel{ 311130803Smarcel uint32_t resolved_mask = 0; 312130803Smarcel if (target_sp) resolved_mask |= eSymbolContextTarget; 313130803Smarcel if (module_sp) resolved_mask |= eSymbolContextModule; 314130803Smarcel if (comp_unit) resolved_mask |= eSymbolContextCompUnit; 315130803Smarcel if (function) resolved_mask |= eSymbolContextFunction; 316130803Smarcel if (block) resolved_mask |= eSymbolContextBlock; 317130803Smarcel if (line_entry.IsValid()) resolved_mask |= eSymbolContextLineEntry; 318130803Smarcel if (symbol) resolved_mask |= eSymbolContextSymbol; 319130803Smarcel return resolved_mask; 320130803Smarcel} 321130803Smarcel 322130803Smarcelvoid 323130803SmarcelSymbolContext::Dump(Stream *s, Target *target) const 324130803Smarcel{ 325130803Smarcel *s << (void *)this << ": "; 326130803Smarcel s->Indent(); 327130803Smarcel s->PutCString("SymbolContext"); 328130803Smarcel s->IndentMore(); 329130803Smarcel s->EOL(); 330130803Smarcel s->IndentMore(); 331130803Smarcel s->Indent(); 332130803Smarcel *s << "Module = " << (void *)module_sp.get() << ' '; 333130803Smarcel if (module_sp) 334130803Smarcel module_sp->GetFileSpec().Dump(s); 335130803Smarcel s->EOL(); 336130803Smarcel s->Indent(); 337130803Smarcel *s << "CompileUnit = " << (void *)comp_unit; 338130803Smarcel if (comp_unit != NULL) 339130803Smarcel *s << " {0x" << comp_unit->GetID() << "} " << *(static_cast<FileSpec*> (comp_unit)); 340130803Smarcel s->EOL(); 341130803Smarcel s->Indent(); 342130803Smarcel *s << "Function = " << (void *)function; 343130803Smarcel if (function != NULL) 344130803Smarcel { 345130803Smarcel *s << " {0x" << function->GetID() << "} " << function->GetType()->GetName() << ", address-range = "; 346130803Smarcel function->GetAddressRange().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress); 347130803Smarcel s->EOL(); 348130803Smarcel s->Indent(); 349130803Smarcel Type* func_type = function->GetType(); 350130803Smarcel if (func_type) 351130803Smarcel { 352130803Smarcel *s << " Type = "; 353130803Smarcel func_type->Dump (s, false); 354130803Smarcel } 355130803Smarcel } 356130803Smarcel s->EOL(); 357130803Smarcel s->Indent(); 358130803Smarcel *s << "Block = " << (void *)block; 359130803Smarcel if (block != NULL) 360130803Smarcel *s << " {0x" << block->GetID() << '}'; 361130803Smarcel // Dump the block and pass it a negative depth to we print all the parent blocks 362130803Smarcel //if (block != NULL) 363130803Smarcel // block->Dump(s, function->GetFileAddress(), INT_MIN); 364130803Smarcel s->EOL(); 365130803Smarcel s->Indent(); 366130803Smarcel *s << "LineEntry = "; 367130803Smarcel line_entry.Dump (s, target, true, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, true); 368130803Smarcel s->EOL(); 369130803Smarcel s->Indent(); 370130803Smarcel *s << "Symbol = " << (void *)symbol; 371130803Smarcel if (symbol != NULL && symbol->GetMangled()) 372130803Smarcel *s << ' ' << symbol->GetMangled().GetName().AsCString(); 373130803Smarcel s->EOL(); 374130803Smarcel s->IndentLess(); 375130803Smarcel s->IndentLess(); 376130803Smarcel} 377130803Smarcel 378130803Smarcelbool 379130803Smarcellldb_private::operator== (const SymbolContext& lhs, const SymbolContext& rhs) 380130803Smarcel{ 381130803Smarcel return lhs.function == rhs.function 382130803Smarcel && lhs.symbol == rhs.symbol 383130803Smarcel && lhs.module_sp.get() == rhs.module_sp.get() 384130803Smarcel && lhs.comp_unit == rhs.comp_unit 385130803Smarcel && lhs.target_sp.get() == rhs.target_sp.get() 386130803Smarcel && LineEntry::Compare(lhs.line_entry, rhs.line_entry) == 0; 387130803Smarcel} 388130803Smarcel 389130803Smarcelbool 390130803Smarcellldb_private::operator!= (const SymbolContext& lhs, const SymbolContext& rhs) 391130803Smarcel{ 392130803Smarcel return lhs.function != rhs.function 393130803Smarcel || lhs.symbol != rhs.symbol 394130803Smarcel || lhs.module_sp.get() != rhs.module_sp.get() 395130803Smarcel || lhs.comp_unit != rhs.comp_unit 396130803Smarcel || lhs.target_sp.get() != rhs.target_sp.get() 397130803Smarcel || LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0; 398130803Smarcel} 399130803Smarcel 400130803Smarcelbool 401130803SmarcelSymbolContext::GetAddressRange (uint32_t scope, 402130803Smarcel uint32_t range_idx, 403130803Smarcel bool use_inline_block_range, 404130803Smarcel AddressRange &range) const 405130803Smarcel{ 406130803Smarcel if ((scope & eSymbolContextLineEntry) && line_entry.IsValid()) 407130803Smarcel { 408130803Smarcel range = line_entry.range; 409130803Smarcel return true; 410130803Smarcel } 411130803Smarcel 412130803Smarcel if ((scope & eSymbolContextBlock) && (block != NULL)) 413130803Smarcel { 414130803Smarcel if (use_inline_block_range) 415130803Smarcel { 416130803Smarcel Block *inline_block = block->GetContainingInlinedBlock(); 417130803Smarcel if (inline_block) 418130803Smarcel return inline_block->GetRangeAtIndex (range_idx, range); 419130803Smarcel } 420130803Smarcel else 421130803Smarcel { 422130803Smarcel return block->GetRangeAtIndex (range_idx, range); 423130803Smarcel } 424130803Smarcel } 425130803Smarcel 426130803Smarcel if ((scope & eSymbolContextFunction) && (function != NULL)) 427130803Smarcel { 428130803Smarcel if (range_idx == 0) 429130803Smarcel { 430130803Smarcel range = function->GetAddressRange(); 431130803Smarcel return true; 432130803Smarcel } 433130803Smarcel } 434130803Smarcel 435130803Smarcel if ((scope & eSymbolContextSymbol) && (symbol != NULL)) 436130803Smarcel { 437130803Smarcel if (range_idx == 0) 438130803Smarcel { 439130803Smarcel if (symbol->ValueIsAddress()) 440130803Smarcel { 441130803Smarcel range.GetBaseAddress() = symbol->GetAddress(); 442130803Smarcel range.SetByteSize (symbol->GetByteSize()); 443130803Smarcel return true; 444130803Smarcel } 445130803Smarcel } 446130803Smarcel } 447130803Smarcel range.Clear(); 448130803Smarcel return false; 449130803Smarcel} 450130803Smarcel 451130803Smarcelbool 452130803SmarcelSymbolContext::GetParentOfInlinedScope (const Address &curr_frame_pc, 453130803Smarcel SymbolContext &next_frame_sc, 454130803Smarcel Address &next_frame_pc) const 455130803Smarcel{ 456130803Smarcel next_frame_sc.Clear(false); 457130803Smarcel next_frame_pc.Clear(); 458130803Smarcel 459130803Smarcel if (block) 460130803Smarcel { 461130803Smarcel //const addr_t curr_frame_file_addr = curr_frame_pc.GetFileAddress(); 462130803Smarcel 463130803Smarcel // In order to get the parent of an inlined function we first need to 464130803Smarcel // see if we are in an inlined block as "this->block" could be an 465130803Smarcel // inlined block, or a parent of "block" could be. So lets check if 466130803Smarcel // this block or one of this blocks parents is an inlined function. 467130803Smarcel Block *curr_inlined_block = block->GetContainingInlinedBlock(); 468130803Smarcel if (curr_inlined_block) 469130803Smarcel { 470130803Smarcel // "this->block" is contained in an inline function block, so to 471130803Smarcel // get the scope above the inlined block, we get the parent of the 472130803Smarcel // inlined block itself 473130803Smarcel Block *next_frame_block = curr_inlined_block->GetParent(); 474130803Smarcel // Now calculate the symbol context of the containing block 475130803Smarcel next_frame_block->CalculateSymbolContext (&next_frame_sc); 476130803Smarcel 477130803Smarcel // If we get here we weren't able to find the return line entry using the nesting of the blocks and 478130803Smarcel // the line table. So just use the call site info from our inlined block. 479130803Smarcel 480130803Smarcel AddressRange range; 481130803Smarcel if (curr_inlined_block->GetRangeContainingAddress (curr_frame_pc, range)) 482130803Smarcel { 483130803Smarcel // To see there this new frame block it, we need to look at the 484130803Smarcel // call site information from 485130803Smarcel const InlineFunctionInfo* curr_inlined_block_inlined_info = curr_inlined_block->GetInlinedFunctionInfo(); 486130803Smarcel next_frame_pc = range.GetBaseAddress(); 487130803Smarcel next_frame_sc.line_entry.range.GetBaseAddress() = next_frame_pc; 488130803Smarcel next_frame_sc.line_entry.file = curr_inlined_block_inlined_info->GetCallSite().GetFile(); 489130803Smarcel next_frame_sc.line_entry.line = curr_inlined_block_inlined_info->GetCallSite().GetLine(); 490130803Smarcel next_frame_sc.line_entry.column = curr_inlined_block_inlined_info->GetCallSite().GetColumn(); 491130803Smarcel return true; 492130803Smarcel } 493130803Smarcel else 494130803Smarcel { 495130803Smarcel Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS)); 496130803Smarcel 497130803Smarcel if (log) 498130803Smarcel { 499130803Smarcel log->Printf ("warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64, 500130803Smarcel curr_inlined_block->GetID(), curr_frame_pc.GetFileAddress()); 501130803Smarcel } 502130803Smarcel#ifdef LLDB_CONFIGURATION_DEBUG 503130803Smarcel else 504130803Smarcel { 505130803Smarcel ObjectFile *objfile = NULL; 506130803Smarcel if (module_sp) 507130803Smarcel { 508130803Smarcel SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(); 509130803Smarcel if (symbol_vendor) 510130803Smarcel { 511130803Smarcel SymbolFile *symbol_file = symbol_vendor->GetSymbolFile(); 512130803Smarcel if (symbol_file) 513130803Smarcel objfile = symbol_file->GetObjectFile(); 514130803Smarcel } 515130803Smarcel } 516130803Smarcel if (objfile) 517130803Smarcel { 518130803Smarcel Host::SystemLog (Host::eSystemLogWarning, 519130803Smarcel "warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64 " in %s\n", 520130803Smarcel curr_inlined_block->GetID(), 521130803Smarcel curr_frame_pc.GetFileAddress(), 522130803Smarcel objfile->GetFileSpec().GetPath().c_str()); 523130803Smarcel } 524130803Smarcel else 525130803Smarcel { 526130803Smarcel Host::SystemLog (Host::eSystemLogWarning, 527130803Smarcel "warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64 "\n", 528130803Smarcel curr_inlined_block->GetID(), 529130803Smarcel curr_frame_pc.GetFileAddress()); 530130803Smarcel } 531130803Smarcel } 532130803Smarcel#endif 533130803Smarcel } 534130803Smarcel } 535130803Smarcel } 536130803Smarcel 537130803Smarcel return false; 538130803Smarcel} 539130803Smarcel 540130803SmarcelBlock * 541130803SmarcelSymbolContext::GetFunctionBlock () 542130803Smarcel{ 543130803Smarcel if (function) 544130803Smarcel { 545130803Smarcel if (block) 546130803Smarcel { 547130803Smarcel // If this symbol context has a block, check to see if this block 548130803Smarcel // is itself, or is contained within a block with inlined function 549130803Smarcel // information. If so, then the inlined block is the block that 550130803Smarcel // defines the function. 551130803Smarcel Block *inlined_block = block->GetContainingInlinedBlock(); 552130803Smarcel if (inlined_block) 553130803Smarcel return inlined_block; 554130803Smarcel 555130803Smarcel // The block in this symbol context is not inside an inlined 556130803Smarcel // block, so the block that defines the function is the function's 557130803Smarcel // top level block, which is returned below. 558130803Smarcel } 559130803Smarcel 560130803Smarcel // There is no block information in this symbol context, so we must 561130803Smarcel // assume that the block that is desired is the top level block of 562130803Smarcel // the function itself. 563130803Smarcel return &function->GetBlock(true); 564130803Smarcel } 565130803Smarcel return NULL; 566130803Smarcel} 567130803Smarcel 568130803Smarcelbool 569130803SmarcelSymbolContext::GetFunctionMethodInfo (lldb::LanguageType &language, 570130803Smarcel bool &is_instance_method, 571130803Smarcel ConstString &language_object_name) 572130803Smarcel 573130803Smarcel 574130803Smarcel{ 575130803Smarcel Block *function_block = GetFunctionBlock (); 576130803Smarcel if (function_block) 577130803Smarcel { 578130803Smarcel clang::DeclContext *decl_context = function_block->GetClangDeclContext(); 579130803Smarcel 580130803Smarcel if (decl_context) 581130803Smarcel { 582130803Smarcel return ClangASTContext::GetClassMethodInfoForDeclContext (decl_context, 583130803Smarcel language, 584130803Smarcel is_instance_method, 585130803Smarcel language_object_name); 586130803Smarcel } 587130803Smarcel } 588130803Smarcel language = eLanguageTypeUnknown; 589130803Smarcel is_instance_method = false; 590130803Smarcel language_object_name.Clear(); 591130803Smarcel return false; 592130803Smarcel} 593130803Smarcel 594130803SmarcelConstString 595130803SmarcelSymbolContext::GetFunctionName (Mangled::NamePreference preference) const 596130803Smarcel{ 597130803Smarcel if (function) 598130803Smarcel { 599130803Smarcel if (block) 600130803Smarcel { 601130803Smarcel Block *inlined_block = block->GetContainingInlinedBlock(); 602130803Smarcel 603130803Smarcel if (inlined_block) 604130803Smarcel { 605130803Smarcel const InlineFunctionInfo *inline_info = inlined_block->GetInlinedFunctionInfo(); 606130803Smarcel if (inline_info) 607130803Smarcel return inline_info->GetName(); 608130803Smarcel } 609130803Smarcel } 610130803Smarcel return function->GetMangled().GetName(preference); 611130803Smarcel } 612130803Smarcel else if (symbol && symbol->ValueIsAddress()) 613130803Smarcel { 614130803Smarcel return symbol->GetMangled().GetName(preference); 615130803Smarcel } 616130803Smarcel else 617130803Smarcel { 618130803Smarcel // No function, return an empty string. 619130803Smarcel return ConstString(); 620130803Smarcel } 621130803Smarcel} 622130803Smarcel 623130803SmarcelLineEntry 624130803SmarcelSymbolContext::GetFunctionStartLineEntry () const 625130803Smarcel{ 626130803Smarcel LineEntry line_entry; 627130803Smarcel Address start_addr; 628130803Smarcel if (block) 629130803Smarcel { 630130803Smarcel Block *inlined_block = block->GetContainingInlinedBlock(); 631130803Smarcel if (inlined_block) 632130803Smarcel { 633130803Smarcel if (inlined_block->GetStartAddress (start_addr)) 634130803Smarcel { 635130803Smarcel if (start_addr.CalculateSymbolContextLineEntry (line_entry)) 636130803Smarcel return line_entry; 637130803Smarcel } 638130803Smarcel return LineEntry(); 639130803Smarcel } 640130803Smarcel } 641130803Smarcel 642130803Smarcel if (function) 643130803Smarcel { 644130803Smarcel if (function->GetAddressRange().GetBaseAddress().CalculateSymbolContextLineEntry(line_entry)) 645130803Smarcel return line_entry; 646130803Smarcel } 647130803Smarcel return LineEntry(); 648130803Smarcel} 649130803Smarcel 650130803Smarcel//---------------------------------------------------------------------- 651130803Smarcel// 652130803Smarcel// SymbolContextSpecifier 653130803Smarcel// 654130803Smarcel//---------------------------------------------------------------------- 655130803Smarcel 656130803SmarcelSymbolContextSpecifier::SymbolContextSpecifier (const TargetSP &target_sp) : 657130803Smarcel m_target_sp (target_sp), 658130803Smarcel m_module_spec (), 659130803Smarcel m_module_sp (), 660130803Smarcel m_file_spec_ap (), 661130803Smarcel m_start_line (0), 662130803Smarcel m_end_line (0), 663130803Smarcel m_function_spec (), 664130803Smarcel m_class_name (), 665130803Smarcel m_address_range_ap (), 666130803Smarcel m_type (eNothingSpecified) 667130803Smarcel{ 668130803Smarcel} 669130803Smarcel 670130803SmarcelSymbolContextSpecifier::~SymbolContextSpecifier() 671130803Smarcel{ 672130803Smarcel} 673130803Smarcel 674130803Smarcelbool 675130803SmarcelSymbolContextSpecifier::AddLineSpecification (uint32_t line_no, SpecificationType type) 676130803Smarcel{ 677130803Smarcel bool return_value = true; 678130803Smarcel switch (type) 679130803Smarcel { 680130803Smarcel case eNothingSpecified: 681130803Smarcel Clear(); 682130803Smarcel break; 683130803Smarcel case eLineStartSpecified: 684130803Smarcel m_start_line = line_no; 685130803Smarcel m_type |= eLineStartSpecified; 686130803Smarcel break; 687130803Smarcel case eLineEndSpecified: 688130803Smarcel m_end_line = line_no; 689130803Smarcel m_type |= eLineEndSpecified; 690130803Smarcel break; 691130803Smarcel default: 692130803Smarcel return_value = false; 693130803Smarcel break; 694130803Smarcel } 695130803Smarcel return return_value; 696130803Smarcel} 697130803Smarcel 698130803Smarcelbool 699130803SmarcelSymbolContextSpecifier::AddSpecification (const char *spec_string, SpecificationType type) 700130803Smarcel{ 701130803Smarcel bool return_value = true; 702130803Smarcel switch (type) 703130803Smarcel { 704130803Smarcel case eNothingSpecified: 705130803Smarcel Clear(); 706130803Smarcel break; 707130803Smarcel case eModuleSpecified: 708130803Smarcel { 709130803Smarcel // See if we can find the Module, if so stick it in the SymbolContext. 710130803Smarcel FileSpec module_file_spec(spec_string, false); 711130803Smarcel ModuleSpec module_spec (module_file_spec); 712130803Smarcel lldb::ModuleSP module_sp (m_target_sp->GetImages().FindFirstModule (module_spec)); 713130803Smarcel m_type |= eModuleSpecified; 714130803Smarcel if (module_sp) 715130803Smarcel m_module_sp = module_sp; 716130803Smarcel else 717130803Smarcel m_module_spec.assign (spec_string); 718130803Smarcel } 719130803Smarcel break; 720130803Smarcel case eFileSpecified: 721130803Smarcel // CompUnits can't necessarily be resolved here, since an inlined function might show up in 722130803Smarcel // a number of CompUnits. Instead we just convert to a FileSpec and store it away. 723130803Smarcel m_file_spec_ap.reset (new FileSpec (spec_string, false)); 724130803Smarcel m_type |= eFileSpecified; 725130803Smarcel break; 726130803Smarcel case eLineStartSpecified: 727130803Smarcel m_start_line = Args::StringToSInt32(spec_string, 0, 0, &return_value); 728130803Smarcel if (return_value) 729130803Smarcel m_type |= eLineStartSpecified; 730130803Smarcel break; 731130803Smarcel case eLineEndSpecified: 732130803Smarcel m_end_line = Args::StringToSInt32(spec_string, 0, 0, &return_value); 733130803Smarcel if (return_value) 734130803Smarcel m_type |= eLineEndSpecified; 735130803Smarcel break; 736130803Smarcel case eFunctionSpecified: 737130803Smarcel m_function_spec.assign(spec_string); 738130803Smarcel m_type |= eFunctionSpecified; 739130803Smarcel break; 740130803Smarcel case eClassOrNamespaceSpecified: 741130803Smarcel Clear(); 742130803Smarcel m_class_name.assign (spec_string); 743130803Smarcel m_type = eClassOrNamespaceSpecified; 744130803Smarcel break; 745130803Smarcel case eAddressRangeSpecified: 746130803Smarcel // Not specified yet... 747130803Smarcel break; 748130803Smarcel } 749130803Smarcel 750130803Smarcel return return_value; 751130803Smarcel} 752130803Smarcel 753130803Smarcelvoid 754130803SmarcelSymbolContextSpecifier::Clear() 755130803Smarcel{ 756130803Smarcel m_module_spec.clear(); 757130803Smarcel m_file_spec_ap.reset(); 758130803Smarcel m_function_spec.clear(); 759130803Smarcel m_class_name.clear(); 760130803Smarcel m_start_line = 0; 761130803Smarcel m_end_line = 0; 762130803Smarcel m_address_range_ap.reset(); 763130803Smarcel 764130803Smarcel m_type = eNothingSpecified; 765130803Smarcel} 766130803Smarcel 767130803Smarcelbool 768130803SmarcelSymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc) 769130803Smarcel{ 770130803Smarcel if (m_type == eNothingSpecified) 771130803Smarcel return true; 772130803Smarcel 773130803Smarcel if (m_target_sp.get() != sc.target_sp.get()) 774130803Smarcel return false; 775130803Smarcel 776130803Smarcel if (m_type & eModuleSpecified) 777130803Smarcel { 778130803Smarcel if (sc.module_sp) 779130803Smarcel { 780130803Smarcel if (m_module_sp.get() != NULL) 781130803Smarcel { 782130803Smarcel if (m_module_sp.get() != sc.module_sp.get()) 783130803Smarcel return false; 784130803Smarcel } 785130803Smarcel else 786130803Smarcel { 787130803Smarcel FileSpec module_file_spec (m_module_spec.c_str(), false); 788130803Smarcel if (!FileSpec::Equal (module_file_spec, sc.module_sp->GetFileSpec(), false)) 789130803Smarcel return false; 790130803Smarcel } 791130803Smarcel } 792130803Smarcel } 793130803Smarcel if (m_type & eFileSpecified) 794130803Smarcel { 795130803Smarcel if (m_file_spec_ap.get()) 796130803Smarcel { 797130803Smarcel // If we don't have a block or a comp_unit, then we aren't going to match a source file. 798130803Smarcel if (sc.block == NULL && sc.comp_unit == NULL) 799130803Smarcel return false; 800130803Smarcel 801130803Smarcel // Check if the block is present, and if so is it inlined: 802130803Smarcel bool was_inlined = false; 803130803Smarcel if (sc.block != NULL) 804130803Smarcel { 805130803Smarcel const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo(); 806130803Smarcel if (inline_info != NULL) 807130803Smarcel { 808130803Smarcel was_inlined = true; 809130803Smarcel if (!FileSpec::Equal (inline_info->GetDeclaration().GetFile(), *(m_file_spec_ap.get()), false)) 810130803Smarcel return false; 811130803Smarcel } 812130803Smarcel } 813130803Smarcel 814130803Smarcel // Next check the comp unit, but only if the SymbolContext was not inlined. 815130803Smarcel if (!was_inlined && sc.comp_unit != NULL) 816130803Smarcel { 817130803Smarcel if (!FileSpec::Equal (*(sc.comp_unit), *(m_file_spec_ap.get()), false)) 818130803Smarcel return false; 819130803Smarcel } 820130803Smarcel } 821130803Smarcel } 822130803Smarcel if (m_type & eLineStartSpecified 823130803Smarcel || m_type & eLineEndSpecified) 824130803Smarcel { 825130803Smarcel if (sc.line_entry.line < m_start_line || sc.line_entry.line > m_end_line) 826130803Smarcel return false; 827130803Smarcel } 828130803Smarcel 829130803Smarcel if (m_type & eFunctionSpecified) 830130803Smarcel { 831130803Smarcel // First check the current block, and if it is inlined, get the inlined function name: 832130803Smarcel bool was_inlined = false; 833130803Smarcel ConstString func_name(m_function_spec.c_str()); 834130803Smarcel 835130803Smarcel if (sc.block != NULL) 836130803Smarcel { 837130803Smarcel const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo(); 838130803Smarcel if (inline_info != NULL) 839130803Smarcel { 840130803Smarcel was_inlined = true; 841130803Smarcel const Mangled &name = inline_info->GetMangled(); 842130803Smarcel if (!name.NameMatches (func_name)) 843130803Smarcel return false; 844130803Smarcel } 845130803Smarcel } 846130803Smarcel // If it wasn't inlined, check the name in the function or symbol: 847130803Smarcel if (!was_inlined) 848130803Smarcel { 849130803Smarcel if (sc.function != NULL) 850130803Smarcel { 851130803Smarcel if (!sc.function->GetMangled().NameMatches(func_name)) 852130803Smarcel return false; 853130803Smarcel } 854130803Smarcel else if (sc.symbol != NULL) 855130803Smarcel { 856130803Smarcel if (!sc.symbol->GetMangled().NameMatches(func_name)) 857130803Smarcel return false; 858130803Smarcel } 859130803Smarcel } 860130803Smarcel 861130803Smarcel 862130803Smarcel } 863130803Smarcel 864130803Smarcel return true; 865130803Smarcel} 866130803Smarcel 867130803Smarcelbool 868130803SmarcelSymbolContextSpecifier::AddressMatches(lldb::addr_t addr) 869130803Smarcel{ 870130803Smarcel if (m_type & eAddressRangeSpecified) 871130803Smarcel { 872130803Smarcel 873130803Smarcel } 874130803Smarcel else 875130803Smarcel { 876130803Smarcel Address match_address (addr, NULL); 877130803Smarcel SymbolContext sc; 878130803Smarcel m_target_sp->GetImages().ResolveSymbolContextForAddress(match_address, eSymbolContextEverything, sc); 879130803Smarcel return SymbolContextMatches(sc); 880130803Smarcel } 881130803Smarcel return true; 882130803Smarcel} 883130803Smarcel 884130803Smarcelvoid 885130803SmarcelSymbolContextSpecifier::GetDescription (Stream *s, lldb::DescriptionLevel level) const 886130803Smarcel{ 887130803Smarcel char path_str[PATH_MAX + 1]; 888130803Smarcel 889130803Smarcel if (m_type == eNothingSpecified) 890130803Smarcel { 891130803Smarcel s->Printf ("Nothing specified.\n"); 892130803Smarcel } 893130803Smarcel 894130803Smarcel if (m_type == eModuleSpecified) 895130803Smarcel { 896130803Smarcel s->Indent(); 897130803Smarcel if (m_module_sp) 898130803Smarcel { 899130803Smarcel m_module_sp->GetFileSpec().GetPath (path_str, PATH_MAX); 900130803Smarcel s->Printf ("Module: %s\n", path_str); 901130803Smarcel } 902130803Smarcel else 903130803Smarcel s->Printf ("Module: %s\n", m_module_spec.c_str()); 904130803Smarcel } 905130803Smarcel 906130803Smarcel if (m_type == eFileSpecified && m_file_spec_ap.get() != NULL) 907130803Smarcel { 908130803Smarcel m_file_spec_ap->GetPath (path_str, PATH_MAX); 909130803Smarcel s->Indent(); 910130803Smarcel s->Printf ("File: %s", path_str); 911130803Smarcel if (m_type == eLineStartSpecified) 912130803Smarcel { 913130803Smarcel s->Printf (" from line %lu", m_start_line); 914130803Smarcel if (m_type == eLineEndSpecified) 915130803Smarcel s->Printf ("to line %lu", m_end_line); 916130803Smarcel else 917130803Smarcel s->Printf ("to end"); 918130803Smarcel } 919130803Smarcel else if (m_type == eLineEndSpecified) 920130803Smarcel { 921130803Smarcel s->Printf (" from start to line %ld", m_end_line); 922130803Smarcel } 923130803Smarcel s->Printf (".\n"); 924130803Smarcel } 925130803Smarcel 926130803Smarcel if (m_type == eLineStartSpecified) 927130803Smarcel { 928130803Smarcel s->Indent(); 929130803Smarcel s->Printf ("From line %lu", m_start_line); 930130803Smarcel if (m_type == eLineEndSpecified) 931130803Smarcel s->Printf ("to line %lu", m_end_line); 932130803Smarcel else 933130803Smarcel s->Printf ("to end"); 934130803Smarcel s->Printf (".\n"); 935130803Smarcel } 936130803Smarcel else if (m_type == eLineEndSpecified) 937130803Smarcel { 938130803Smarcel s->Printf ("From start to line %ld.\n", m_end_line); 939130803Smarcel } 940130803Smarcel 941130803Smarcel if (m_type == eFunctionSpecified) 942130803Smarcel { 943130803Smarcel s->Indent(); 944130803Smarcel s->Printf ("Function: %s.\n", m_function_spec.c_str()); 945130803Smarcel } 946130803Smarcel 947130803Smarcel if (m_type == eClassOrNamespaceSpecified) 948130803Smarcel { 949130803Smarcel s->Indent(); 950130803Smarcel s->Printf ("Class name: %s.\n", m_class_name.c_str()); 951130803Smarcel } 952130803Smarcel 953130803Smarcel if (m_type == eAddressRangeSpecified && m_address_range_ap.get() != NULL) 954130803Smarcel { 955130803Smarcel s->Indent(); 956130803Smarcel s->PutCString ("Address range: "); 957130803Smarcel m_address_range_ap->Dump (s, m_target_sp.get(), Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress); 958130803Smarcel s->PutCString ("\n"); 959130803Smarcel } 960130803Smarcel} 961130803Smarcel 962130803Smarcel//---------------------------------------------------------------------- 963130803Smarcel// 964130803Smarcel// SymbolContextList 965130803Smarcel// 966130803Smarcel//---------------------------------------------------------------------- 967130803Smarcel 968130803Smarcel 969130803SmarcelSymbolContextList::SymbolContextList() : 970130803Smarcel m_symbol_contexts() 971130803Smarcel{ 972130803Smarcel} 973130803Smarcel 974130803SmarcelSymbolContextList::~SymbolContextList() 975130803Smarcel{ 976130803Smarcel} 977130803Smarcel 978130803Smarcelvoid 979130803SmarcelSymbolContextList::Append(const SymbolContext& sc) 980130803Smarcel{ 981130803Smarcel m_symbol_contexts.push_back(sc); 982130803Smarcel} 983130803Smarcel 984130803Smarcelvoid 985130803SmarcelSymbolContextList::Append (const SymbolContextList& sc_list) 986130803Smarcel{ 987130803Smarcel collection::const_iterator pos, end = sc_list.m_symbol_contexts.end(); 988130803Smarcel for (pos = sc_list.m_symbol_contexts.begin(); pos != end; ++pos) 989130803Smarcel m_symbol_contexts.push_back (*pos); 990130803Smarcel} 991130803Smarcel 992130803Smarcel 993130803Smarceluint32_t 994130803SmarcelSymbolContextList::AppendIfUnique (const SymbolContextList& sc_list, bool merge_symbol_into_function) 995130803Smarcel{ 996130803Smarcel uint32_t unique_sc_add_count = 0; 997130803Smarcel collection::const_iterator pos, end = sc_list.m_symbol_contexts.end(); 998130803Smarcel for (pos = sc_list.m_symbol_contexts.begin(); pos != end; ++pos) 999130803Smarcel { 1000130803Smarcel if (AppendIfUnique (*pos, merge_symbol_into_function)) 1001130803Smarcel ++unique_sc_add_count; 1002130803Smarcel } 1003130803Smarcel return unique_sc_add_count; 1004130803Smarcel} 1005130803Smarcel 1006130803Smarcelbool 1007130803SmarcelSymbolContextList::AppendIfUnique (const SymbolContext& sc, bool merge_symbol_into_function) 1008130803Smarcel{ 1009130803Smarcel collection::iterator pos, end = m_symbol_contexts.end(); 1010130803Smarcel for (pos = m_symbol_contexts.begin(); pos != end; ++pos) 1011130803Smarcel { 1012130803Smarcel if (*pos == sc) 1013130803Smarcel return false; 1014130803Smarcel } 1015130803Smarcel if (merge_symbol_into_function 1016130803Smarcel && sc.symbol != NULL 1017130803Smarcel && sc.comp_unit == NULL 1018130803Smarcel && sc.function == NULL 1019130803Smarcel && sc.block == NULL 1020130803Smarcel && sc.line_entry.IsValid() == false) 1021130803Smarcel { 1022130803Smarcel if (sc.symbol->ValueIsAddress()) 1023130803Smarcel { 1024130803Smarcel for (pos = m_symbol_contexts.begin(); pos != end; ++pos) 1025130803Smarcel { 1026130803Smarcel // Don't merge symbols into inlined function symbol contexts 1027130803Smarcel if (pos->block && pos->block->GetContainingInlinedBlock()) 1028130803Smarcel continue; 1029130803Smarcel 1030130803Smarcel if (pos->function) 1031130803Smarcel { 1032130803Smarcel if (pos->function->GetAddressRange().GetBaseAddress() == sc.symbol->GetAddress()) 1033130803Smarcel { 1034130803Smarcel // Do we already have a function with this symbol? 1035130803Smarcel if (pos->symbol == sc.symbol) 1036130803Smarcel return false; 1037130803Smarcel if (pos->symbol == NULL) 1038130803Smarcel { 1039130803Smarcel pos->symbol = sc.symbol; 1040130803Smarcel return false; 1041130803Smarcel } 1042130803Smarcel } 1043130803Smarcel } 1044130803Smarcel } 1045130803Smarcel } 1046130803Smarcel } 1047130803Smarcel m_symbol_contexts.push_back(sc); 1048130803Smarcel return true; 1049130803Smarcel} 1050130803Smarcel 1051130803Smarcelbool 1052130803SmarcelSymbolContextList::MergeSymbolContextIntoFunctionContext (const SymbolContext& symbol_sc, 1053130803Smarcel uint32_t start_idx, 1054130803Smarcel uint32_t stop_idx) 1055130803Smarcel{ 1056130803Smarcel if (symbol_sc.symbol != NULL 1057130803Smarcel && symbol_sc.comp_unit == NULL 1058130803Smarcel && symbol_sc.function == NULL 1059130803Smarcel && symbol_sc.block == NULL 1060130803Smarcel && symbol_sc.line_entry.IsValid() == false) 1061130803Smarcel { 1062130803Smarcel if (symbol_sc.symbol->ValueIsAddress()) 1063130803Smarcel { 1064130803Smarcel const size_t end = std::min<size_t>(m_symbol_contexts.size(), stop_idx); 1065130803Smarcel for (size_t i=start_idx; i<end; ++i) 1066130803Smarcel { 1067130803Smarcel const SymbolContext &function_sc = m_symbol_contexts[i]; 1068130803Smarcel // Don't merge symbols into inlined function symbol contexts 1069130803Smarcel if (function_sc.block && function_sc.block->GetContainingInlinedBlock()) 1070130803Smarcel continue; 1071130803Smarcel 1072130803Smarcel if (function_sc.function) 1073130803Smarcel { 1074130803Smarcel if (function_sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddress()) 1075130803Smarcel { 1076130803Smarcel // Do we already have a function with this symbol? 1077130803Smarcel if (function_sc.symbol == symbol_sc.symbol) 1078130803Smarcel return true; // Already have a symbol context with this symbol, return true 1079130803Smarcel 1080130803Smarcel if (function_sc.symbol == NULL) 1081130803Smarcel { 1082130803Smarcel // We successfully merged this symbol into an existing symbol context 1083130803Smarcel m_symbol_contexts[i].symbol = symbol_sc.symbol; 1084130803Smarcel return true; 1085130803Smarcel } 1086130803Smarcel } 1087130803Smarcel } 1088130803Smarcel } 1089130803Smarcel } 1090130803Smarcel } 1091130803Smarcel return false; 1092130803Smarcel} 1093130803Smarcel 1094130803Smarcelvoid 1095130803SmarcelSymbolContextList::Clear() 1096130803Smarcel{ 1097130803Smarcel m_symbol_contexts.clear(); 1098130803Smarcel} 1099130803Smarcel 1100130803Smarcelvoid 1101130803SmarcelSymbolContextList::Dump(Stream *s, Target *target) const 1102130803Smarcel{ 1103130803Smarcel 1104130803Smarcel *s << (void *)this << ": "; 1105130803Smarcel s->Indent(); 1106130803Smarcel s->PutCString("SymbolContextList"); 1107130803Smarcel s->EOL(); 1108130803Smarcel s->IndentMore(); 1109130803Smarcel 1110130803Smarcel collection::const_iterator pos, end = m_symbol_contexts.end(); 1111130803Smarcel for (pos = m_symbol_contexts.begin(); pos != end; ++pos) 1112130803Smarcel { 1113130803Smarcel //pos->Dump(s, target); 1114130803Smarcel pos->GetDescription(s, eDescriptionLevelVerbose, target); 1115130803Smarcel } 1116130803Smarcel s->IndentLess(); 1117130803Smarcel} 1118130803Smarcel 1119130803Smarcelbool 1120130803SmarcelSymbolContextList::GetContextAtIndex(size_t idx, SymbolContext& sc) const 1121130803Smarcel{ 1122130803Smarcel if (idx < m_symbol_contexts.size()) 1123130803Smarcel { 1124130803Smarcel sc = m_symbol_contexts[idx]; 1125130803Smarcel return true; 1126130803Smarcel } 1127130803Smarcel return false; 1128130803Smarcel} 1129130803Smarcel 1130130803Smarcelbool 1131130803SmarcelSymbolContextList::GetLastContext(SymbolContext& sc) const 1132130803Smarcel{ 1133130803Smarcel if (!m_symbol_contexts.empty()) 1134130803Smarcel { 1135130803Smarcel sc = m_symbol_contexts.back(); 1136130803Smarcel return true; 1137130803Smarcel } 1138130803Smarcel return false; 1139130803Smarcel} 1140130803Smarcel 1141130803Smarcelbool 1142130803SmarcelSymbolContextList::RemoveContextAtIndex (size_t idx) 1143130803Smarcel{ 1144130803Smarcel if (idx < m_symbol_contexts.size()) 1145130803Smarcel { 1146130803Smarcel m_symbol_contexts.erase(m_symbol_contexts.begin() + idx); 1147130803Smarcel return true; 1148130803Smarcel } 1149130803Smarcel return false; 1150130803Smarcel} 1151130803Smarcel 1152130803Smarceluint32_t 1153130803SmarcelSymbolContextList::GetSize() const 1154130803Smarcel{ 1155130803Smarcel return m_symbol_contexts.size(); 1156130803Smarcel} 1157130803Smarcel 1158130803Smarceluint32_t 1159130803SmarcelSymbolContextList::NumLineEntriesWithLine (uint32_t line) const 1160130803Smarcel{ 1161130803Smarcel uint32_t match_count = 0; 1162130803Smarcel const size_t size = m_symbol_contexts.size(); 1163130803Smarcel for (size_t idx = 0; idx<size; ++idx) 1164130803Smarcel { 1165130803Smarcel if (m_symbol_contexts[idx].line_entry.line == line) 1166130803Smarcel ++match_count; 1167130803Smarcel } 1168130803Smarcel return match_count; 1169130803Smarcel} 1170130803Smarcel 1171130803Smarcelvoid 1172130803SmarcelSymbolContextList::GetDescription(Stream *s, 1173130803Smarcel lldb::DescriptionLevel level, 1174130803Smarcel Target *target) const 1175130803Smarcel{ 1176130803Smarcel const size_t size = m_symbol_contexts.size(); 1177130803Smarcel for (size_t idx = 0; idx<size; ++idx) 1178130803Smarcel m_symbol_contexts[idx].GetDescription (s, level, target); 1179130803Smarcel} 1180130803Smarcel 1181130803Smarcelbool 1182130803Smarcellldb_private::operator== (const SymbolContextList& lhs, const SymbolContextList& rhs) 1183130803Smarcel{ 1184130803Smarcel const uint32_t size = lhs.GetSize(); 1185130803Smarcel if (size != rhs.GetSize()) 1186130803Smarcel return false; 1187130803Smarcel 1188130803Smarcel SymbolContext lhs_sc; 1189130803Smarcel SymbolContext rhs_sc; 1190130803Smarcel for (uint32_t i=0; i<size; ++i) 1191130803Smarcel { 1192130803Smarcel lhs.GetContextAtIndex(i, lhs_sc); 1193130803Smarcel rhs.GetContextAtIndex(i, rhs_sc); 1194130803Smarcel if (lhs_sc != rhs_sc) 1195130803Smarcel return false; 1196130803Smarcel } 1197130803Smarcel return true; 1198130803Smarcel} 1199130803Smarcel 1200130803Smarcelbool 1201130803Smarcellldb_private::operator!= (const SymbolContextList& lhs, const SymbolContextList& rhs) 1202130803Smarcel{ 1203130803Smarcel return !(lhs == rhs); 1204130803Smarcel} 1205130803Smarcel 1206130803Smarcel