1 //===-- SymbolContext.cpp ---------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/Symbol/SymbolContext.h" 11 12 #include "lldb/Core/Log.h" 13 #include "lldb/Core/Module.h" 14 #include "lldb/Interpreter/Args.h" 15 #include "lldb/Symbol/CompileUnit.h" 16 #include "lldb/Symbol/ObjectFile.h" 17 #include "lldb/Symbol/Symbol.h" 18 #include "lldb/Symbol/SymbolVendor.h" 19 #include "lldb/Target/Target.h" 20 21 using namespace lldb; 22 using namespace lldb_private; 23 24 SymbolContext::SymbolContext() : 25 target_sp (), 26 module_sp (), 27 comp_unit (NULL), 28 function (NULL), 29 block (NULL), 30 line_entry (), 31 symbol (NULL) 32 { 33 } 34 35 SymbolContext::SymbolContext(const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) : 36 target_sp (), 37 module_sp (m), 38 comp_unit (cu), 39 function (f), 40 block (b), 41 line_entry (), 42 symbol (s) 43 { 44 if (le) 45 line_entry = *le; 46 } 47 48 SymbolContext::SymbolContext(const TargetSP &t, const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) : 49 target_sp (t), 50 module_sp (m), 51 comp_unit (cu), 52 function (f), 53 block (b), 54 line_entry (), 55 symbol (s) 56 { 57 if (le) 58 line_entry = *le; 59 } 60 61 SymbolContext::SymbolContext(const SymbolContext& rhs) : 62 target_sp (rhs.target_sp), 63 module_sp (rhs.module_sp), 64 comp_unit (rhs.comp_unit), 65 function (rhs.function), 66 block (rhs.block), 67 line_entry (rhs.line_entry), 68 symbol (rhs.symbol) 69 { 70 } 71 72 73 SymbolContext::SymbolContext (SymbolContextScope *sc_scope) : 74 target_sp (), 75 module_sp (), 76 comp_unit (NULL), 77 function (NULL), 78 block (NULL), 79 line_entry (), 80 symbol (NULL) 81 { 82 sc_scope->CalculateSymbolContext (this); 83 } 84 85 SymbolContext::~SymbolContext () 86 { 87 } 88 89 const SymbolContext& 90 SymbolContext::operator= (const SymbolContext& rhs) 91 { 92 if (this != &rhs) 93 { 94 target_sp = rhs.target_sp; 95 module_sp = rhs.module_sp; 96 comp_unit = rhs.comp_unit; 97 function = rhs.function; 98 block = rhs.block; 99 line_entry = rhs.line_entry; 100 symbol = rhs.symbol; 101 } 102 return *this; 103 } 104 105 void 106 SymbolContext::Clear() 107 { 108 target_sp.reset(); 109 module_sp.reset(); 110 comp_unit = NULL; 111 function = NULL; 112 block = NULL; 113 line_entry.Clear(); 114 symbol = NULL; 115 } 116 117 bool 118 SymbolContext::DumpStopContext 119 ( 120 Stream *s, 121 ExecutionContextScope *exe_scope, 122 const Address &addr, 123 bool show_fullpaths, 124 bool show_module, 125 bool show_inlined_frames 126 ) const 127 { 128 bool dumped_something = false; 129 if (show_module && module_sp) 130 { 131 if (show_fullpaths) 132 *s << module_sp->GetFileSpec(); 133 else 134 *s << module_sp->GetFileSpec().GetFilename(); 135 s->PutChar('`'); 136 dumped_something = true; 137 } 138 139 if (function != NULL) 140 { 141 SymbolContext inline_parent_sc; 142 Address inline_parent_addr; 143 if (function->GetMangled().GetName()) 144 { 145 dumped_something = true; 146 function->GetMangled().GetName().Dump(s); 147 } 148 149 if (addr.IsValid()) 150 { 151 const addr_t function_offset = addr.GetOffset() - function->GetAddressRange().GetBaseAddress().GetOffset(); 152 if (function_offset) 153 { 154 dumped_something = true; 155 s->Printf(" + %llu", function_offset); 156 } 157 } 158 159 if (GetParentOfInlinedScope (addr, inline_parent_sc, inline_parent_addr)) 160 { 161 dumped_something = true; 162 Block *inlined_block = block->GetContainingInlinedBlock(); 163 const InlineFunctionInfo* inlined_block_info = inlined_block->GetInlinedFunctionInfo(); 164 s->Printf (" [inlined] %s", inlined_block_info->GetName().GetCString()); 165 166 lldb_private::AddressRange block_range; 167 if (inlined_block->GetRangeContainingAddress(addr, block_range)) 168 { 169 const addr_t inlined_function_offset = addr.GetOffset() - block_range.GetBaseAddress().GetOffset(); 170 if (inlined_function_offset) 171 { 172 s->Printf(" + %llu", inlined_function_offset); 173 } 174 } 175 const Declaration &call_site = inlined_block_info->GetCallSite(); 176 if (call_site.IsValid()) 177 { 178 s->PutCString(" at "); 179 call_site.DumpStopContext (s, show_fullpaths); 180 } 181 if (show_inlined_frames) 182 { 183 s->EOL(); 184 s->Indent(); 185 return inline_parent_sc.DumpStopContext (s, exe_scope, inline_parent_addr, show_fullpaths, show_module, show_inlined_frames); 186 } 187 } 188 else 189 { 190 if (line_entry.IsValid()) 191 { 192 dumped_something = true; 193 s->PutCString(" at "); 194 if (line_entry.DumpStopContext(s, show_fullpaths)) 195 dumped_something = true; 196 } 197 } 198 } 199 else if (symbol != NULL) 200 { 201 if (symbol->GetMangled().GetName()) 202 { 203 dumped_something = true; 204 symbol->GetMangled().GetName().Dump(s); 205 } 206 207 if (addr.IsValid() && symbol->GetAddressRangePtr()) 208 { 209 const addr_t symbol_offset = addr.GetOffset() - symbol->GetAddressRangePtr()->GetBaseAddress().GetOffset(); 210 if (symbol_offset) 211 { 212 dumped_something = true; 213 s->Printf(" + %llu", symbol_offset); 214 } 215 } 216 } 217 else if (addr.IsValid()) 218 { 219 addr.Dump(s, exe_scope, Address::DumpStyleModuleWithFileAddress); 220 dumped_something = true; 221 } 222 return dumped_something; 223 } 224 225 void 226 SymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target) const 227 { 228 if (module_sp) 229 { 230 s->Indent(" Module: file = \""); 231 module_sp->GetFileSpec().Dump(s); 232 *s << '"'; 233 if (module_sp->GetArchitecture().IsValid()) 234 s->Printf (", arch = \"%s\"", module_sp->GetArchitecture().GetArchitectureName()); 235 s->EOL(); 236 } 237 238 if (comp_unit != NULL) 239 { 240 s->Indent("CompileUnit: "); 241 comp_unit->GetDescription (s, level); 242 s->EOL(); 243 } 244 245 if (function != NULL) 246 { 247 s->Indent(" Function: "); 248 function->GetDescription (s, level, target); 249 s->EOL(); 250 251 Type *func_type = function->GetType(); 252 if (func_type) 253 { 254 s->Indent(" FuncType: "); 255 func_type->GetDescription (s, level, false); 256 s->EOL(); 257 } 258 } 259 260 if (block != NULL) 261 { 262 std::vector<Block *> blocks; 263 blocks.push_back (block); 264 Block *parent_block = block->GetParent(); 265 266 while (parent_block) 267 { 268 blocks.push_back (parent_block); 269 parent_block = parent_block->GetParent(); 270 } 271 std::vector<Block *>::reverse_iterator pos; 272 std::vector<Block *>::reverse_iterator begin = blocks.rbegin(); 273 std::vector<Block *>::reverse_iterator end = blocks.rend(); 274 for (pos = begin; pos != end; ++pos) 275 { 276 if (pos == begin) 277 s->Indent(" Blocks: "); 278 else 279 s->Indent(" "); 280 (*pos)->GetDescription(s, function, level, target); 281 s->EOL(); 282 } 283 } 284 285 if (line_entry.IsValid()) 286 { 287 s->Indent(" LineEntry: "); 288 line_entry.GetDescription (s, level, comp_unit, target, false); 289 s->EOL(); 290 } 291 292 if (symbol != NULL) 293 { 294 s->Indent(" Symbol: "); 295 symbol->GetDescription(s, level, target); 296 s->EOL(); 297 } 298 } 299 300 uint32_t 301 SymbolContext::GetResolvedMask () const 302 { 303 uint32_t resolved_mask = 0; 304 if (target_sp) resolved_mask |= eSymbolContextTarget; 305 if (module_sp) resolved_mask |= eSymbolContextModule; 306 if (comp_unit) resolved_mask |= eSymbolContextCompUnit; 307 if (function) resolved_mask |= eSymbolContextFunction; 308 if (block) resolved_mask |= eSymbolContextBlock; 309 if (line_entry.IsValid()) resolved_mask |= eSymbolContextLineEntry; 310 if (symbol) resolved_mask |= eSymbolContextSymbol; 311 return resolved_mask; 312 } 313 314 315 void 316 SymbolContext::Dump(Stream *s, Target *target) const 317 { 318 *s << (void *)this << ": "; 319 s->Indent(); 320 s->PutCString("SymbolContext"); 321 s->IndentMore(); 322 s->EOL(); 323 s->IndentMore(); 324 s->Indent(); 325 *s << "Module = " << (void *)module_sp.get() << ' '; 326 if (module_sp) 327 module_sp->GetFileSpec().Dump(s); 328 s->EOL(); 329 s->Indent(); 330 *s << "CompileUnit = " << (void *)comp_unit; 331 if (comp_unit != NULL) 332 *s << " {0x" << comp_unit->GetID() << "} " << *(static_cast<FileSpec*> (comp_unit)); 333 s->EOL(); 334 s->Indent(); 335 *s << "Function = " << (void *)function; 336 if (function != NULL) 337 { 338 *s << " {0x" << function->GetID() << "} " << function->GetType()->GetName() << ", address-range = "; 339 function->GetAddressRange().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress); 340 s->EOL(); 341 s->Indent(); 342 Type* func_type = function->GetType(); 343 if (func_type) 344 { 345 *s << " Type = "; 346 func_type->Dump (s, false); 347 } 348 } 349 s->EOL(); 350 s->Indent(); 351 *s << "Block = " << (void *)block; 352 if (block != NULL) 353 *s << " {0x" << block->GetID() << '}'; 354 // Dump the block and pass it a negative depth to we print all the parent blocks 355 //if (block != NULL) 356 // block->Dump(s, function->GetFileAddress(), INT_MIN); 357 s->EOL(); 358 s->Indent(); 359 *s << "LineEntry = "; 360 line_entry.Dump (s, target, true, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, true); 361 s->EOL(); 362 s->Indent(); 363 *s << "Symbol = " << (void *)symbol; 364 if (symbol != NULL && symbol->GetMangled()) 365 *s << ' ' << symbol->GetMangled().GetName().AsCString(); 366 s->EOL(); 367 s->IndentLess(); 368 s->IndentLess(); 369 } 370 371 bool 372 lldb_private::operator== (const SymbolContext& lhs, const SymbolContext& rhs) 373 { 374 return lhs.function == rhs.function 375 && lhs.symbol == rhs.symbol 376 && lhs.module_sp.get() == rhs.module_sp.get() 377 && lhs.comp_unit == rhs.comp_unit 378 && lhs.target_sp.get() == rhs.target_sp.get() 379 && LineEntry::Compare(lhs.line_entry, rhs.line_entry) == 0; 380 } 381 382 bool 383 lldb_private::operator!= (const SymbolContext& lhs, const SymbolContext& rhs) 384 { 385 return lhs.function != rhs.function 386 || lhs.symbol != rhs.symbol 387 || lhs.module_sp.get() != rhs.module_sp.get() 388 || lhs.comp_unit != rhs.comp_unit 389 || lhs.target_sp.get() != rhs.target_sp.get() 390 || LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0; 391 } 392 393 bool 394 SymbolContext::GetAddressRange (uint32_t scope, 395 uint32_t range_idx, 396 bool use_inline_block_range, 397 AddressRange &range) const 398 { 399 if ((scope & eSymbolContextLineEntry) && line_entry.IsValid()) 400 { 401 range = line_entry.range; 402 return true; 403 } 404 405 if ((scope & eSymbolContextBlock) && (block != NULL)) 406 { 407 if (use_inline_block_range) 408 { 409 Block *inline_block = block->GetContainingInlinedBlock(); 410 if (inline_block) 411 return inline_block->GetRangeAtIndex (range_idx, range); 412 } 413 else 414 { 415 return block->GetRangeAtIndex (range_idx, range); 416 } 417 } 418 419 if ((scope & eSymbolContextFunction) && (function != NULL)) 420 { 421 if (range_idx == 0) 422 { 423 range = function->GetAddressRange(); 424 return true; 425 } 426 } 427 428 if ((scope & eSymbolContextSymbol) && (symbol != NULL) && (symbol->GetAddressRangePtr() != NULL)) 429 { 430 if (range_idx == 0) 431 { 432 range = *symbol->GetAddressRangePtr(); 433 434 if (range.GetByteSize() == 0) 435 { 436 if (module_sp) 437 { 438 ObjectFile *objfile = module_sp->GetObjectFile(); 439 if (objfile) 440 { 441 Symtab *symtab = objfile->GetSymtab(); 442 if (symtab) 443 range.SetByteSize(symtab->CalculateSymbolSize (symbol)); 444 } 445 } 446 } 447 return true; 448 } 449 } 450 range.Clear(); 451 return false; 452 } 453 454 ClangNamespaceDecl 455 SymbolContext::FindNamespace (const ConstString &name) const 456 { 457 ClangNamespaceDecl namespace_decl; 458 if (module_sp) 459 namespace_decl = module_sp->GetSymbolVendor()->FindNamespace (*this, name); 460 return namespace_decl; 461 } 462 463 size_t 464 SymbolContext::FindFunctionsByName (const ConstString &name, 465 bool include_symbols, 466 bool append, 467 SymbolContextList &sc_list) const 468 { 469 if (!append) 470 sc_list.Clear(); 471 472 if (function != NULL) 473 { 474 // FIXME: Look in the class of the current function, if it exists, 475 // for methods matching name. 476 } 477 478 if (module_sp) 479 module_sp->FindFunctions (name, eFunctionNameTypeBase | eFunctionNameTypeFull, include_symbols, true, sc_list); 480 481 if (target_sp) 482 target_sp->GetImages().FindFunctions (name, eFunctionNameTypeBase | eFunctionNameTypeFull, include_symbols, true, sc_list); 483 484 return sc_list.GetSize(); 485 } 486 487 //lldb::VariableSP 488 //SymbolContext::FindVariableByName (const char *name) const 489 //{ 490 // lldb::VariableSP return_value; 491 // return return_value; 492 //} 493 494 lldb::TypeSP 495 SymbolContext::FindTypeByName (const ConstString &name) const 496 { 497 lldb::TypeSP return_value; 498 499 TypeList types; 500 501 if (module_sp && module_sp->FindTypes (*this, name, false, 1, types)) 502 return types.GetTypeAtIndex(0); 503 504 SymbolContext sc_for_global_search; 505 506 sc_for_global_search.target_sp = target_sp; 507 508 if (!return_value.get() && target_sp && target_sp->GetImages().FindTypes (sc_for_global_search, name, false, 1, types)) 509 return types.GetTypeAtIndex(0); 510 511 return return_value; 512 } 513 514 bool 515 SymbolContext::GetParentOfInlinedScope (const Address &curr_frame_pc, 516 SymbolContext &next_frame_sc, 517 Address &next_frame_pc) const 518 { 519 next_frame_sc.Clear(); 520 next_frame_pc.Clear(); 521 522 if (block) 523 { 524 //const addr_t curr_frame_file_addr = curr_frame_pc.GetFileAddress(); 525 526 // In order to get the parent of an inlined function we first need to 527 // see if we are in an inlined block as "this->block" could be an 528 // inlined block, or a parent of "block" could be. So lets check if 529 // this block or one of this blocks parents is an inlined function. 530 Block *curr_inlined_block = block->GetContainingInlinedBlock(); 531 if (curr_inlined_block) 532 { 533 // "this->block" is contained in an inline function block, so to 534 // get the scope above the inlined block, we get the parent of the 535 // inlined block itself 536 Block *next_frame_block = curr_inlined_block->GetParent(); 537 // Now calculate the symbol context of the containing block 538 next_frame_block->CalculateSymbolContext (&next_frame_sc); 539 540 // If we get here we weren't able to find the return line entry using the nesting of the blocks and 541 // the line table. So just use the call site info from our inlined block. 542 543 AddressRange range; 544 bool got_range = curr_inlined_block->GetRangeContainingAddress (curr_frame_pc, range); 545 assert (got_range); 546 // To see there this new frame block it, we need to look at the 547 // call site information from 548 const InlineFunctionInfo* curr_inlined_block_inlined_info = curr_inlined_block->GetInlinedFunctionInfo(); 549 next_frame_pc = range.GetBaseAddress(); 550 next_frame_sc.line_entry.range.GetBaseAddress() = next_frame_pc; 551 next_frame_sc.line_entry.file = curr_inlined_block_inlined_info->GetCallSite().GetFile(); 552 next_frame_sc.line_entry.line = curr_inlined_block_inlined_info->GetCallSite().GetLine(); 553 next_frame_sc.line_entry.column = curr_inlined_block_inlined_info->GetCallSite().GetColumn(); 554 return true; 555 } 556 } 557 558 return false; 559 } 560 561 ConstString 562 SymbolContext::GetFunctionName (Mangled::NamePreference preference) 563 { 564 if (function) 565 { 566 if (block) 567 { 568 Block *inlined_block = block->GetContainingInlinedBlock(); 569 570 if (inlined_block) 571 { 572 const InlineFunctionInfo *inline_info = inlined_block->GetInlinedFunctionInfo(); 573 if (inline_info) 574 return inline_info->GetName(); 575 } 576 } 577 return function->GetMangled().GetName(preference); 578 } 579 else if (symbol && symbol->GetAddressRangePtr()) 580 { 581 return symbol->GetMangled().GetName(preference); 582 } 583 else 584 { 585 // No function, return an empty string. 586 return ConstString(); 587 } 588 } 589 590 //---------------------------------------------------------------------- 591 // 592 // SymbolContextSpecifier 593 // 594 //---------------------------------------------------------------------- 595 596 SymbolContextSpecifier::SymbolContextSpecifier (const TargetSP &target_sp) : 597 m_target_sp (target_sp), 598 m_module_spec (), 599 m_module_sp (), 600 m_file_spec_ap (), 601 m_start_line (0), 602 m_end_line (0), 603 m_function_spec (), 604 m_class_name (), 605 m_address_range_ap (), 606 m_type (eNothingSpecified) 607 { 608 } 609 610 SymbolContextSpecifier::~SymbolContextSpecifier() 611 { 612 } 613 614 bool 615 SymbolContextSpecifier::AddLineSpecification (uint32_t line_no, SpecificationType type) 616 { 617 bool return_value = true; 618 switch (type) 619 { 620 case eNothingSpecified: 621 Clear(); 622 break; 623 case eLineStartSpecified: 624 m_start_line = line_no; 625 m_type |= eLineStartSpecified; 626 break; 627 case eLineEndSpecified: 628 m_end_line = line_no; 629 m_type |= eLineEndSpecified; 630 break; 631 default: 632 return_value = false; 633 break; 634 } 635 return return_value; 636 } 637 638 bool 639 SymbolContextSpecifier::AddSpecification (const char *spec_string, SpecificationType type) 640 { 641 bool return_value = true; 642 switch (type) 643 { 644 case eNothingSpecified: 645 Clear(); 646 break; 647 case eModuleSpecified: 648 { 649 // See if we can find the Module, if so stick it in the SymbolContext. 650 FileSpec module_spec(spec_string, false); 651 lldb::ModuleSP module_sp = m_target_sp->GetImages().FindFirstModuleForFileSpec (module_spec, NULL, NULL); 652 m_type |= eModuleSpecified; 653 if (module_sp) 654 m_module_sp = module_sp; 655 else 656 m_module_spec.assign (spec_string); 657 } 658 break; 659 case eFileSpecified: 660 // CompUnits can't necessarily be resolved here, since an inlined function might show up in 661 // a number of CompUnits. Instead we just convert to a FileSpec and store it away. 662 m_file_spec_ap.reset (new FileSpec (spec_string, false)); 663 m_type |= eFileSpecified; 664 break; 665 case eLineStartSpecified: 666 m_start_line = Args::StringToSInt32(spec_string, 0, 0, &return_value); 667 if (return_value) 668 m_type |= eLineStartSpecified; 669 break; 670 case eLineEndSpecified: 671 m_end_line = Args::StringToSInt32(spec_string, 0, 0, &return_value); 672 if (return_value) 673 m_type |= eLineEndSpecified; 674 break; 675 case eFunctionSpecified: 676 m_function_spec.assign(spec_string); 677 m_type |= eFunctionSpecified; 678 break; 679 case eClassOrNamespaceSpecified: 680 Clear(); 681 m_class_name.assign (spec_string); 682 m_type = eClassOrNamespaceSpecified; 683 break; 684 case eAddressRangeSpecified: 685 // Not specified yet... 686 break; 687 } 688 689 return return_value; 690 } 691 692 void 693 SymbolContextSpecifier::Clear() 694 { 695 m_module_spec.clear(); 696 m_file_spec_ap.reset(); 697 m_function_spec.clear(); 698 m_class_name.clear(); 699 m_start_line = 0; 700 m_end_line = 0; 701 m_address_range_ap.reset(); 702 703 m_type = eNothingSpecified; 704 } 705 706 bool 707 SymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc) 708 { 709 if (m_type == eNothingSpecified) 710 return true; 711 712 if (m_target_sp.get() != sc.target_sp.get()) 713 return false; 714 715 if (m_type & eModuleSpecified) 716 { 717 if (sc.module_sp) 718 { 719 if (m_module_sp.get() != NULL) 720 { 721 if (m_module_sp.get() != sc.module_sp.get()) 722 return false; 723 } 724 else 725 { 726 FileSpec module_file_spec (m_module_spec.c_str(), false); 727 if (!FileSpec::Equal (module_file_spec, sc.module_sp->GetFileSpec(), false)) 728 return false; 729 } 730 } 731 } 732 if (m_type & eFileSpecified) 733 { 734 if (m_file_spec_ap.get()) 735 { 736 // If we don't have a block or a comp_unit, then we aren't going to match a source file. 737 if (sc.block == NULL && sc.comp_unit == NULL) 738 return false; 739 740 // Check if the block is present, and if so is it inlined: 741 bool was_inlined = false; 742 if (sc.block != NULL) 743 { 744 const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo(); 745 if (inline_info != NULL) 746 { 747 was_inlined = true; 748 if (!FileSpec::Equal (inline_info->GetDeclaration().GetFile(), *(m_file_spec_ap.get()), false)) 749 return false; 750 } 751 } 752 753 // Next check the comp unit, but only if the SymbolContext was not inlined. 754 if (!was_inlined && sc.comp_unit != NULL) 755 { 756 if (!FileSpec::Equal (*(sc.comp_unit), *(m_file_spec_ap.get()), false)) 757 return false; 758 } 759 } 760 } 761 if (m_type & eLineStartSpecified 762 || m_type & eLineEndSpecified) 763 { 764 if (sc.line_entry.line < m_start_line || sc.line_entry.line > m_end_line) 765 return false; 766 } 767 768 if (m_type & eFunctionSpecified) 769 { 770 // First check the current block, and if it is inlined, get the inlined function name: 771 bool was_inlined = false; 772 ConstString func_name(m_function_spec.c_str()); 773 774 if (sc.block != NULL) 775 { 776 const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo(); 777 if (inline_info != NULL) 778 { 779 was_inlined = true; 780 const Mangled &name = inline_info->GetMangled(); 781 if (!name.NameMatches (func_name)) 782 return false; 783 } 784 } 785 // If it wasn't inlined, check the name in the function or symbol: 786 if (!was_inlined) 787 { 788 if (sc.function != NULL) 789 { 790 if (!sc.function->GetMangled().NameMatches(func_name)) 791 return false; 792 } 793 else if (sc.symbol != NULL) 794 { 795 if (!sc.symbol->GetMangled().NameMatches(func_name)) 796 return false; 797 } 798 } 799 800 801 } 802 803 return true; 804 } 805 806 bool 807 SymbolContextSpecifier::AddressMatches(lldb::addr_t addr) 808 { 809 if (m_type & eAddressRangeSpecified) 810 { 811 812 } 813 else 814 { 815 Address match_address (addr, NULL); 816 SymbolContext sc; 817 m_target_sp->GetImages().ResolveSymbolContextForAddress(match_address, eSymbolContextEverything, sc); 818 return SymbolContextMatches(sc); 819 } 820 return true; 821 } 822 823 void 824 SymbolContextSpecifier::GetDescription (Stream *s, lldb::DescriptionLevel level) const 825 { 826 char path_str[PATH_MAX + 1]; 827 828 if (m_type == eNothingSpecified) 829 { 830 s->Printf ("Nothing specified.\n"); 831 } 832 833 if (m_type == eModuleSpecified) 834 { 835 s->Indent(); 836 if (m_module_sp) 837 { 838 m_module_sp->GetFileSpec().GetPath (path_str, PATH_MAX); 839 s->Printf ("Module: %s\n", path_str); 840 } 841 else 842 s->Printf ("Module: %s\n", m_module_spec.c_str()); 843 } 844 845 if (m_type == eFileSpecified && m_file_spec_ap.get() != NULL) 846 { 847 m_file_spec_ap->GetPath (path_str, PATH_MAX); 848 s->Indent(); 849 s->Printf ("File: %s", path_str); 850 if (m_type == eLineStartSpecified) 851 { 852 s->Printf (" from line %lu", m_start_line); 853 if (m_type == eLineEndSpecified) 854 s->Printf ("to line %lu", m_end_line); 855 else 856 s->Printf ("to end"); 857 } 858 else if (m_type == eLineEndSpecified) 859 { 860 s->Printf (" from start to line %ld", m_end_line); 861 } 862 s->Printf (".\n"); 863 } 864 865 if (m_type == eLineStartSpecified) 866 { 867 s->Indent(); 868 s->Printf ("From line %lu", m_start_line); 869 if (m_type == eLineEndSpecified) 870 s->Printf ("to line %lu", m_end_line); 871 else 872 s->Printf ("to end"); 873 s->Printf (".\n"); 874 } 875 else if (m_type == eLineEndSpecified) 876 { 877 s->Printf ("From start to line %ld.\n", m_end_line); 878 } 879 880 if (m_type == eFunctionSpecified) 881 { 882 s->Indent(); 883 s->Printf ("Function: %s.\n", m_function_spec.c_str()); 884 } 885 886 if (m_type == eClassOrNamespaceSpecified) 887 { 888 s->Indent(); 889 s->Printf ("Class name: %s.\n", m_class_name.c_str()); 890 } 891 892 if (m_type == eAddressRangeSpecified && m_address_range_ap.get() != NULL) 893 { 894 s->Indent(); 895 s->PutCString ("Address range: "); 896 m_address_range_ap->Dump (s, m_target_sp.get(), Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress); 897 s->PutCString ("\n"); 898 } 899 } 900 901 //---------------------------------------------------------------------- 902 // 903 // SymbolContextList 904 // 905 //---------------------------------------------------------------------- 906 907 908 SymbolContextList::SymbolContextList() : 909 m_symbol_contexts() 910 { 911 } 912 913 SymbolContextList::~SymbolContextList() 914 { 915 } 916 917 void 918 SymbolContextList::Append(const SymbolContext& sc) 919 { 920 m_symbol_contexts.push_back(sc); 921 } 922 923 bool 924 SymbolContextList::AppendIfUnique (const SymbolContext& sc, bool merge_symbol_into_function) 925 { 926 collection::iterator pos, end = m_symbol_contexts.end(); 927 for (pos = m_symbol_contexts.begin(); pos != end; ++pos) 928 { 929 if (*pos == sc) 930 return false; 931 } 932 if (merge_symbol_into_function 933 && sc.symbol != NULL 934 && sc.comp_unit == NULL 935 && sc.function == NULL 936 && sc.block == NULL 937 && sc.line_entry.IsValid() == false) 938 { 939 const AddressRange *symbol_range = sc.symbol->GetAddressRangePtr(); 940 if (symbol_range) 941 { 942 for (pos = m_symbol_contexts.begin(); pos != end; ++pos) 943 { 944 if (pos->function) 945 { 946 if (pos->function->GetAddressRange().GetBaseAddress() == symbol_range->GetBaseAddress()) 947 { 948 // Do we already have a function with this symbol? 949 if (pos->symbol == sc.symbol) 950 return false; 951 if (pos->symbol == NULL) 952 { 953 pos->symbol = sc.symbol; 954 return false; 955 } 956 } 957 } 958 } 959 } 960 } 961 m_symbol_contexts.push_back(sc); 962 return true; 963 } 964 965 void 966 SymbolContextList::Clear() 967 { 968 m_symbol_contexts.clear(); 969 } 970 971 void 972 SymbolContextList::Dump(Stream *s, Target *target) const 973 { 974 975 *s << (void *)this << ": "; 976 s->Indent(); 977 s->PutCString("SymbolContextList"); 978 s->EOL(); 979 s->IndentMore(); 980 981 collection::const_iterator pos, end = m_symbol_contexts.end(); 982 for (pos = m_symbol_contexts.begin(); pos != end; ++pos) 983 { 984 pos->Dump(s, target); 985 } 986 s->IndentLess(); 987 } 988 989 bool 990 SymbolContextList::GetContextAtIndex(uint32_t idx, SymbolContext& sc) const 991 { 992 if (idx < m_symbol_contexts.size()) 993 { 994 sc = m_symbol_contexts[idx]; 995 return true; 996 } 997 return false; 998 } 999 1000 bool 1001 SymbolContextList::RemoveContextAtIndex (uint32_t idx) 1002 { 1003 if (idx < m_symbol_contexts.size()) 1004 { 1005 m_symbol_contexts.erase(m_symbol_contexts.begin() + idx); 1006 return true; 1007 } 1008 return false; 1009 } 1010 1011 uint32_t 1012 SymbolContextList::GetSize() const 1013 { 1014 return m_symbol_contexts.size(); 1015 } 1016 1017 uint32_t 1018 SymbolContextList::NumLineEntriesWithLine (uint32_t line) const 1019 { 1020 uint32_t match_count = 0; 1021 const uint32_t size = m_symbol_contexts.size(); 1022 for (uint32_t idx = 0; idx<size; ++idx) 1023 { 1024 if (m_symbol_contexts[idx].line_entry.line == line) 1025 ++match_count; 1026 } 1027 return match_count; 1028 } 1029 1030 bool 1031 lldb_private::operator== (const SymbolContextList& lhs, const SymbolContextList& rhs) 1032 { 1033 const uint32_t size = lhs.GetSize(); 1034 if (size != rhs.GetSize()) 1035 return false; 1036 1037 SymbolContext lhs_sc; 1038 SymbolContext rhs_sc; 1039 for (uint32_t i=0; i<size; ++i) 1040 { 1041 lhs.GetContextAtIndex(i, lhs_sc); 1042 rhs.GetContextAtIndex(i, rhs_sc); 1043 if (lhs_sc != rhs_sc) 1044 return false; 1045 } 1046 return true; 1047 } 1048 1049 bool 1050 lldb_private::operator!= (const SymbolContextList& lhs, const SymbolContextList& rhs) 1051 { 1052 return !(lhs == rhs); 1053 } 1054 1055