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" 16288943Sdim#include "lldb/Host/StringConvert.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" 24288943Sdim#include "lldb/Symbol/Variable.h" 25254721Semaste#include "lldb/Target/Target.h" 26254721Semaste 27254721Semasteusing namespace lldb; 28254721Semasteusing namespace lldb_private; 29254721Semaste 30254721SemasteSymbolContext::SymbolContext() : 31254721Semaste target_sp (), 32254721Semaste module_sp (), 33276479Sdim comp_unit (nullptr), 34276479Sdim function (nullptr), 35276479Sdim block (nullptr), 36254721Semaste line_entry (), 37288943Sdim symbol (nullptr), 38288943Sdim variable (nullptr) 39254721Semaste{ 40254721Semaste} 41254721Semaste 42254721SemasteSymbolContext::SymbolContext(const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) : 43254721Semaste target_sp (), 44254721Semaste module_sp (m), 45254721Semaste comp_unit (cu), 46254721Semaste function (f), 47254721Semaste block (b), 48254721Semaste line_entry (), 49288943Sdim symbol (s), 50288943Sdim variable (nullptr) 51254721Semaste{ 52254721Semaste if (le) 53254721Semaste line_entry = *le; 54254721Semaste} 55254721Semaste 56254721SemasteSymbolContext::SymbolContext(const TargetSP &t, const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) : 57254721Semaste target_sp (t), 58254721Semaste module_sp (m), 59254721Semaste comp_unit (cu), 60254721Semaste function (f), 61254721Semaste block (b), 62254721Semaste line_entry (), 63288943Sdim symbol (s), 64288943Sdim variable (nullptr) 65254721Semaste{ 66254721Semaste if (le) 67254721Semaste line_entry = *le; 68254721Semaste} 69254721Semaste 70254721SemasteSymbolContext::SymbolContext(const SymbolContext& rhs) : 71254721Semaste target_sp (rhs.target_sp), 72254721Semaste module_sp (rhs.module_sp), 73254721Semaste comp_unit (rhs.comp_unit), 74254721Semaste function (rhs.function), 75254721Semaste block (rhs.block), 76254721Semaste line_entry (rhs.line_entry), 77288943Sdim symbol (rhs.symbol), 78288943Sdim variable (rhs.variable) 79254721Semaste{ 80254721Semaste} 81254721Semaste 82254721Semaste 83254721SemasteSymbolContext::SymbolContext (SymbolContextScope *sc_scope) : 84254721Semaste target_sp (), 85254721Semaste module_sp (), 86276479Sdim comp_unit (nullptr), 87276479Sdim function (nullptr), 88276479Sdim block (nullptr), 89254721Semaste line_entry (), 90288943Sdim symbol (nullptr), 91288943Sdim variable (nullptr) 92254721Semaste{ 93254721Semaste sc_scope->CalculateSymbolContext (this); 94254721Semaste} 95254721Semaste 96254721SemasteSymbolContext::~SymbolContext () 97254721Semaste{ 98254721Semaste} 99254721Semaste 100254721Semasteconst SymbolContext& 101254721SemasteSymbolContext::operator= (const SymbolContext& rhs) 102254721Semaste{ 103254721Semaste if (this != &rhs) 104254721Semaste { 105254721Semaste target_sp = rhs.target_sp; 106254721Semaste module_sp = rhs.module_sp; 107254721Semaste comp_unit = rhs.comp_unit; 108254721Semaste function = rhs.function; 109254721Semaste block = rhs.block; 110254721Semaste line_entry = rhs.line_entry; 111254721Semaste symbol = rhs.symbol; 112288943Sdim variable = rhs.variable; 113254721Semaste } 114254721Semaste return *this; 115254721Semaste} 116254721Semaste 117254721Semastevoid 118254721SemasteSymbolContext::Clear(bool clear_target) 119254721Semaste{ 120254721Semaste if (clear_target) 121254721Semaste target_sp.reset(); 122254721Semaste module_sp.reset(); 123276479Sdim comp_unit = nullptr; 124276479Sdim function = nullptr; 125276479Sdim block = nullptr; 126254721Semaste line_entry.Clear(); 127276479Sdim symbol = nullptr; 128288943Sdim variable = nullptr; 129254721Semaste} 130254721Semaste 131254721Semastebool 132288943SdimSymbolContext::DumpStopContext ( 133254721Semaste Stream *s, 134254721Semaste ExecutionContextScope *exe_scope, 135254721Semaste const Address &addr, 136254721Semaste bool show_fullpaths, 137254721Semaste bool show_module, 138280031Sdim bool show_inlined_frames, 139288943Sdim bool show_function_arguments, 140288943Sdim bool show_function_name 141254721Semaste) const 142254721Semaste{ 143254721Semaste bool dumped_something = false; 144254721Semaste if (show_module && module_sp) 145254721Semaste { 146254721Semaste if (show_fullpaths) 147254721Semaste *s << module_sp->GetFileSpec(); 148254721Semaste else 149254721Semaste *s << module_sp->GetFileSpec().GetFilename(); 150254721Semaste s->PutChar('`'); 151254721Semaste dumped_something = true; 152254721Semaste } 153254721Semaste 154276479Sdim if (function != nullptr) 155254721Semaste { 156254721Semaste SymbolContext inline_parent_sc; 157254721Semaste Address inline_parent_addr; 158288943Sdim if (show_function_name == false) 159254721Semaste { 160288943Sdim s->Printf("<"); 161254721Semaste dumped_something = true; 162280031Sdim } 163288943Sdim else 164280031Sdim { 165288943Sdim ConstString name; 166288943Sdim if (show_function_arguments == false) 167288943Sdim name = function->GetNameNoArguments(); 168288943Sdim if (!name) 169288943Sdim name = function->GetName(); 170288943Sdim if (name) 171288943Sdim name.Dump(s); 172254721Semaste } 173254721Semaste 174254721Semaste if (addr.IsValid()) 175254721Semaste { 176254721Semaste const addr_t function_offset = addr.GetOffset() - function->GetAddressRange().GetBaseAddress().GetOffset(); 177288943Sdim if (show_function_name == false) 178254721Semaste { 179288943Sdim // Print +offset even if offset is 0 180254721Semaste dumped_something = true; 181288943Sdim s->Printf("+%" PRIu64 ">", function_offset); 182288943Sdim } 183288943Sdim else if (function_offset) 184288943Sdim { 185288943Sdim dumped_something = true; 186254721Semaste s->Printf(" + %" PRIu64, function_offset); 187254721Semaste } 188254721Semaste } 189254721Semaste 190254721Semaste if (GetParentOfInlinedScope (addr, inline_parent_sc, inline_parent_addr)) 191254721Semaste { 192254721Semaste dumped_something = true; 193254721Semaste Block *inlined_block = block->GetContainingInlinedBlock(); 194254721Semaste const InlineFunctionInfo* inlined_block_info = inlined_block->GetInlinedFunctionInfo(); 195288943Sdim s->Printf (" [inlined] %s", inlined_block_info->GetName(function->GetLanguage()).GetCString()); 196254721Semaste 197254721Semaste lldb_private::AddressRange block_range; 198254721Semaste if (inlined_block->GetRangeContainingAddress(addr, block_range)) 199254721Semaste { 200254721Semaste const addr_t inlined_function_offset = addr.GetOffset() - block_range.GetBaseAddress().GetOffset(); 201254721Semaste if (inlined_function_offset) 202254721Semaste { 203254721Semaste s->Printf(" + %" PRIu64, inlined_function_offset); 204254721Semaste } 205254721Semaste } 206254721Semaste const Declaration &call_site = inlined_block_info->GetCallSite(); 207254721Semaste if (call_site.IsValid()) 208254721Semaste { 209254721Semaste s->PutCString(" at "); 210254721Semaste call_site.DumpStopContext (s, show_fullpaths); 211254721Semaste } 212254721Semaste if (show_inlined_frames) 213254721Semaste { 214254721Semaste s->EOL(); 215254721Semaste s->Indent(); 216288943Sdim const bool show_function_name = true; 217288943Sdim return inline_parent_sc.DumpStopContext (s, exe_scope, inline_parent_addr, show_fullpaths, show_module, show_inlined_frames, show_function_arguments, show_function_name); 218254721Semaste } 219254721Semaste } 220254721Semaste else 221254721Semaste { 222254721Semaste if (line_entry.IsValid()) 223254721Semaste { 224254721Semaste dumped_something = true; 225254721Semaste s->PutCString(" at "); 226254721Semaste if (line_entry.DumpStopContext(s, show_fullpaths)) 227254721Semaste dumped_something = true; 228254721Semaste } 229254721Semaste } 230254721Semaste } 231276479Sdim else if (symbol != nullptr) 232254721Semaste { 233288943Sdim if (show_function_name == false) 234254721Semaste { 235288943Sdim s->Printf("<"); 236254721Semaste dumped_something = true; 237288943Sdim } 238288943Sdim else if (symbol->GetName()) 239288943Sdim { 240288943Sdim dumped_something = true; 241254721Semaste if (symbol->GetType() == eSymbolTypeTrampoline) 242254721Semaste s->PutCString("symbol stub for: "); 243288943Sdim symbol->GetName().Dump(s); 244254721Semaste } 245254721Semaste 246254721Semaste if (addr.IsValid() && symbol->ValueIsAddress()) 247254721Semaste { 248288943Sdim const addr_t symbol_offset = addr.GetOffset() - symbol->GetAddressRef().GetOffset(); 249288943Sdim if (show_function_name == false) 250254721Semaste { 251288943Sdim // Print +offset even if offset is 0 252254721Semaste dumped_something = true; 253288943Sdim s->Printf("+%" PRIu64 ">", symbol_offset); 254288943Sdim } 255288943Sdim else if (symbol_offset) 256288943Sdim { 257288943Sdim dumped_something = true; 258254721Semaste s->Printf(" + %" PRIu64, symbol_offset); 259254721Semaste } 260254721Semaste } 261254721Semaste } 262254721Semaste else if (addr.IsValid()) 263254721Semaste { 264254721Semaste addr.Dump(s, exe_scope, Address::DumpStyleModuleWithFileAddress); 265254721Semaste dumped_something = true; 266254721Semaste } 267254721Semaste return dumped_something; 268254721Semaste} 269254721Semaste 270254721Semastevoid 271254721SemasteSymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target) const 272254721Semaste{ 273254721Semaste if (module_sp) 274254721Semaste { 275254721Semaste s->Indent(" Module: file = \""); 276254721Semaste module_sp->GetFileSpec().Dump(s); 277254721Semaste *s << '"'; 278254721Semaste if (module_sp->GetArchitecture().IsValid()) 279254721Semaste s->Printf (", arch = \"%s\"", module_sp->GetArchitecture().GetArchitectureName()); 280254721Semaste s->EOL(); 281254721Semaste } 282254721Semaste 283276479Sdim if (comp_unit != nullptr) 284254721Semaste { 285254721Semaste s->Indent("CompileUnit: "); 286254721Semaste comp_unit->GetDescription (s, level); 287254721Semaste s->EOL(); 288254721Semaste } 289254721Semaste 290276479Sdim if (function != nullptr) 291254721Semaste { 292254721Semaste s->Indent(" Function: "); 293254721Semaste function->GetDescription (s, level, target); 294254721Semaste s->EOL(); 295254721Semaste 296254721Semaste Type *func_type = function->GetType(); 297254721Semaste if (func_type) 298254721Semaste { 299254721Semaste s->Indent(" FuncType: "); 300254721Semaste func_type->GetDescription (s, level, false); 301254721Semaste s->EOL(); 302254721Semaste } 303254721Semaste } 304254721Semaste 305276479Sdim if (block != nullptr) 306254721Semaste { 307254721Semaste std::vector<Block *> blocks; 308254721Semaste blocks.push_back (block); 309254721Semaste Block *parent_block = block->GetParent(); 310254721Semaste 311254721Semaste while (parent_block) 312254721Semaste { 313254721Semaste blocks.push_back (parent_block); 314254721Semaste parent_block = parent_block->GetParent(); 315254721Semaste } 316254721Semaste std::vector<Block *>::reverse_iterator pos; 317254721Semaste std::vector<Block *>::reverse_iterator begin = blocks.rbegin(); 318254721Semaste std::vector<Block *>::reverse_iterator end = blocks.rend(); 319254721Semaste for (pos = begin; pos != end; ++pos) 320254721Semaste { 321254721Semaste if (pos == begin) 322254721Semaste s->Indent(" Blocks: "); 323254721Semaste else 324254721Semaste s->Indent(" "); 325254721Semaste (*pos)->GetDescription(s, function, level, target); 326254721Semaste s->EOL(); 327254721Semaste } 328254721Semaste } 329254721Semaste 330254721Semaste if (line_entry.IsValid()) 331254721Semaste { 332254721Semaste s->Indent(" LineEntry: "); 333254721Semaste line_entry.GetDescription (s, level, comp_unit, target, false); 334254721Semaste s->EOL(); 335254721Semaste } 336254721Semaste 337276479Sdim if (symbol != nullptr) 338254721Semaste { 339254721Semaste s->Indent(" Symbol: "); 340254721Semaste symbol->GetDescription(s, level, target); 341254721Semaste s->EOL(); 342254721Semaste } 343288943Sdim 344288943Sdim if (variable != nullptr) 345288943Sdim { 346288943Sdim s->Indent(" Variable: "); 347288943Sdim 348288943Sdim s->Printf("id = {0x%8.8" PRIx64 "}, ", variable->GetID()); 349288943Sdim 350288943Sdim switch (variable->GetScope()) 351288943Sdim { 352288943Sdim case eValueTypeVariableGlobal: 353288943Sdim s->PutCString("kind = global, "); 354288943Sdim break; 355288943Sdim 356288943Sdim case eValueTypeVariableStatic: 357288943Sdim s->PutCString("kind = static, "); 358288943Sdim break; 359288943Sdim 360288943Sdim case eValueTypeVariableArgument: 361288943Sdim s->PutCString("kind = argument, "); 362288943Sdim break; 363288943Sdim 364288943Sdim case eValueTypeVariableLocal: 365288943Sdim s->PutCString("kind = local, "); 366288943Sdim break; 367288943Sdim 368288943Sdim default: 369288943Sdim break; 370288943Sdim } 371288943Sdim 372288943Sdim s->Printf ("name = \"%s\"\n", variable->GetName().GetCString()); 373288943Sdim } 374254721Semaste} 375254721Semaste 376254721Semasteuint32_t 377254721SemasteSymbolContext::GetResolvedMask () const 378254721Semaste{ 379254721Semaste uint32_t resolved_mask = 0; 380254721Semaste if (target_sp) resolved_mask |= eSymbolContextTarget; 381254721Semaste if (module_sp) resolved_mask |= eSymbolContextModule; 382254721Semaste if (comp_unit) resolved_mask |= eSymbolContextCompUnit; 383254721Semaste if (function) resolved_mask |= eSymbolContextFunction; 384254721Semaste if (block) resolved_mask |= eSymbolContextBlock; 385254721Semaste if (line_entry.IsValid()) resolved_mask |= eSymbolContextLineEntry; 386254721Semaste if (symbol) resolved_mask |= eSymbolContextSymbol; 387288943Sdim if (variable) resolved_mask |= eSymbolContextVariable; 388254721Semaste return resolved_mask; 389254721Semaste} 390254721Semaste 391254721Semastevoid 392254721SemasteSymbolContext::Dump(Stream *s, Target *target) const 393254721Semaste{ 394296417Sdim *s << this << ": "; 395254721Semaste s->Indent(); 396254721Semaste s->PutCString("SymbolContext"); 397254721Semaste s->IndentMore(); 398254721Semaste s->EOL(); 399254721Semaste s->IndentMore(); 400254721Semaste s->Indent(); 401296417Sdim *s << "Module = " << module_sp.get() << ' '; 402254721Semaste if (module_sp) 403254721Semaste module_sp->GetFileSpec().Dump(s); 404254721Semaste s->EOL(); 405254721Semaste s->Indent(); 406296417Sdim *s << "CompileUnit = " << comp_unit; 407276479Sdim if (comp_unit != nullptr) 408254721Semaste *s << " {0x" << comp_unit->GetID() << "} " << *(static_cast<FileSpec*> (comp_unit)); 409254721Semaste s->EOL(); 410254721Semaste s->Indent(); 411296417Sdim *s << "Function = " << function; 412276479Sdim if (function != nullptr) 413254721Semaste { 414254721Semaste *s << " {0x" << function->GetID() << "} " << function->GetType()->GetName() << ", address-range = "; 415254721Semaste function->GetAddressRange().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress); 416254721Semaste s->EOL(); 417254721Semaste s->Indent(); 418254721Semaste Type* func_type = function->GetType(); 419254721Semaste if (func_type) 420254721Semaste { 421254721Semaste *s << " Type = "; 422254721Semaste func_type->Dump (s, false); 423254721Semaste } 424254721Semaste } 425254721Semaste s->EOL(); 426254721Semaste s->Indent(); 427296417Sdim *s << "Block = " << block; 428276479Sdim if (block != nullptr) 429254721Semaste *s << " {0x" << block->GetID() << '}'; 430254721Semaste // Dump the block and pass it a negative depth to we print all the parent blocks 431254721Semaste //if (block != NULL) 432254721Semaste // block->Dump(s, function->GetFileAddress(), INT_MIN); 433254721Semaste s->EOL(); 434254721Semaste s->Indent(); 435254721Semaste *s << "LineEntry = "; 436254721Semaste line_entry.Dump (s, target, true, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, true); 437254721Semaste s->EOL(); 438254721Semaste s->Indent(); 439296417Sdim *s << "Symbol = " << symbol; 440276479Sdim if (symbol != nullptr && symbol->GetMangled()) 441288943Sdim *s << ' ' << symbol->GetName().AsCString(); 442254721Semaste s->EOL(); 443296417Sdim *s << "Variable = " << variable; 444288943Sdim if (variable != nullptr) 445288943Sdim { 446288943Sdim *s << " {0x" << variable->GetID() << "} " << variable->GetType()->GetName(); 447288943Sdim s->EOL(); 448288943Sdim } 449254721Semaste s->IndentLess(); 450254721Semaste s->IndentLess(); 451254721Semaste} 452254721Semaste 453254721Semastebool 454254721Semastelldb_private::operator== (const SymbolContext& lhs, const SymbolContext& rhs) 455254721Semaste{ 456254721Semaste return lhs.function == rhs.function 457254721Semaste && lhs.symbol == rhs.symbol 458254721Semaste && lhs.module_sp.get() == rhs.module_sp.get() 459254721Semaste && lhs.comp_unit == rhs.comp_unit 460254721Semaste && lhs.target_sp.get() == rhs.target_sp.get() 461288943Sdim && LineEntry::Compare(lhs.line_entry, rhs.line_entry) == 0 462288943Sdim && lhs.variable == rhs.variable; 463254721Semaste} 464254721Semaste 465254721Semastebool 466254721Semastelldb_private::operator!= (const SymbolContext& lhs, const SymbolContext& rhs) 467254721Semaste{ 468254721Semaste return lhs.function != rhs.function 469254721Semaste || lhs.symbol != rhs.symbol 470254721Semaste || lhs.module_sp.get() != rhs.module_sp.get() 471254721Semaste || lhs.comp_unit != rhs.comp_unit 472254721Semaste || lhs.target_sp.get() != rhs.target_sp.get() 473288943Sdim || LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0 474288943Sdim || lhs.variable != rhs.variable; 475254721Semaste} 476254721Semaste 477254721Semastebool 478254721SemasteSymbolContext::GetAddressRange (uint32_t scope, 479254721Semaste uint32_t range_idx, 480254721Semaste bool use_inline_block_range, 481254721Semaste AddressRange &range) const 482254721Semaste{ 483254721Semaste if ((scope & eSymbolContextLineEntry) && line_entry.IsValid()) 484254721Semaste { 485254721Semaste range = line_entry.range; 486254721Semaste return true; 487254721Semaste } 488254721Semaste 489276479Sdim if ((scope & eSymbolContextBlock) && (block != nullptr)) 490254721Semaste { 491254721Semaste if (use_inline_block_range) 492254721Semaste { 493254721Semaste Block *inline_block = block->GetContainingInlinedBlock(); 494254721Semaste if (inline_block) 495254721Semaste return inline_block->GetRangeAtIndex (range_idx, range); 496254721Semaste } 497254721Semaste else 498254721Semaste { 499254721Semaste return block->GetRangeAtIndex (range_idx, range); 500254721Semaste } 501254721Semaste } 502254721Semaste 503276479Sdim if ((scope & eSymbolContextFunction) && (function != nullptr)) 504254721Semaste { 505254721Semaste if (range_idx == 0) 506254721Semaste { 507254721Semaste range = function->GetAddressRange(); 508254721Semaste return true; 509254721Semaste } 510254721Semaste } 511254721Semaste 512276479Sdim if ((scope & eSymbolContextSymbol) && (symbol != nullptr)) 513254721Semaste { 514254721Semaste if (range_idx == 0) 515254721Semaste { 516254721Semaste if (symbol->ValueIsAddress()) 517254721Semaste { 518288943Sdim range.GetBaseAddress() = symbol->GetAddressRef(); 519254721Semaste range.SetByteSize (symbol->GetByteSize()); 520254721Semaste return true; 521254721Semaste } 522254721Semaste } 523254721Semaste } 524254721Semaste range.Clear(); 525254721Semaste return false; 526254721Semaste} 527254721Semaste 528296417SdimLanguageType 529296417SdimSymbolContext::GetLanguage () const 530296417Sdim{ 531296417Sdim LanguageType lang; 532296417Sdim if (function && 533296417Sdim (lang = function->GetLanguage()) != eLanguageTypeUnknown) 534296417Sdim { 535296417Sdim return lang; 536296417Sdim } 537296417Sdim else if (variable && 538296417Sdim (lang = variable->GetLanguage()) != eLanguageTypeUnknown) 539296417Sdim { 540296417Sdim return lang; 541296417Sdim } 542296417Sdim else if (symbol && 543296417Sdim (lang = symbol->GetLanguage()) != eLanguageTypeUnknown) 544296417Sdim { 545296417Sdim return lang; 546296417Sdim } 547296417Sdim else if (comp_unit && 548296417Sdim (lang = comp_unit->GetLanguage()) != eLanguageTypeUnknown) 549296417Sdim { 550296417Sdim return lang; 551296417Sdim } 552296417Sdim else if (symbol) 553296417Sdim { 554296417Sdim // If all else fails, try to guess the language from the name. 555296417Sdim return symbol->GetMangled().GuessLanguage(); 556296417Sdim } 557296417Sdim return eLanguageTypeUnknown; 558296417Sdim} 559296417Sdim 560254721Semastebool 561254721SemasteSymbolContext::GetParentOfInlinedScope (const Address &curr_frame_pc, 562254721Semaste SymbolContext &next_frame_sc, 563254721Semaste Address &next_frame_pc) const 564254721Semaste{ 565254721Semaste next_frame_sc.Clear(false); 566254721Semaste next_frame_pc.Clear(); 567254721Semaste 568254721Semaste if (block) 569254721Semaste { 570254721Semaste //const addr_t curr_frame_file_addr = curr_frame_pc.GetFileAddress(); 571254721Semaste 572254721Semaste // In order to get the parent of an inlined function we first need to 573254721Semaste // see if we are in an inlined block as "this->block" could be an 574254721Semaste // inlined block, or a parent of "block" could be. So lets check if 575254721Semaste // this block or one of this blocks parents is an inlined function. 576254721Semaste Block *curr_inlined_block = block->GetContainingInlinedBlock(); 577254721Semaste if (curr_inlined_block) 578254721Semaste { 579254721Semaste // "this->block" is contained in an inline function block, so to 580254721Semaste // get the scope above the inlined block, we get the parent of the 581254721Semaste // inlined block itself 582254721Semaste Block *next_frame_block = curr_inlined_block->GetParent(); 583254721Semaste // Now calculate the symbol context of the containing block 584254721Semaste next_frame_block->CalculateSymbolContext (&next_frame_sc); 585254721Semaste 586254721Semaste // If we get here we weren't able to find the return line entry using the nesting of the blocks and 587254721Semaste // the line table. So just use the call site info from our inlined block. 588254721Semaste 589254721Semaste AddressRange range; 590254721Semaste if (curr_inlined_block->GetRangeContainingAddress (curr_frame_pc, range)) 591254721Semaste { 592254721Semaste // To see there this new frame block it, we need to look at the 593254721Semaste // call site information from 594254721Semaste const InlineFunctionInfo* curr_inlined_block_inlined_info = curr_inlined_block->GetInlinedFunctionInfo(); 595254721Semaste next_frame_pc = range.GetBaseAddress(); 596254721Semaste next_frame_sc.line_entry.range.GetBaseAddress() = next_frame_pc; 597254721Semaste next_frame_sc.line_entry.file = curr_inlined_block_inlined_info->GetCallSite().GetFile(); 598254721Semaste next_frame_sc.line_entry.line = curr_inlined_block_inlined_info->GetCallSite().GetLine(); 599254721Semaste next_frame_sc.line_entry.column = curr_inlined_block_inlined_info->GetCallSite().GetColumn(); 600254721Semaste return true; 601254721Semaste } 602254721Semaste else 603254721Semaste { 604254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS)); 605254721Semaste 606254721Semaste if (log) 607254721Semaste { 608254721Semaste log->Printf ("warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64, 609254721Semaste curr_inlined_block->GetID(), curr_frame_pc.GetFileAddress()); 610254721Semaste } 611254721Semaste#ifdef LLDB_CONFIGURATION_DEBUG 612254721Semaste else 613254721Semaste { 614254721Semaste ObjectFile *objfile = NULL; 615254721Semaste if (module_sp) 616254721Semaste { 617254721Semaste SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(); 618254721Semaste if (symbol_vendor) 619254721Semaste { 620254721Semaste SymbolFile *symbol_file = symbol_vendor->GetSymbolFile(); 621254721Semaste if (symbol_file) 622254721Semaste objfile = symbol_file->GetObjectFile(); 623254721Semaste } 624254721Semaste } 625254721Semaste if (objfile) 626254721Semaste { 627254721Semaste Host::SystemLog (Host::eSystemLogWarning, 628254721Semaste "warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64 " in %s\n", 629254721Semaste curr_inlined_block->GetID(), 630254721Semaste curr_frame_pc.GetFileAddress(), 631254721Semaste objfile->GetFileSpec().GetPath().c_str()); 632254721Semaste } 633254721Semaste else 634254721Semaste { 635254721Semaste Host::SystemLog (Host::eSystemLogWarning, 636254721Semaste "warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64 "\n", 637254721Semaste curr_inlined_block->GetID(), 638254721Semaste curr_frame_pc.GetFileAddress()); 639254721Semaste } 640254721Semaste } 641254721Semaste#endif 642254721Semaste } 643254721Semaste } 644254721Semaste } 645254721Semaste 646254721Semaste return false; 647254721Semaste} 648254721Semaste 649254721SemasteBlock * 650254721SemasteSymbolContext::GetFunctionBlock () 651254721Semaste{ 652254721Semaste if (function) 653254721Semaste { 654254721Semaste if (block) 655254721Semaste { 656254721Semaste // If this symbol context has a block, check to see if this block 657254721Semaste // is itself, or is contained within a block with inlined function 658254721Semaste // information. If so, then the inlined block is the block that 659254721Semaste // defines the function. 660254721Semaste Block *inlined_block = block->GetContainingInlinedBlock(); 661254721Semaste if (inlined_block) 662254721Semaste return inlined_block; 663254721Semaste 664254721Semaste // The block in this symbol context is not inside an inlined 665254721Semaste // block, so the block that defines the function is the function's 666254721Semaste // top level block, which is returned below. 667254721Semaste } 668254721Semaste 669254721Semaste // There is no block information in this symbol context, so we must 670254721Semaste // assume that the block that is desired is the top level block of 671254721Semaste // the function itself. 672254721Semaste return &function->GetBlock(true); 673254721Semaste } 674276479Sdim return nullptr; 675254721Semaste} 676254721Semaste 677254721Semastebool 678254721SemasteSymbolContext::GetFunctionMethodInfo (lldb::LanguageType &language, 679254721Semaste bool &is_instance_method, 680254721Semaste ConstString &language_object_name) 681254721Semaste 682254721Semaste 683254721Semaste{ 684296417Sdim Block *function_block = GetFunctionBlock(); 685254721Semaste if (function_block) 686254721Semaste { 687296417Sdim CompilerDeclContext decl_ctx = function_block->GetDeclContext(); 688296417Sdim if (decl_ctx) 689296417Sdim return decl_ctx.IsClassMethod(&language, &is_instance_method, &language_object_name); 690296417Sdim } 691296417Sdim return false; 692296417Sdim} 693296417Sdim 694296417Sdimvoid 695296417SdimSymbolContext::SortTypeList(TypeMap &type_map, TypeList &type_list) const 696296417Sdim{ 697296417Sdim Block * curr_block = block; 698296417Sdim bool isInlinedblock = false; 699296417Sdim if (curr_block != nullptr && curr_block->GetContainingInlinedBlock() != nullptr) 700296417Sdim isInlinedblock = true; 701296417Sdim 702296417Sdim //---------------------------------------------------------------------- 703296417Sdim // Find all types that match the current block if we have one and put 704296417Sdim // them first in the list. Keep iterating up through all blocks. 705296417Sdim //---------------------------------------------------------------------- 706296417Sdim while (curr_block != nullptr && !isInlinedblock) 707296417Sdim { 708296417Sdim type_map.ForEach([curr_block, &type_list](const lldb::TypeSP& type_sp) -> bool { 709296417Sdim SymbolContextScope *scs = type_sp->GetSymbolContextScope(); 710296417Sdim if (scs && curr_block == scs->CalculateSymbolContextBlock()) 711296417Sdim type_list.Insert(type_sp); 712296417Sdim return true; // Keep iterating 713296417Sdim }); 714296417Sdim 715296417Sdim // Remove any entries that are now in "type_list" from "type_map" 716296417Sdim // since we can't remove from type_map while iterating 717296417Sdim type_list.ForEach([&type_map](const lldb::TypeSP& type_sp) -> bool { 718296417Sdim type_map.Remove(type_sp); 719296417Sdim return true; // Keep iterating 720296417Sdim }); 721296417Sdim curr_block = curr_block->GetParent(); 722296417Sdim } 723296417Sdim //---------------------------------------------------------------------- 724296417Sdim // Find all types that match the current function, if we have onem, and 725296417Sdim // put them next in the list. 726296417Sdim //---------------------------------------------------------------------- 727296417Sdim if (function != nullptr && !type_map.Empty()) 728296417Sdim { 729296417Sdim const size_t old_type_list_size = type_list.GetSize(); 730296417Sdim type_map.ForEach([this, &type_list](const lldb::TypeSP& type_sp) -> bool { 731296417Sdim SymbolContextScope *scs = type_sp->GetSymbolContextScope(); 732296417Sdim if (scs && function == scs->CalculateSymbolContextFunction()) 733296417Sdim type_list.Insert(type_sp); 734296417Sdim return true; // Keep iterating 735296417Sdim }); 736296417Sdim 737296417Sdim // Remove any entries that are now in "type_list" from "type_map" 738296417Sdim // since we can't remove from type_map while iterating 739296417Sdim const size_t new_type_list_size = type_list.GetSize(); 740296417Sdim if (new_type_list_size > old_type_list_size) 741254721Semaste { 742296417Sdim for (size_t i=old_type_list_size; i<new_type_list_size; ++i) 743296417Sdim type_map.Remove(type_list.GetTypeAtIndex(i)); 744254721Semaste } 745254721Semaste } 746296417Sdim //---------------------------------------------------------------------- 747296417Sdim // Find all types that match the current compile unit, if we have one, 748296417Sdim // and put them next in the list. 749296417Sdim //---------------------------------------------------------------------- 750296417Sdim if (comp_unit != nullptr && !type_map.Empty()) 751296417Sdim { 752296417Sdim const size_t old_type_list_size = type_list.GetSize(); 753296417Sdim 754296417Sdim type_map.ForEach([this, &type_list](const lldb::TypeSP& type_sp) -> bool { 755296417Sdim SymbolContextScope *scs = type_sp->GetSymbolContextScope(); 756296417Sdim if (scs && comp_unit == scs->CalculateSymbolContextCompileUnit()) 757296417Sdim type_list.Insert(type_sp); 758296417Sdim return true; // Keep iterating 759296417Sdim }); 760296417Sdim 761296417Sdim // Remove any entries that are now in "type_list" from "type_map" 762296417Sdim // since we can't remove from type_map while iterating 763296417Sdim const size_t new_type_list_size = type_list.GetSize(); 764296417Sdim if (new_type_list_size > old_type_list_size) 765296417Sdim { 766296417Sdim for (size_t i=old_type_list_size; i<new_type_list_size; ++i) 767296417Sdim type_map.Remove(type_list.GetTypeAtIndex(i)); 768296417Sdim } 769296417Sdim } 770296417Sdim //---------------------------------------------------------------------- 771296417Sdim // Find all types that match the current module, if we have one, and put 772296417Sdim // them next in the list. 773296417Sdim //---------------------------------------------------------------------- 774296417Sdim if (module_sp && !type_map.Empty()) 775296417Sdim { 776296417Sdim const size_t old_type_list_size = type_list.GetSize(); 777296417Sdim type_map.ForEach([this, &type_list](const lldb::TypeSP& type_sp) -> bool { 778296417Sdim SymbolContextScope *scs = type_sp->GetSymbolContextScope(); 779296417Sdim if (scs && module_sp == scs->CalculateSymbolContextModule()) 780296417Sdim type_list.Insert(type_sp); 781296417Sdim return true; // Keep iterating 782296417Sdim }); 783296417Sdim // Remove any entries that are now in "type_list" from "type_map" 784296417Sdim // since we can't remove from type_map while iterating 785296417Sdim const size_t new_type_list_size = type_list.GetSize(); 786296417Sdim if (new_type_list_size > old_type_list_size) 787296417Sdim { 788296417Sdim for (size_t i=old_type_list_size; i<new_type_list_size; ++i) 789296417Sdim type_map.Remove(type_list.GetTypeAtIndex(i)); 790296417Sdim } 791296417Sdim } 792296417Sdim //---------------------------------------------------------------------- 793296417Sdim // Any types that are left get copied into the list an any order. 794296417Sdim //---------------------------------------------------------------------- 795296417Sdim if (!type_map.Empty()) 796296417Sdim { 797296417Sdim type_map.ForEach([&type_list](const lldb::TypeSP& type_sp) -> bool { 798296417Sdim type_list.Insert(type_sp); 799296417Sdim return true; // Keep iterating 800296417Sdim }); 801296417Sdim } 802254721Semaste} 803254721Semaste 804254721SemasteConstString 805254721SemasteSymbolContext::GetFunctionName (Mangled::NamePreference preference) const 806254721Semaste{ 807254721Semaste if (function) 808254721Semaste { 809254721Semaste if (block) 810254721Semaste { 811254721Semaste Block *inlined_block = block->GetContainingInlinedBlock(); 812254721Semaste 813254721Semaste if (inlined_block) 814254721Semaste { 815254721Semaste const InlineFunctionInfo *inline_info = inlined_block->GetInlinedFunctionInfo(); 816254721Semaste if (inline_info) 817288943Sdim return inline_info->GetName(function->GetLanguage()); 818254721Semaste } 819254721Semaste } 820288943Sdim return function->GetMangled().GetName(function->GetLanguage(), preference); 821254721Semaste } 822254721Semaste else if (symbol && symbol->ValueIsAddress()) 823254721Semaste { 824288943Sdim return symbol->GetMangled().GetName(symbol->GetLanguage(), preference); 825254721Semaste } 826254721Semaste else 827254721Semaste { 828254721Semaste // No function, return an empty string. 829254721Semaste return ConstString(); 830254721Semaste } 831254721Semaste} 832254721Semaste 833254721SemasteLineEntry 834254721SemasteSymbolContext::GetFunctionStartLineEntry () const 835254721Semaste{ 836254721Semaste LineEntry line_entry; 837254721Semaste Address start_addr; 838254721Semaste if (block) 839254721Semaste { 840254721Semaste Block *inlined_block = block->GetContainingInlinedBlock(); 841254721Semaste if (inlined_block) 842254721Semaste { 843254721Semaste if (inlined_block->GetStartAddress (start_addr)) 844254721Semaste { 845254721Semaste if (start_addr.CalculateSymbolContextLineEntry (line_entry)) 846254721Semaste return line_entry; 847254721Semaste } 848254721Semaste return LineEntry(); 849254721Semaste } 850254721Semaste } 851254721Semaste 852254721Semaste if (function) 853254721Semaste { 854254721Semaste if (function->GetAddressRange().GetBaseAddress().CalculateSymbolContextLineEntry(line_entry)) 855254721Semaste return line_entry; 856254721Semaste } 857254721Semaste return LineEntry(); 858254721Semaste} 859254721Semaste 860254721Semaste//---------------------------------------------------------------------- 861254721Semaste// 862254721Semaste// SymbolContextSpecifier 863254721Semaste// 864254721Semaste//---------------------------------------------------------------------- 865254721Semaste 866254721SemasteSymbolContextSpecifier::SymbolContextSpecifier (const TargetSP &target_sp) : 867254721Semaste m_target_sp (target_sp), 868254721Semaste m_module_spec (), 869254721Semaste m_module_sp (), 870254721Semaste m_file_spec_ap (), 871254721Semaste m_start_line (0), 872254721Semaste m_end_line (0), 873254721Semaste m_function_spec (), 874254721Semaste m_class_name (), 875254721Semaste m_address_range_ap (), 876254721Semaste m_type (eNothingSpecified) 877254721Semaste{ 878254721Semaste} 879254721Semaste 880254721SemasteSymbolContextSpecifier::~SymbolContextSpecifier() 881254721Semaste{ 882254721Semaste} 883254721Semaste 884254721Semastebool 885254721SemasteSymbolContextSpecifier::AddLineSpecification (uint32_t line_no, SpecificationType type) 886254721Semaste{ 887254721Semaste bool return_value = true; 888254721Semaste switch (type) 889254721Semaste { 890254721Semaste case eNothingSpecified: 891254721Semaste Clear(); 892254721Semaste break; 893254721Semaste case eLineStartSpecified: 894254721Semaste m_start_line = line_no; 895254721Semaste m_type |= eLineStartSpecified; 896254721Semaste break; 897254721Semaste case eLineEndSpecified: 898254721Semaste m_end_line = line_no; 899254721Semaste m_type |= eLineEndSpecified; 900254721Semaste break; 901254721Semaste default: 902254721Semaste return_value = false; 903254721Semaste break; 904254721Semaste } 905254721Semaste return return_value; 906254721Semaste} 907254721Semaste 908254721Semastebool 909254721SemasteSymbolContextSpecifier::AddSpecification (const char *spec_string, SpecificationType type) 910254721Semaste{ 911254721Semaste bool return_value = true; 912254721Semaste switch (type) 913254721Semaste { 914254721Semaste case eNothingSpecified: 915254721Semaste Clear(); 916254721Semaste break; 917254721Semaste case eModuleSpecified: 918254721Semaste { 919254721Semaste // See if we can find the Module, if so stick it in the SymbolContext. 920254721Semaste FileSpec module_file_spec(spec_string, false); 921254721Semaste ModuleSpec module_spec (module_file_spec); 922254721Semaste lldb::ModuleSP module_sp (m_target_sp->GetImages().FindFirstModule (module_spec)); 923254721Semaste m_type |= eModuleSpecified; 924254721Semaste if (module_sp) 925254721Semaste m_module_sp = module_sp; 926254721Semaste else 927254721Semaste m_module_spec.assign (spec_string); 928254721Semaste } 929254721Semaste break; 930254721Semaste case eFileSpecified: 931254721Semaste // CompUnits can't necessarily be resolved here, since an inlined function might show up in 932254721Semaste // a number of CompUnits. Instead we just convert to a FileSpec and store it away. 933254721Semaste m_file_spec_ap.reset (new FileSpec (spec_string, false)); 934254721Semaste m_type |= eFileSpecified; 935254721Semaste break; 936254721Semaste case eLineStartSpecified: 937288943Sdim m_start_line = StringConvert::ToSInt32(spec_string, 0, 0, &return_value); 938254721Semaste if (return_value) 939254721Semaste m_type |= eLineStartSpecified; 940254721Semaste break; 941254721Semaste case eLineEndSpecified: 942288943Sdim m_end_line = StringConvert::ToSInt32(spec_string, 0, 0, &return_value); 943254721Semaste if (return_value) 944254721Semaste m_type |= eLineEndSpecified; 945254721Semaste break; 946254721Semaste case eFunctionSpecified: 947254721Semaste m_function_spec.assign(spec_string); 948254721Semaste m_type |= eFunctionSpecified; 949254721Semaste break; 950254721Semaste case eClassOrNamespaceSpecified: 951254721Semaste Clear(); 952254721Semaste m_class_name.assign (spec_string); 953254721Semaste m_type = eClassOrNamespaceSpecified; 954254721Semaste break; 955254721Semaste case eAddressRangeSpecified: 956254721Semaste // Not specified yet... 957254721Semaste break; 958254721Semaste } 959254721Semaste 960254721Semaste return return_value; 961254721Semaste} 962254721Semaste 963254721Semastevoid 964254721SemasteSymbolContextSpecifier::Clear() 965254721Semaste{ 966254721Semaste m_module_spec.clear(); 967254721Semaste m_file_spec_ap.reset(); 968254721Semaste m_function_spec.clear(); 969254721Semaste m_class_name.clear(); 970254721Semaste m_start_line = 0; 971254721Semaste m_end_line = 0; 972254721Semaste m_address_range_ap.reset(); 973254721Semaste 974254721Semaste m_type = eNothingSpecified; 975254721Semaste} 976254721Semaste 977254721Semastebool 978254721SemasteSymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc) 979254721Semaste{ 980254721Semaste if (m_type == eNothingSpecified) 981254721Semaste return true; 982254721Semaste 983254721Semaste if (m_target_sp.get() != sc.target_sp.get()) 984254721Semaste return false; 985254721Semaste 986254721Semaste if (m_type & eModuleSpecified) 987254721Semaste { 988254721Semaste if (sc.module_sp) 989254721Semaste { 990276479Sdim if (m_module_sp.get() != nullptr) 991254721Semaste { 992254721Semaste if (m_module_sp.get() != sc.module_sp.get()) 993254721Semaste return false; 994254721Semaste } 995254721Semaste else 996254721Semaste { 997254721Semaste FileSpec module_file_spec (m_module_spec.c_str(), false); 998254721Semaste if (!FileSpec::Equal (module_file_spec, sc.module_sp->GetFileSpec(), false)) 999254721Semaste return false; 1000254721Semaste } 1001254721Semaste } 1002254721Semaste } 1003254721Semaste if (m_type & eFileSpecified) 1004254721Semaste { 1005254721Semaste if (m_file_spec_ap.get()) 1006254721Semaste { 1007254721Semaste // If we don't have a block or a comp_unit, then we aren't going to match a source file. 1008276479Sdim if (sc.block == nullptr && sc.comp_unit == nullptr) 1009254721Semaste return false; 1010254721Semaste 1011254721Semaste // Check if the block is present, and if so is it inlined: 1012254721Semaste bool was_inlined = false; 1013276479Sdim if (sc.block != nullptr) 1014254721Semaste { 1015254721Semaste const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo(); 1016276479Sdim if (inline_info != nullptr) 1017254721Semaste { 1018254721Semaste was_inlined = true; 1019254721Semaste if (!FileSpec::Equal (inline_info->GetDeclaration().GetFile(), *(m_file_spec_ap.get()), false)) 1020254721Semaste return false; 1021254721Semaste } 1022254721Semaste } 1023254721Semaste 1024254721Semaste // Next check the comp unit, but only if the SymbolContext was not inlined. 1025276479Sdim if (!was_inlined && sc.comp_unit != nullptr) 1026254721Semaste { 1027254721Semaste if (!FileSpec::Equal (*(sc.comp_unit), *(m_file_spec_ap.get()), false)) 1028254721Semaste return false; 1029254721Semaste } 1030254721Semaste } 1031254721Semaste } 1032254721Semaste if (m_type & eLineStartSpecified 1033254721Semaste || m_type & eLineEndSpecified) 1034254721Semaste { 1035254721Semaste if (sc.line_entry.line < m_start_line || sc.line_entry.line > m_end_line) 1036254721Semaste return false; 1037254721Semaste } 1038254721Semaste 1039254721Semaste if (m_type & eFunctionSpecified) 1040254721Semaste { 1041254721Semaste // First check the current block, and if it is inlined, get the inlined function name: 1042254721Semaste bool was_inlined = false; 1043254721Semaste ConstString func_name(m_function_spec.c_str()); 1044254721Semaste 1045276479Sdim if (sc.block != nullptr) 1046254721Semaste { 1047254721Semaste const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo(); 1048276479Sdim if (inline_info != nullptr) 1049254721Semaste { 1050254721Semaste was_inlined = true; 1051254721Semaste const Mangled &name = inline_info->GetMangled(); 1052288943Sdim if (!name.NameMatches (func_name, sc.function->GetLanguage())) 1053254721Semaste return false; 1054254721Semaste } 1055254721Semaste } 1056254721Semaste // If it wasn't inlined, check the name in the function or symbol: 1057254721Semaste if (!was_inlined) 1058254721Semaste { 1059276479Sdim if (sc.function != nullptr) 1060254721Semaste { 1061288943Sdim if (!sc.function->GetMangled().NameMatches(func_name, sc.function->GetLanguage())) 1062254721Semaste return false; 1063254721Semaste } 1064276479Sdim else if (sc.symbol != nullptr) 1065254721Semaste { 1066296417Sdim if (!sc.symbol->GetMangled().NameMatches(func_name, sc.symbol->GetLanguage())) 1067254721Semaste return false; 1068254721Semaste } 1069254721Semaste } 1070254721Semaste 1071254721Semaste 1072254721Semaste } 1073254721Semaste 1074254721Semaste return true; 1075254721Semaste} 1076254721Semaste 1077254721Semastebool 1078254721SemasteSymbolContextSpecifier::AddressMatches(lldb::addr_t addr) 1079254721Semaste{ 1080254721Semaste if (m_type & eAddressRangeSpecified) 1081254721Semaste { 1082254721Semaste 1083254721Semaste } 1084254721Semaste else 1085254721Semaste { 1086276479Sdim Address match_address (addr, nullptr); 1087254721Semaste SymbolContext sc; 1088254721Semaste m_target_sp->GetImages().ResolveSymbolContextForAddress(match_address, eSymbolContextEverything, sc); 1089254721Semaste return SymbolContextMatches(sc); 1090254721Semaste } 1091254721Semaste return true; 1092254721Semaste} 1093254721Semaste 1094254721Semastevoid 1095254721SemasteSymbolContextSpecifier::GetDescription (Stream *s, lldb::DescriptionLevel level) const 1096254721Semaste{ 1097254721Semaste char path_str[PATH_MAX + 1]; 1098254721Semaste 1099254721Semaste if (m_type == eNothingSpecified) 1100254721Semaste { 1101254721Semaste s->Printf ("Nothing specified.\n"); 1102254721Semaste } 1103254721Semaste 1104254721Semaste if (m_type == eModuleSpecified) 1105254721Semaste { 1106254721Semaste s->Indent(); 1107254721Semaste if (m_module_sp) 1108254721Semaste { 1109254721Semaste m_module_sp->GetFileSpec().GetPath (path_str, PATH_MAX); 1110254721Semaste s->Printf ("Module: %s\n", path_str); 1111254721Semaste } 1112254721Semaste else 1113254721Semaste s->Printf ("Module: %s\n", m_module_spec.c_str()); 1114254721Semaste } 1115254721Semaste 1116276479Sdim if (m_type == eFileSpecified && m_file_spec_ap.get() != nullptr) 1117254721Semaste { 1118254721Semaste m_file_spec_ap->GetPath (path_str, PATH_MAX); 1119254721Semaste s->Indent(); 1120254721Semaste s->Printf ("File: %s", path_str); 1121254721Semaste if (m_type == eLineStartSpecified) 1122254721Semaste { 1123276479Sdim s->Printf (" from line %" PRIu64 "", (uint64_t)m_start_line); 1124254721Semaste if (m_type == eLineEndSpecified) 1125276479Sdim s->Printf ("to line %" PRIu64 "", (uint64_t)m_end_line); 1126254721Semaste else 1127254721Semaste s->Printf ("to end"); 1128254721Semaste } 1129254721Semaste else if (m_type == eLineEndSpecified) 1130254721Semaste { 1131276479Sdim s->Printf (" from start to line %" PRIu64 "", (uint64_t)m_end_line); 1132254721Semaste } 1133254721Semaste s->Printf (".\n"); 1134254721Semaste } 1135254721Semaste 1136254721Semaste if (m_type == eLineStartSpecified) 1137254721Semaste { 1138254721Semaste s->Indent(); 1139276479Sdim s->Printf ("From line %" PRIu64 "", (uint64_t)m_start_line); 1140254721Semaste if (m_type == eLineEndSpecified) 1141276479Sdim s->Printf ("to line %" PRIu64 "", (uint64_t)m_end_line); 1142254721Semaste else 1143254721Semaste s->Printf ("to end"); 1144254721Semaste s->Printf (".\n"); 1145254721Semaste } 1146254721Semaste else if (m_type == eLineEndSpecified) 1147254721Semaste { 1148276479Sdim s->Printf ("From start to line %" PRIu64 ".\n", (uint64_t)m_end_line); 1149254721Semaste } 1150254721Semaste 1151254721Semaste if (m_type == eFunctionSpecified) 1152254721Semaste { 1153254721Semaste s->Indent(); 1154254721Semaste s->Printf ("Function: %s.\n", m_function_spec.c_str()); 1155254721Semaste } 1156254721Semaste 1157254721Semaste if (m_type == eClassOrNamespaceSpecified) 1158254721Semaste { 1159254721Semaste s->Indent(); 1160254721Semaste s->Printf ("Class name: %s.\n", m_class_name.c_str()); 1161254721Semaste } 1162254721Semaste 1163276479Sdim if (m_type == eAddressRangeSpecified && m_address_range_ap.get() != nullptr) 1164254721Semaste { 1165254721Semaste s->Indent(); 1166254721Semaste s->PutCString ("Address range: "); 1167254721Semaste m_address_range_ap->Dump (s, m_target_sp.get(), Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress); 1168254721Semaste s->PutCString ("\n"); 1169254721Semaste } 1170254721Semaste} 1171254721Semaste 1172254721Semaste//---------------------------------------------------------------------- 1173254721Semaste// 1174254721Semaste// SymbolContextList 1175254721Semaste// 1176254721Semaste//---------------------------------------------------------------------- 1177254721Semaste 1178254721Semaste 1179254721SemasteSymbolContextList::SymbolContextList() : 1180254721Semaste m_symbol_contexts() 1181254721Semaste{ 1182254721Semaste} 1183254721Semaste 1184254721SemasteSymbolContextList::~SymbolContextList() 1185254721Semaste{ 1186254721Semaste} 1187254721Semaste 1188254721Semastevoid 1189254721SemasteSymbolContextList::Append(const SymbolContext& sc) 1190254721Semaste{ 1191254721Semaste m_symbol_contexts.push_back(sc); 1192254721Semaste} 1193254721Semaste 1194254721Semastevoid 1195254721SemasteSymbolContextList::Append (const SymbolContextList& sc_list) 1196254721Semaste{ 1197254721Semaste collection::const_iterator pos, end = sc_list.m_symbol_contexts.end(); 1198254721Semaste for (pos = sc_list.m_symbol_contexts.begin(); pos != end; ++pos) 1199254721Semaste m_symbol_contexts.push_back (*pos); 1200254721Semaste} 1201254721Semaste 1202254721Semaste 1203254721Semasteuint32_t 1204254721SemasteSymbolContextList::AppendIfUnique (const SymbolContextList& sc_list, bool merge_symbol_into_function) 1205254721Semaste{ 1206254721Semaste uint32_t unique_sc_add_count = 0; 1207254721Semaste collection::const_iterator pos, end = sc_list.m_symbol_contexts.end(); 1208254721Semaste for (pos = sc_list.m_symbol_contexts.begin(); pos != end; ++pos) 1209254721Semaste { 1210254721Semaste if (AppendIfUnique (*pos, merge_symbol_into_function)) 1211254721Semaste ++unique_sc_add_count; 1212254721Semaste } 1213254721Semaste return unique_sc_add_count; 1214254721Semaste} 1215254721Semaste 1216254721Semastebool 1217254721SemasteSymbolContextList::AppendIfUnique (const SymbolContext& sc, bool merge_symbol_into_function) 1218254721Semaste{ 1219254721Semaste collection::iterator pos, end = m_symbol_contexts.end(); 1220254721Semaste for (pos = m_symbol_contexts.begin(); pos != end; ++pos) 1221254721Semaste { 1222254721Semaste if (*pos == sc) 1223254721Semaste return false; 1224254721Semaste } 1225254721Semaste if (merge_symbol_into_function 1226276479Sdim && sc.symbol != nullptr 1227276479Sdim && sc.comp_unit == nullptr 1228276479Sdim && sc.function == nullptr 1229276479Sdim && sc.block == nullptr 1230254721Semaste && sc.line_entry.IsValid() == false) 1231254721Semaste { 1232254721Semaste if (sc.symbol->ValueIsAddress()) 1233254721Semaste { 1234254721Semaste for (pos = m_symbol_contexts.begin(); pos != end; ++pos) 1235254721Semaste { 1236254721Semaste // Don't merge symbols into inlined function symbol contexts 1237254721Semaste if (pos->block && pos->block->GetContainingInlinedBlock()) 1238254721Semaste continue; 1239254721Semaste 1240254721Semaste if (pos->function) 1241254721Semaste { 1242288943Sdim if (pos->function->GetAddressRange().GetBaseAddress() == sc.symbol->GetAddressRef()) 1243254721Semaste { 1244254721Semaste // Do we already have a function with this symbol? 1245254721Semaste if (pos->symbol == sc.symbol) 1246254721Semaste return false; 1247276479Sdim if (pos->symbol == nullptr) 1248254721Semaste { 1249254721Semaste pos->symbol = sc.symbol; 1250254721Semaste return false; 1251254721Semaste } 1252254721Semaste } 1253254721Semaste } 1254254721Semaste } 1255254721Semaste } 1256254721Semaste } 1257254721Semaste m_symbol_contexts.push_back(sc); 1258254721Semaste return true; 1259254721Semaste} 1260254721Semaste 1261254721Semastebool 1262254721SemasteSymbolContextList::MergeSymbolContextIntoFunctionContext (const SymbolContext& symbol_sc, 1263254721Semaste uint32_t start_idx, 1264254721Semaste uint32_t stop_idx) 1265254721Semaste{ 1266276479Sdim if (symbol_sc.symbol != nullptr 1267276479Sdim && symbol_sc.comp_unit == nullptr 1268276479Sdim && symbol_sc.function == nullptr 1269276479Sdim && symbol_sc.block == nullptr 1270254721Semaste && symbol_sc.line_entry.IsValid() == false) 1271254721Semaste { 1272254721Semaste if (symbol_sc.symbol->ValueIsAddress()) 1273254721Semaste { 1274254721Semaste const size_t end = std::min<size_t>(m_symbol_contexts.size(), stop_idx); 1275254721Semaste for (size_t i=start_idx; i<end; ++i) 1276254721Semaste { 1277254721Semaste const SymbolContext &function_sc = m_symbol_contexts[i]; 1278254721Semaste // Don't merge symbols into inlined function symbol contexts 1279254721Semaste if (function_sc.block && function_sc.block->GetContainingInlinedBlock()) 1280254721Semaste continue; 1281254721Semaste 1282254721Semaste if (function_sc.function) 1283254721Semaste { 1284288943Sdim if (function_sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddressRef()) 1285254721Semaste { 1286254721Semaste // Do we already have a function with this symbol? 1287254721Semaste if (function_sc.symbol == symbol_sc.symbol) 1288254721Semaste return true; // Already have a symbol context with this symbol, return true 1289254721Semaste 1290276479Sdim if (function_sc.symbol == nullptr) 1291254721Semaste { 1292254721Semaste // We successfully merged this symbol into an existing symbol context 1293254721Semaste m_symbol_contexts[i].symbol = symbol_sc.symbol; 1294254721Semaste return true; 1295254721Semaste } 1296254721Semaste } 1297254721Semaste } 1298254721Semaste } 1299254721Semaste } 1300254721Semaste } 1301254721Semaste return false; 1302254721Semaste} 1303254721Semaste 1304254721Semastevoid 1305254721SemasteSymbolContextList::Clear() 1306254721Semaste{ 1307254721Semaste m_symbol_contexts.clear(); 1308254721Semaste} 1309254721Semaste 1310254721Semastevoid 1311254721SemasteSymbolContextList::Dump(Stream *s, Target *target) const 1312254721Semaste{ 1313254721Semaste 1314296417Sdim *s << this << ": "; 1315254721Semaste s->Indent(); 1316254721Semaste s->PutCString("SymbolContextList"); 1317254721Semaste s->EOL(); 1318254721Semaste s->IndentMore(); 1319254721Semaste 1320254721Semaste collection::const_iterator pos, end = m_symbol_contexts.end(); 1321254721Semaste for (pos = m_symbol_contexts.begin(); pos != end; ++pos) 1322254721Semaste { 1323254721Semaste //pos->Dump(s, target); 1324254721Semaste pos->GetDescription(s, eDescriptionLevelVerbose, target); 1325254721Semaste } 1326254721Semaste s->IndentLess(); 1327254721Semaste} 1328254721Semaste 1329254721Semastebool 1330254721SemasteSymbolContextList::GetContextAtIndex(size_t idx, SymbolContext& sc) const 1331254721Semaste{ 1332254721Semaste if (idx < m_symbol_contexts.size()) 1333254721Semaste { 1334254721Semaste sc = m_symbol_contexts[idx]; 1335254721Semaste return true; 1336254721Semaste } 1337254721Semaste return false; 1338254721Semaste} 1339254721Semaste 1340254721Semastebool 1341254721SemasteSymbolContextList::GetLastContext(SymbolContext& sc) const 1342254721Semaste{ 1343254721Semaste if (!m_symbol_contexts.empty()) 1344254721Semaste { 1345254721Semaste sc = m_symbol_contexts.back(); 1346254721Semaste return true; 1347254721Semaste } 1348254721Semaste return false; 1349254721Semaste} 1350254721Semaste 1351254721Semastebool 1352254721SemasteSymbolContextList::RemoveContextAtIndex (size_t idx) 1353254721Semaste{ 1354254721Semaste if (idx < m_symbol_contexts.size()) 1355254721Semaste { 1356254721Semaste m_symbol_contexts.erase(m_symbol_contexts.begin() + idx); 1357254721Semaste return true; 1358254721Semaste } 1359254721Semaste return false; 1360254721Semaste} 1361254721Semaste 1362254721Semasteuint32_t 1363254721SemasteSymbolContextList::GetSize() const 1364254721Semaste{ 1365254721Semaste return m_symbol_contexts.size(); 1366254721Semaste} 1367254721Semaste 1368254721Semasteuint32_t 1369254721SemasteSymbolContextList::NumLineEntriesWithLine (uint32_t line) const 1370254721Semaste{ 1371254721Semaste uint32_t match_count = 0; 1372254721Semaste const size_t size = m_symbol_contexts.size(); 1373254721Semaste for (size_t idx = 0; idx<size; ++idx) 1374254721Semaste { 1375254721Semaste if (m_symbol_contexts[idx].line_entry.line == line) 1376254721Semaste ++match_count; 1377254721Semaste } 1378254721Semaste return match_count; 1379254721Semaste} 1380254721Semaste 1381254721Semastevoid 1382254721SemasteSymbolContextList::GetDescription(Stream *s, 1383254721Semaste lldb::DescriptionLevel level, 1384254721Semaste Target *target) const 1385254721Semaste{ 1386254721Semaste const size_t size = m_symbol_contexts.size(); 1387254721Semaste for (size_t idx = 0; idx<size; ++idx) 1388254721Semaste m_symbol_contexts[idx].GetDescription (s, level, target); 1389254721Semaste} 1390254721Semaste 1391254721Semastebool 1392254721Semastelldb_private::operator== (const SymbolContextList& lhs, const SymbolContextList& rhs) 1393254721Semaste{ 1394254721Semaste const uint32_t size = lhs.GetSize(); 1395254721Semaste if (size != rhs.GetSize()) 1396254721Semaste return false; 1397254721Semaste 1398254721Semaste SymbolContext lhs_sc; 1399254721Semaste SymbolContext rhs_sc; 1400254721Semaste for (uint32_t i=0; i<size; ++i) 1401254721Semaste { 1402254721Semaste lhs.GetContextAtIndex(i, lhs_sc); 1403254721Semaste rhs.GetContextAtIndex(i, rhs_sc); 1404254721Semaste if (lhs_sc != rhs_sc) 1405254721Semaste return false; 1406254721Semaste } 1407254721Semaste return true; 1408254721Semaste} 1409254721Semaste 1410254721Semastebool 1411254721Semastelldb_private::operator!= (const SymbolContextList& lhs, const SymbolContextList& rhs) 1412254721Semaste{ 1413254721Semaste return !(lhs == rhs); 1414254721Semaste} 1415254721Semaste 1416