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