1 //===-- SearchFilter.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 // C Includes 11 // C++ Includes 12 // Other libraries and framework includes 13 // Project includes 14 15 #include "lldb/lldb-private.h" 16 #include "lldb/Core/SearchFilter.h" 17 #include "lldb/Core/Module.h" 18 #include "lldb/Symbol/CompileUnit.h" 19 #include "lldb/Target/Target.h" 20 21 using namespace lldb; 22 using namespace lldb_private; 23 24 //---------------------------------------------------------------------- 25 // SearchFilter constructor 26 //---------------------------------------------------------------------- 27 Searcher::Searcher () 28 { 29 30 } 31 32 Searcher::~Searcher () 33 { 34 35 } 36 37 void 38 Searcher::GetDescription (Stream *s) 39 { 40 } 41 42 //---------------------------------------------------------------------- 43 // SearchFilter constructor 44 //---------------------------------------------------------------------- 45 SearchFilter::SearchFilter(const TargetSP &target_sp) : 46 m_target_sp (target_sp) 47 { 48 } 49 50 //---------------------------------------------------------------------- 51 // SearchFilter copy constructor 52 //---------------------------------------------------------------------- 53 SearchFilter::SearchFilter(const SearchFilter& rhs) : 54 m_target_sp (rhs.m_target_sp) 55 { 56 } 57 58 //---------------------------------------------------------------------- 59 // SearchFilter assignment operator 60 //---------------------------------------------------------------------- 61 const SearchFilter& 62 SearchFilter::operator=(const SearchFilter& rhs) 63 { 64 m_target_sp = rhs.m_target_sp; 65 return *this; 66 } 67 68 //---------------------------------------------------------------------- 69 // Destructor 70 //---------------------------------------------------------------------- 71 SearchFilter::~SearchFilter() 72 { 73 } 74 75 bool 76 SearchFilter::ModulePasses (const FileSpec &spec) 77 { 78 return true; 79 } 80 81 bool 82 SearchFilter::ModulePasses (const ModuleSP &module_sp) 83 { 84 return true; 85 } 86 87 bool 88 SearchFilter::AddressPasses (Address &address) 89 { 90 return true; 91 } 92 93 bool 94 SearchFilter::CompUnitPasses (FileSpec &fileSpec) 95 { 96 return true; 97 } 98 99 bool 100 SearchFilter::CompUnitPasses (CompileUnit &compUnit) 101 { 102 return true; 103 } 104 105 uint32_t 106 SearchFilter::GetFilterRequiredItems() 107 { 108 return (lldb::SymbolContextItem) 0; 109 } 110 111 void 112 SearchFilter::GetDescription (Stream *s) 113 { 114 } 115 116 void 117 SearchFilter::Dump (Stream *s) const 118 { 119 120 } 121 122 //---------------------------------------------------------------------- 123 // UTILITY Functions to help iterate down through the elements of the 124 // SymbolContext. 125 //---------------------------------------------------------------------- 126 127 void 128 SearchFilter::Search (Searcher &searcher) 129 { 130 SymbolContext empty_sc; 131 132 if (!m_target_sp) 133 return; 134 empty_sc.target_sp = m_target_sp; 135 136 if (searcher.GetDepth() == Searcher::eDepthTarget) 137 searcher.SearchCallback (*this, empty_sc, NULL, false); 138 else 139 DoModuleIteration(empty_sc, searcher); 140 } 141 142 void 143 SearchFilter::SearchInModuleList (Searcher &searcher, ModuleList &modules) 144 { 145 SymbolContext empty_sc; 146 147 if (!m_target_sp) 148 return; 149 empty_sc.target_sp = m_target_sp; 150 151 if (searcher.GetDepth() == Searcher::eDepthTarget) 152 searcher.SearchCallback (*this, empty_sc, NULL, false); 153 else 154 { 155 Mutex::Locker modules_locker(modules.GetMutex()); 156 const size_t numModules = modules.GetSize(); 157 158 for (size_t i = 0; i < numModules; i++) 159 { 160 ModuleSP module_sp(modules.GetModuleAtIndexUnlocked(i)); 161 if (ModulePasses(module_sp)) 162 { 163 if (DoModuleIteration(module_sp, searcher) == Searcher::eCallbackReturnStop) 164 return; 165 } 166 } 167 } 168 } 169 170 171 Searcher::CallbackReturn 172 SearchFilter::DoModuleIteration (const lldb::ModuleSP& module_sp, Searcher &searcher) 173 { 174 SymbolContext matchingContext (m_target_sp, module_sp); 175 return DoModuleIteration(matchingContext, searcher); 176 } 177 178 Searcher::CallbackReturn 179 SearchFilter::DoModuleIteration (const SymbolContext &context, Searcher &searcher) 180 { 181 if (searcher.GetDepth () >= Searcher::eDepthModule) 182 { 183 if (context.module_sp) 184 { 185 if (searcher.GetDepth () == Searcher::eDepthModule) 186 { 187 SymbolContext matchingContext(context.module_sp.get()); 188 searcher.SearchCallback (*this, matchingContext, NULL, false); 189 } 190 else 191 { 192 return DoCUIteration(context.module_sp, context, searcher); 193 } 194 } 195 else 196 { 197 const ModuleList &target_images = m_target_sp->GetImages(); 198 Mutex::Locker modules_locker(target_images.GetMutex()); 199 200 size_t n_modules = target_images.GetSize(); 201 for (size_t i = 0; i < n_modules; i++) 202 { 203 // If this is the last level supplied, then call the callback directly, 204 // otherwise descend. 205 ModuleSP module_sp(target_images.GetModuleAtIndexUnlocked (i)); 206 if (!ModulePasses (module_sp)) 207 continue; 208 209 if (searcher.GetDepth () == Searcher::eDepthModule) 210 { 211 SymbolContext matchingContext(m_target_sp, module_sp); 212 213 Searcher::CallbackReturn shouldContinue = searcher.SearchCallback (*this, matchingContext, NULL, false); 214 if (shouldContinue == Searcher::eCallbackReturnStop 215 || shouldContinue == Searcher::eCallbackReturnPop) 216 return shouldContinue; 217 } 218 else 219 { 220 Searcher::CallbackReturn shouldContinue = DoCUIteration(module_sp, context, searcher); 221 if (shouldContinue == Searcher::eCallbackReturnStop) 222 return shouldContinue; 223 else if (shouldContinue == Searcher::eCallbackReturnPop) 224 continue; 225 } 226 } 227 } 228 } 229 return Searcher::eCallbackReturnContinue; 230 } 231 232 Searcher::CallbackReturn 233 SearchFilter::DoCUIteration (const ModuleSP &module_sp, const SymbolContext &context, Searcher &searcher) 234 { 235 Searcher::CallbackReturn shouldContinue; 236 if (context.comp_unit == NULL) 237 { 238 const size_t num_comp_units = module_sp->GetNumCompileUnits(); 239 for (size_t i = 0; i < num_comp_units; i++) 240 { 241 CompUnitSP cu_sp (module_sp->GetCompileUnitAtIndex (i)); 242 if (cu_sp) 243 { 244 if (!CompUnitPasses (*(cu_sp.get()))) 245 continue; 246 247 if (searcher.GetDepth () == Searcher::eDepthCompUnit) 248 { 249 SymbolContext matchingContext(m_target_sp, module_sp, cu_sp.get()); 250 251 shouldContinue = searcher.SearchCallback (*this, matchingContext, NULL, false); 252 253 if (shouldContinue == Searcher::eCallbackReturnPop) 254 return Searcher::eCallbackReturnContinue; 255 else if (shouldContinue == Searcher::eCallbackReturnStop) 256 return shouldContinue; 257 } 258 else 259 { 260 // FIXME Descend to block. 261 } 262 } 263 } 264 } 265 else 266 { 267 if (CompUnitPasses(*context.comp_unit)) 268 { 269 SymbolContext matchingContext (m_target_sp, module_sp, context.comp_unit); 270 return searcher.SearchCallback (*this, matchingContext, NULL, false); 271 } 272 } 273 return Searcher::eCallbackReturnContinue; 274 } 275 276 Searcher::CallbackReturn 277 SearchFilter::DoFunctionIteration (Function *function, const SymbolContext &context, Searcher &searcher) 278 { 279 // FIXME: Implement... 280 return Searcher::eCallbackReturnContinue; 281 } 282 283 //---------------------------------------------------------------------- 284 // SearchFilterForNonModuleSpecificSearches: 285 // Selects a shared library matching a given file spec, consulting the targets "black list". 286 //---------------------------------------------------------------------- 287 288 bool 289 SearchFilterForNonModuleSpecificSearches::ModulePasses (const FileSpec &module_spec) 290 { 291 if (m_target_sp->ModuleIsExcludedForNonModuleSpecificSearches (module_spec)) 292 return false; 293 else 294 return true; 295 } 296 297 bool 298 SearchFilterForNonModuleSpecificSearches::ModulePasses (const lldb::ModuleSP &module_sp) 299 { 300 if (!module_sp) 301 return true; 302 else if (m_target_sp->ModuleIsExcludedForNonModuleSpecificSearches (module_sp)) 303 return false; 304 else 305 return true; 306 } 307 308 //---------------------------------------------------------------------- 309 // SearchFilterByModule: 310 // Selects a shared library matching a given file spec 311 //---------------------------------------------------------------------- 312 313 //---------------------------------------------------------------------- 314 // SearchFilterByModule constructors 315 //---------------------------------------------------------------------- 316 317 SearchFilterByModule::SearchFilterByModule (const lldb::TargetSP &target_sp, const FileSpec &module) : 318 SearchFilter (target_sp), 319 m_module_spec (module) 320 { 321 } 322 323 324 //---------------------------------------------------------------------- 325 // SearchFilterByModule copy constructor 326 //---------------------------------------------------------------------- 327 SearchFilterByModule::SearchFilterByModule(const SearchFilterByModule& rhs) : 328 SearchFilter (rhs), 329 m_module_spec (rhs.m_module_spec) 330 { 331 } 332 333 //---------------------------------------------------------------------- 334 // SearchFilterByModule assignment operator 335 //---------------------------------------------------------------------- 336 const SearchFilterByModule& 337 SearchFilterByModule::operator=(const SearchFilterByModule& rhs) 338 { 339 m_target_sp = rhs.m_target_sp; 340 m_module_spec = rhs.m_module_spec; 341 return *this; 342 } 343 344 //---------------------------------------------------------------------- 345 // Destructor 346 //---------------------------------------------------------------------- 347 SearchFilterByModule::~SearchFilterByModule() 348 { 349 } 350 351 bool 352 SearchFilterByModule::ModulePasses (const ModuleSP &module_sp) 353 { 354 if (module_sp && FileSpec::Equal(module_sp->GetFileSpec(), m_module_spec, false)) 355 return true; 356 else 357 return false; 358 } 359 360 bool 361 SearchFilterByModule::ModulePasses (const FileSpec &spec) 362 { 363 // Do a full match only if "spec" has a directory 364 const bool full_match = spec.GetDirectory(); 365 return FileSpec::Equal(spec, m_module_spec, full_match); 366 } 367 368 bool 369 SearchFilterByModule::AddressPasses (Address &address) 370 { 371 // FIXME: Not yet implemented 372 return true; 373 } 374 375 376 bool 377 SearchFilterByModule::CompUnitPasses (FileSpec &fileSpec) 378 { 379 return true; 380 } 381 382 bool 383 SearchFilterByModule::CompUnitPasses (CompileUnit &compUnit) 384 { 385 return true; 386 } 387 388 void 389 SearchFilterByModule::Search (Searcher &searcher) 390 { 391 if (!m_target_sp) 392 return; 393 394 if (searcher.GetDepth() == Searcher::eDepthTarget) 395 { 396 SymbolContext empty_sc; 397 empty_sc.target_sp = m_target_sp; 398 searcher.SearchCallback (*this, empty_sc, NULL, false); 399 } 400 401 // If the module file spec is a full path, then we can just find the one 402 // filespec that passes. Otherwise, we need to go through all modules and 403 // find the ones that match the file name. 404 405 const ModuleList &target_modules = m_target_sp->GetImages(); 406 Mutex::Locker modules_locker (target_modules.GetMutex()); 407 408 const size_t num_modules = target_modules.GetSize (); 409 for (size_t i = 0; i < num_modules; i++) 410 { 411 Module* module = target_modules.GetModulePointerAtIndexUnlocked(i); 412 const bool full_match = m_module_spec.GetDirectory(); 413 if (FileSpec::Equal (m_module_spec, module->GetFileSpec(), full_match)) 414 { 415 SymbolContext matchingContext(m_target_sp, module->shared_from_this()); 416 Searcher::CallbackReturn shouldContinue; 417 418 shouldContinue = DoModuleIteration(matchingContext, searcher); 419 if (shouldContinue == Searcher::eCallbackReturnStop) 420 return; 421 } 422 } 423 } 424 425 void 426 SearchFilterByModule::GetDescription (Stream *s) 427 { 428 s->PutCString(", module = "); 429 if (s->GetVerbose()) 430 { 431 char buffer[2048]; 432 m_module_spec.GetPath(buffer, 2047); 433 s->PutCString(buffer); 434 } 435 else 436 { 437 s->PutCString(m_module_spec.GetFilename().AsCString("<unknown>")); 438 } 439 } 440 441 uint32_t 442 SearchFilterByModule::GetFilterRequiredItems() 443 { 444 return eSymbolContextModule; 445 } 446 447 void 448 SearchFilterByModule::Dump (Stream *s) const 449 { 450 451 } 452 //---------------------------------------------------------------------- 453 // SearchFilterByModuleList: 454 // Selects a shared library matching a given file spec 455 //---------------------------------------------------------------------- 456 457 //---------------------------------------------------------------------- 458 // SearchFilterByModuleList constructors 459 //---------------------------------------------------------------------- 460 461 SearchFilterByModuleList::SearchFilterByModuleList (const lldb::TargetSP &target_sp, const FileSpecList &module_list) : 462 SearchFilter (target_sp), 463 m_module_spec_list (module_list) 464 { 465 } 466 467 468 //---------------------------------------------------------------------- 469 // SearchFilterByModuleList copy constructor 470 //---------------------------------------------------------------------- 471 SearchFilterByModuleList::SearchFilterByModuleList(const SearchFilterByModuleList& rhs) : 472 SearchFilter (rhs), 473 m_module_spec_list (rhs.m_module_spec_list) 474 { 475 } 476 477 //---------------------------------------------------------------------- 478 // SearchFilterByModuleList assignment operator 479 //---------------------------------------------------------------------- 480 const SearchFilterByModuleList& 481 SearchFilterByModuleList::operator=(const SearchFilterByModuleList& rhs) 482 { 483 m_target_sp = rhs.m_target_sp; 484 m_module_spec_list = rhs.m_module_spec_list; 485 return *this; 486 } 487 488 //---------------------------------------------------------------------- 489 // Destructor 490 //---------------------------------------------------------------------- 491 SearchFilterByModuleList::~SearchFilterByModuleList() 492 { 493 } 494 495 bool 496 SearchFilterByModuleList::ModulePasses (const ModuleSP &module_sp) 497 { 498 if (m_module_spec_list.GetSize() == 0) 499 return true; 500 501 if (module_sp && m_module_spec_list.FindFileIndex(0, module_sp->GetFileSpec(), false) != UINT32_MAX) 502 return true; 503 else 504 return false; 505 } 506 507 bool 508 SearchFilterByModuleList::ModulePasses (const FileSpec &spec) 509 { 510 if (m_module_spec_list.GetSize() == 0) 511 return true; 512 513 if (m_module_spec_list.FindFileIndex(0, spec, true) != UINT32_MAX) 514 return true; 515 else 516 return false; 517 } 518 519 bool 520 SearchFilterByModuleList::AddressPasses (Address &address) 521 { 522 // FIXME: Not yet implemented 523 return true; 524 } 525 526 527 bool 528 SearchFilterByModuleList::CompUnitPasses (FileSpec &fileSpec) 529 { 530 return true; 531 } 532 533 bool 534 SearchFilterByModuleList::CompUnitPasses (CompileUnit &compUnit) 535 { 536 return true; 537 } 538 539 void 540 SearchFilterByModuleList::Search (Searcher &searcher) 541 { 542 if (!m_target_sp) 543 return; 544 545 if (searcher.GetDepth() == Searcher::eDepthTarget) 546 { 547 SymbolContext empty_sc; 548 empty_sc.target_sp = m_target_sp; 549 searcher.SearchCallback (*this, empty_sc, NULL, false); 550 } 551 552 // If the module file spec is a full path, then we can just find the one 553 // filespec that passes. Otherwise, we need to go through all modules and 554 // find the ones that match the file name. 555 556 const ModuleList &target_modules = m_target_sp->GetImages(); 557 Mutex::Locker modules_locker (target_modules.GetMutex()); 558 559 const size_t num_modules = target_modules.GetSize (); 560 for (size_t i = 0; i < num_modules; i++) 561 { 562 Module* module = target_modules.GetModulePointerAtIndexUnlocked(i); 563 if (m_module_spec_list.FindFileIndex(0, module->GetFileSpec(), false) != UINT32_MAX) 564 { 565 SymbolContext matchingContext(m_target_sp, module->shared_from_this()); 566 Searcher::CallbackReturn shouldContinue; 567 568 shouldContinue = DoModuleIteration(matchingContext, searcher); 569 if (shouldContinue == Searcher::eCallbackReturnStop) 570 return; 571 } 572 } 573 } 574 575 void 576 SearchFilterByModuleList::GetDescription (Stream *s) 577 { 578 size_t num_modules = m_module_spec_list.GetSize(); 579 if (num_modules == 1) 580 { 581 s->Printf (", module = "); 582 if (s->GetVerbose()) 583 { 584 char buffer[2048]; 585 m_module_spec_list.GetFileSpecAtIndex(0).GetPath(buffer, 2047); 586 s->PutCString(buffer); 587 } 588 else 589 { 590 s->PutCString(m_module_spec_list.GetFileSpecAtIndex(0).GetFilename().AsCString("<unknown>")); 591 } 592 } 593 else 594 { 595 s->Printf (", modules(%zu) = ", num_modules); 596 for (size_t i = 0; i < num_modules; i++) 597 { 598 if (s->GetVerbose()) 599 { 600 char buffer[2048]; 601 m_module_spec_list.GetFileSpecAtIndex(i).GetPath(buffer, 2047); 602 s->PutCString(buffer); 603 } 604 else 605 { 606 s->PutCString(m_module_spec_list.GetFileSpecAtIndex(i).GetFilename().AsCString("<unknown>")); 607 } 608 if (i != num_modules - 1) 609 s->PutCString (", "); 610 } 611 } 612 } 613 614 uint32_t 615 SearchFilterByModuleList::GetFilterRequiredItems() 616 { 617 return eSymbolContextModule; 618 } 619 620 void 621 SearchFilterByModuleList::Dump (Stream *s) const 622 { 623 624 } 625 626 //---------------------------------------------------------------------- 627 // SearchFilterByModuleListAndCU: 628 // Selects a shared library matching a given file spec 629 //---------------------------------------------------------------------- 630 631 //---------------------------------------------------------------------- 632 // SearchFilterByModuleListAndCU constructors 633 //---------------------------------------------------------------------- 634 635 SearchFilterByModuleListAndCU::SearchFilterByModuleListAndCU (const lldb::TargetSP &target_sp, 636 const FileSpecList &module_list, 637 const FileSpecList &cu_list) : 638 SearchFilterByModuleList (target_sp, module_list), 639 m_cu_spec_list (cu_list) 640 { 641 } 642 643 644 //---------------------------------------------------------------------- 645 // SearchFilterByModuleListAndCU copy constructor 646 //---------------------------------------------------------------------- 647 SearchFilterByModuleListAndCU::SearchFilterByModuleListAndCU(const SearchFilterByModuleListAndCU& rhs) : 648 SearchFilterByModuleList (rhs), 649 m_cu_spec_list (rhs.m_cu_spec_list) 650 { 651 } 652 653 //---------------------------------------------------------------------- 654 // SearchFilterByModuleListAndCU assignment operator 655 //---------------------------------------------------------------------- 656 const SearchFilterByModuleListAndCU& 657 SearchFilterByModuleListAndCU::operator=(const SearchFilterByModuleListAndCU& rhs) 658 { 659 if (&rhs != this) 660 { 661 m_target_sp = rhs.m_target_sp; 662 m_module_spec_list = rhs.m_module_spec_list; 663 m_cu_spec_list = rhs.m_cu_spec_list; 664 } 665 return *this; 666 } 667 668 //---------------------------------------------------------------------- 669 // Destructor 670 //---------------------------------------------------------------------- 671 SearchFilterByModuleListAndCU::~SearchFilterByModuleListAndCU() 672 { 673 } 674 675 bool 676 SearchFilterByModuleListAndCU::AddressPasses (Address &address) 677 { 678 return true; 679 } 680 681 682 bool 683 SearchFilterByModuleListAndCU::CompUnitPasses (FileSpec &fileSpec) 684 { 685 return m_cu_spec_list.FindFileIndex(0, fileSpec, false) != UINT32_MAX; 686 } 687 688 bool 689 SearchFilterByModuleListAndCU::CompUnitPasses (CompileUnit &compUnit) 690 { 691 bool in_cu_list = m_cu_spec_list.FindFileIndex(0, compUnit, false) != UINT32_MAX; 692 if (in_cu_list) 693 { 694 ModuleSP module_sp(compUnit.GetModule()); 695 if (module_sp) 696 { 697 bool module_passes = SearchFilterByModuleList::ModulePasses(module_sp); 698 return module_passes; 699 } 700 else 701 return true; 702 } 703 else 704 return false; 705 } 706 707 void 708 SearchFilterByModuleListAndCU::Search (Searcher &searcher) 709 { 710 if (!m_target_sp) 711 return; 712 713 if (searcher.GetDepth() == Searcher::eDepthTarget) 714 { 715 SymbolContext empty_sc; 716 empty_sc.target_sp = m_target_sp; 717 searcher.SearchCallback (*this, empty_sc, NULL, false); 718 } 719 720 // If the module file spec is a full path, then we can just find the one 721 // filespec that passes. Otherwise, we need to go through all modules and 722 // find the ones that match the file name. 723 724 ModuleList matching_modules; 725 const ModuleList &target_images = m_target_sp->GetImages(); 726 Mutex::Locker modules_locker(target_images.GetMutex()); 727 728 const size_t num_modules = target_images.GetSize (); 729 bool no_modules_in_filter = m_module_spec_list.GetSize() == 0; 730 for (size_t i = 0; i < num_modules; i++) 731 { 732 lldb::ModuleSP module_sp = target_images.GetModuleAtIndexUnlocked(i); 733 if (no_modules_in_filter || m_module_spec_list.FindFileIndex(0, module_sp->GetFileSpec(), false) != UINT32_MAX) 734 { 735 SymbolContext matchingContext(m_target_sp, module_sp); 736 Searcher::CallbackReturn shouldContinue; 737 738 if (searcher.GetDepth() == Searcher::eDepthModule) 739 { 740 shouldContinue = DoModuleIteration(matchingContext, searcher); 741 if (shouldContinue == Searcher::eCallbackReturnStop) 742 return; 743 } 744 else 745 { 746 const size_t num_cu = module_sp->GetNumCompileUnits(); 747 for (size_t cu_idx = 0; cu_idx < num_cu; cu_idx++) 748 { 749 CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(cu_idx); 750 matchingContext.comp_unit = cu_sp.get(); 751 if (matchingContext.comp_unit) 752 { 753 if (m_cu_spec_list.FindFileIndex(0, *matchingContext.comp_unit, false) != UINT32_MAX) 754 { 755 shouldContinue = DoCUIteration(module_sp, matchingContext, searcher); 756 if (shouldContinue == Searcher::eCallbackReturnStop) 757 return; 758 } 759 } 760 } 761 } 762 } 763 } 764 } 765 766 void 767 SearchFilterByModuleListAndCU::GetDescription (Stream *s) 768 { 769 size_t num_modules = m_module_spec_list.GetSize(); 770 if (num_modules == 1) 771 { 772 s->Printf (", module = "); 773 if (s->GetVerbose()) 774 { 775 char buffer[2048]; 776 m_module_spec_list.GetFileSpecAtIndex(0).GetPath(buffer, 2047); 777 s->PutCString(buffer); 778 } 779 else 780 { 781 s->PutCString(m_module_spec_list.GetFileSpecAtIndex(0).GetFilename().AsCString("<unknown>")); 782 } 783 } 784 else if (num_modules > 0) 785 { 786 s->Printf (", modules(%zd) = ", num_modules); 787 for (size_t i = 0; i < num_modules; i++) 788 { 789 if (s->GetVerbose()) 790 { 791 char buffer[2048]; 792 m_module_spec_list.GetFileSpecAtIndex(i).GetPath(buffer, 2047); 793 s->PutCString(buffer); 794 } 795 else 796 { 797 s->PutCString(m_module_spec_list.GetFileSpecAtIndex(i).GetFilename().AsCString("<unknown>")); 798 } 799 if (i != num_modules - 1) 800 s->PutCString (", "); 801 } 802 } 803 } 804 805 uint32_t 806 SearchFilterByModuleListAndCU::GetFilterRequiredItems() 807 { 808 return eSymbolContextModule | eSymbolContextCompUnit; 809 } 810 811 void 812 SearchFilterByModuleListAndCU::Dump (Stream *s) const 813 { 814 815 } 816 817