1 //===-- SearchFilter.cpp ----------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
12 // Other libraries and framework includes
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"
22 using namespace lldb_private;
24 //----------------------------------------------------------------------
25 // SearchFilter constructor
26 //----------------------------------------------------------------------
32 Searcher::~Searcher ()
38 Searcher::GetDescription (Stream *s)
42 //----------------------------------------------------------------------
43 // SearchFilter constructor
44 //----------------------------------------------------------------------
45 SearchFilter::SearchFilter(const TargetSP &target_sp) :
46 m_target_sp (target_sp)
50 //----------------------------------------------------------------------
51 // SearchFilter copy constructor
52 //----------------------------------------------------------------------
53 SearchFilter::SearchFilter(const SearchFilter& rhs) :
54 m_target_sp (rhs.m_target_sp)
58 //----------------------------------------------------------------------
59 // SearchFilter assignment operator
60 //----------------------------------------------------------------------
62 SearchFilter::operator=(const SearchFilter& rhs)
64 m_target_sp = rhs.m_target_sp;
68 //----------------------------------------------------------------------
70 //----------------------------------------------------------------------
71 SearchFilter::~SearchFilter()
76 SearchFilter::ModulePasses (const FileSpec &spec)
82 SearchFilter::ModulePasses (const ModuleSP &module_sp)
88 SearchFilter::AddressPasses (Address &address)
94 SearchFilter::CompUnitPasses (FileSpec &fileSpec)
100 SearchFilter::CompUnitPasses (CompileUnit &compUnit)
106 SearchFilter::GetFilterRequiredItems()
108 return (lldb::SymbolContextItem) 0;
112 SearchFilter::GetDescription (Stream *s)
117 SearchFilter::Dump (Stream *s) const
122 //----------------------------------------------------------------------
123 // UTILITY Functions to help iterate down through the elements of the
125 //----------------------------------------------------------------------
128 SearchFilter::Search (Searcher &searcher)
130 SymbolContext empty_sc;
134 empty_sc.target_sp = m_target_sp;
136 if (searcher.GetDepth() == Searcher::eDepthTarget)
137 searcher.SearchCallback (*this, empty_sc, NULL, false);
139 DoModuleIteration(empty_sc, searcher);
143 SearchFilter::SearchInModuleList (Searcher &searcher, ModuleList &modules)
145 SymbolContext empty_sc;
149 empty_sc.target_sp = m_target_sp;
151 if (searcher.GetDepth() == Searcher::eDepthTarget)
152 searcher.SearchCallback (*this, empty_sc, NULL, false);
155 Mutex::Locker modules_locker(modules.GetMutex());
156 const size_t numModules = modules.GetSize();
158 for (size_t i = 0; i < numModules; i++)
160 ModuleSP module_sp(modules.GetModuleAtIndexUnlocked(i));
161 if (ModulePasses(module_sp))
163 if (DoModuleIteration(module_sp, searcher) == Searcher::eCallbackReturnStop)
171 Searcher::CallbackReturn
172 SearchFilter::DoModuleIteration (const lldb::ModuleSP& module_sp, Searcher &searcher)
174 SymbolContext matchingContext (m_target_sp, module_sp);
175 return DoModuleIteration(matchingContext, searcher);
178 Searcher::CallbackReturn
179 SearchFilter::DoModuleIteration (const SymbolContext &context, Searcher &searcher)
181 if (searcher.GetDepth () >= Searcher::eDepthModule)
183 if (context.module_sp)
185 if (searcher.GetDepth () == Searcher::eDepthModule)
187 SymbolContext matchingContext(context.module_sp.get());
188 searcher.SearchCallback (*this, matchingContext, NULL, false);
192 return DoCUIteration(context.module_sp, context, searcher);
197 const ModuleList &target_images = m_target_sp->GetImages();
198 Mutex::Locker modules_locker(target_images.GetMutex());
200 size_t n_modules = target_images.GetSize();
201 for (size_t i = 0; i < n_modules; i++)
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))
209 if (searcher.GetDepth () == Searcher::eDepthModule)
211 SymbolContext matchingContext(m_target_sp, module_sp);
213 Searcher::CallbackReturn shouldContinue = searcher.SearchCallback (*this, matchingContext, NULL, false);
214 if (shouldContinue == Searcher::eCallbackReturnStop
215 || shouldContinue == Searcher::eCallbackReturnPop)
216 return shouldContinue;
220 Searcher::CallbackReturn shouldContinue = DoCUIteration(module_sp, context, searcher);
221 if (shouldContinue == Searcher::eCallbackReturnStop)
222 return shouldContinue;
223 else if (shouldContinue == Searcher::eCallbackReturnPop)
229 return Searcher::eCallbackReturnContinue;
232 Searcher::CallbackReturn
233 SearchFilter::DoCUIteration (const ModuleSP &module_sp, const SymbolContext &context, Searcher &searcher)
235 Searcher::CallbackReturn shouldContinue;
236 if (context.comp_unit == NULL)
238 const size_t num_comp_units = module_sp->GetNumCompileUnits();
239 for (size_t i = 0; i < num_comp_units; i++)
241 CompUnitSP cu_sp (module_sp->GetCompileUnitAtIndex (i));
244 if (!CompUnitPasses (*(cu_sp.get())))
247 if (searcher.GetDepth () == Searcher::eDepthCompUnit)
249 SymbolContext matchingContext(m_target_sp, module_sp, cu_sp.get());
251 shouldContinue = searcher.SearchCallback (*this, matchingContext, NULL, false);
253 if (shouldContinue == Searcher::eCallbackReturnPop)
254 return Searcher::eCallbackReturnContinue;
255 else if (shouldContinue == Searcher::eCallbackReturnStop)
256 return shouldContinue;
260 // FIXME Descend to block.
267 if (CompUnitPasses(*context.comp_unit))
269 SymbolContext matchingContext (m_target_sp, module_sp, context.comp_unit);
270 return searcher.SearchCallback (*this, matchingContext, NULL, false);
273 return Searcher::eCallbackReturnContinue;
276 Searcher::CallbackReturn
277 SearchFilter::DoFunctionIteration (Function *function, const SymbolContext &context, Searcher &searcher)
279 // FIXME: Implement...
280 return Searcher::eCallbackReturnContinue;
283 //----------------------------------------------------------------------
284 // SearchFilterForNonModuleSpecificSearches:
285 // Selects a shared library matching a given file spec, consulting the targets "black list".
286 //----------------------------------------------------------------------
289 SearchFilterForNonModuleSpecificSearches::ModulePasses (const FileSpec &module_spec)
291 if (m_target_sp->ModuleIsExcludedForNonModuleSpecificSearches (module_spec))
298 SearchFilterForNonModuleSpecificSearches::ModulePasses (const lldb::ModuleSP &module_sp)
302 else if (m_target_sp->ModuleIsExcludedForNonModuleSpecificSearches (module_sp))
308 //----------------------------------------------------------------------
309 // SearchFilterByModule:
310 // Selects a shared library matching a given file spec
311 //----------------------------------------------------------------------
313 //----------------------------------------------------------------------
314 // SearchFilterByModule constructors
315 //----------------------------------------------------------------------
317 SearchFilterByModule::SearchFilterByModule (const lldb::TargetSP &target_sp, const FileSpec &module) :
318 SearchFilter (target_sp),
319 m_module_spec (module)
324 //----------------------------------------------------------------------
325 // SearchFilterByModule copy constructor
326 //----------------------------------------------------------------------
327 SearchFilterByModule::SearchFilterByModule(const SearchFilterByModule& rhs) :
329 m_module_spec (rhs.m_module_spec)
333 //----------------------------------------------------------------------
334 // SearchFilterByModule assignment operator
335 //----------------------------------------------------------------------
336 const SearchFilterByModule&
337 SearchFilterByModule::operator=(const SearchFilterByModule& rhs)
339 m_target_sp = rhs.m_target_sp;
340 m_module_spec = rhs.m_module_spec;
344 //----------------------------------------------------------------------
346 //----------------------------------------------------------------------
347 SearchFilterByModule::~SearchFilterByModule()
352 SearchFilterByModule::ModulePasses (const ModuleSP &module_sp)
354 if (module_sp && FileSpec::Equal(module_sp->GetFileSpec(), m_module_spec, false))
361 SearchFilterByModule::ModulePasses (const FileSpec &spec)
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);
369 SearchFilterByModule::AddressPasses (Address &address)
371 // FIXME: Not yet implemented
377 SearchFilterByModule::CompUnitPasses (FileSpec &fileSpec)
383 SearchFilterByModule::CompUnitPasses (CompileUnit &compUnit)
389 SearchFilterByModule::Search (Searcher &searcher)
394 if (searcher.GetDepth() == Searcher::eDepthTarget)
396 SymbolContext empty_sc;
397 empty_sc.target_sp = m_target_sp;
398 searcher.SearchCallback (*this, empty_sc, NULL, false);
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.
405 const ModuleList &target_modules = m_target_sp->GetImages();
406 Mutex::Locker modules_locker (target_modules.GetMutex());
408 const size_t num_modules = target_modules.GetSize ();
409 for (size_t i = 0; i < num_modules; i++)
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))
415 SymbolContext matchingContext(m_target_sp, module->shared_from_this());
416 Searcher::CallbackReturn shouldContinue;
418 shouldContinue = DoModuleIteration(matchingContext, searcher);
419 if (shouldContinue == Searcher::eCallbackReturnStop)
426 SearchFilterByModule::GetDescription (Stream *s)
428 s->PutCString(", module = ");
432 m_module_spec.GetPath(buffer, 2047);
433 s->PutCString(buffer);
437 s->PutCString(m_module_spec.GetFilename().AsCString("<unknown>"));
442 SearchFilterByModule::GetFilterRequiredItems()
444 return eSymbolContextModule;
448 SearchFilterByModule::Dump (Stream *s) const
452 //----------------------------------------------------------------------
453 // SearchFilterByModuleList:
454 // Selects a shared library matching a given file spec
455 //----------------------------------------------------------------------
457 //----------------------------------------------------------------------
458 // SearchFilterByModuleList constructors
459 //----------------------------------------------------------------------
461 SearchFilterByModuleList::SearchFilterByModuleList (const lldb::TargetSP &target_sp, const FileSpecList &module_list) :
462 SearchFilter (target_sp),
463 m_module_spec_list (module_list)
468 //----------------------------------------------------------------------
469 // SearchFilterByModuleList copy constructor
470 //----------------------------------------------------------------------
471 SearchFilterByModuleList::SearchFilterByModuleList(const SearchFilterByModuleList& rhs) :
473 m_module_spec_list (rhs.m_module_spec_list)
477 //----------------------------------------------------------------------
478 // SearchFilterByModuleList assignment operator
479 //----------------------------------------------------------------------
480 const SearchFilterByModuleList&
481 SearchFilterByModuleList::operator=(const SearchFilterByModuleList& rhs)
483 m_target_sp = rhs.m_target_sp;
484 m_module_spec_list = rhs.m_module_spec_list;
488 //----------------------------------------------------------------------
490 //----------------------------------------------------------------------
491 SearchFilterByModuleList::~SearchFilterByModuleList()
496 SearchFilterByModuleList::ModulePasses (const ModuleSP &module_sp)
498 if (m_module_spec_list.GetSize() == 0)
501 if (module_sp && m_module_spec_list.FindFileIndex(0, module_sp->GetFileSpec(), false) != UINT32_MAX)
508 SearchFilterByModuleList::ModulePasses (const FileSpec &spec)
510 if (m_module_spec_list.GetSize() == 0)
513 if (m_module_spec_list.FindFileIndex(0, spec, true) != UINT32_MAX)
520 SearchFilterByModuleList::AddressPasses (Address &address)
522 // FIXME: Not yet implemented
528 SearchFilterByModuleList::CompUnitPasses (FileSpec &fileSpec)
534 SearchFilterByModuleList::CompUnitPasses (CompileUnit &compUnit)
540 SearchFilterByModuleList::Search (Searcher &searcher)
545 if (searcher.GetDepth() == Searcher::eDepthTarget)
547 SymbolContext empty_sc;
548 empty_sc.target_sp = m_target_sp;
549 searcher.SearchCallback (*this, empty_sc, NULL, false);
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.
556 const ModuleList &target_modules = m_target_sp->GetImages();
557 Mutex::Locker modules_locker (target_modules.GetMutex());
559 const size_t num_modules = target_modules.GetSize ();
560 for (size_t i = 0; i < num_modules; i++)
562 Module* module = target_modules.GetModulePointerAtIndexUnlocked(i);
563 if (m_module_spec_list.FindFileIndex(0, module->GetFileSpec(), false) != UINT32_MAX)
565 SymbolContext matchingContext(m_target_sp, module->shared_from_this());
566 Searcher::CallbackReturn shouldContinue;
568 shouldContinue = DoModuleIteration(matchingContext, searcher);
569 if (shouldContinue == Searcher::eCallbackReturnStop)
576 SearchFilterByModuleList::GetDescription (Stream *s)
578 size_t num_modules = m_module_spec_list.GetSize();
579 if (num_modules == 1)
581 s->Printf (", module = ");
585 m_module_spec_list.GetFileSpecAtIndex(0).GetPath(buffer, 2047);
586 s->PutCString(buffer);
590 s->PutCString(m_module_spec_list.GetFileSpecAtIndex(0).GetFilename().AsCString("<unknown>"));
595 s->Printf (", modules(%zu) = ", num_modules);
596 for (size_t i = 0; i < num_modules; i++)
601 m_module_spec_list.GetFileSpecAtIndex(i).GetPath(buffer, 2047);
602 s->PutCString(buffer);
606 s->PutCString(m_module_spec_list.GetFileSpecAtIndex(i).GetFilename().AsCString("<unknown>"));
608 if (i != num_modules - 1)
609 s->PutCString (", ");
615 SearchFilterByModuleList::GetFilterRequiredItems()
617 return eSymbolContextModule;
621 SearchFilterByModuleList::Dump (Stream *s) const
626 //----------------------------------------------------------------------
627 // SearchFilterByModuleListAndCU:
628 // Selects a shared library matching a given file spec
629 //----------------------------------------------------------------------
631 //----------------------------------------------------------------------
632 // SearchFilterByModuleListAndCU constructors
633 //----------------------------------------------------------------------
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)
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)
653 //----------------------------------------------------------------------
654 // SearchFilterByModuleListAndCU assignment operator
655 //----------------------------------------------------------------------
656 const SearchFilterByModuleListAndCU&
657 SearchFilterByModuleListAndCU::operator=(const SearchFilterByModuleListAndCU& rhs)
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;
668 //----------------------------------------------------------------------
670 //----------------------------------------------------------------------
671 SearchFilterByModuleListAndCU::~SearchFilterByModuleListAndCU()
676 SearchFilterByModuleListAndCU::AddressPasses (Address &address)
683 SearchFilterByModuleListAndCU::CompUnitPasses (FileSpec &fileSpec)
685 return m_cu_spec_list.FindFileIndex(0, fileSpec, false) != UINT32_MAX;
689 SearchFilterByModuleListAndCU::CompUnitPasses (CompileUnit &compUnit)
691 bool in_cu_list = m_cu_spec_list.FindFileIndex(0, compUnit, false) != UINT32_MAX;
694 ModuleSP module_sp(compUnit.GetModule());
697 bool module_passes = SearchFilterByModuleList::ModulePasses(module_sp);
698 return module_passes;
708 SearchFilterByModuleListAndCU::Search (Searcher &searcher)
713 if (searcher.GetDepth() == Searcher::eDepthTarget)
715 SymbolContext empty_sc;
716 empty_sc.target_sp = m_target_sp;
717 searcher.SearchCallback (*this, empty_sc, NULL, false);
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.
724 ModuleList matching_modules;
725 const ModuleList &target_images = m_target_sp->GetImages();
726 Mutex::Locker modules_locker(target_images.GetMutex());
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++)
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)
735 SymbolContext matchingContext(m_target_sp, module_sp);
736 Searcher::CallbackReturn shouldContinue;
738 if (searcher.GetDepth() == Searcher::eDepthModule)
740 shouldContinue = DoModuleIteration(matchingContext, searcher);
741 if (shouldContinue == Searcher::eCallbackReturnStop)
746 const size_t num_cu = module_sp->GetNumCompileUnits();
747 for (size_t cu_idx = 0; cu_idx < num_cu; cu_idx++)
749 CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(cu_idx);
750 matchingContext.comp_unit = cu_sp.get();
751 if (matchingContext.comp_unit)
753 if (m_cu_spec_list.FindFileIndex(0, *matchingContext.comp_unit, false) != UINT32_MAX)
755 shouldContinue = DoCUIteration(module_sp, matchingContext, searcher);
756 if (shouldContinue == Searcher::eCallbackReturnStop)
767 SearchFilterByModuleListAndCU::GetDescription (Stream *s)
769 size_t num_modules = m_module_spec_list.GetSize();
770 if (num_modules == 1)
772 s->Printf (", module = ");
776 m_module_spec_list.GetFileSpecAtIndex(0).GetPath(buffer, 2047);
777 s->PutCString(buffer);
781 s->PutCString(m_module_spec_list.GetFileSpecAtIndex(0).GetFilename().AsCString("<unknown>"));
784 else if (num_modules > 0)
786 s->Printf (", modules(%zd) = ", num_modules);
787 for (size_t i = 0; i < num_modules; i++)
792 m_module_spec_list.GetFileSpecAtIndex(i).GetPath(buffer, 2047);
793 s->PutCString(buffer);
797 s->PutCString(m_module_spec_list.GetFileSpecAtIndex(i).GetFilename().AsCString("<unknown>"));
799 if (i != num_modules - 1)
800 s->PutCString (", ");
806 SearchFilterByModuleListAndCU::GetFilterRequiredItems()
808 return eSymbolContextModule | eSymbolContextCompUnit;
812 SearchFilterByModuleListAndCU::Dump (Stream *s) const