1 //===-- BreakpointResolverFileRegex.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/Breakpoint/BreakpointResolverFileRegex.h" 11 12 // C Includes 13 // C++ Includes 14 // Other libraries and framework includes 15 // Project includes 16 #include "lldb/Breakpoint/BreakpointLocation.h" 17 #include "lldb/Core/SourceManager.h" 18 #include "lldb/Core/Log.h" 19 #include "lldb/Core/StreamString.h" 20 #include "lldb/Symbol/CompileUnit.h" 21 #include "lldb/Target/Target.h" 22 23 using namespace lldb; 24 using namespace lldb_private; 25 26 //---------------------------------------------------------------------- 27 // BreakpointResolverFileRegex: 28 //---------------------------------------------------------------------- 29 BreakpointResolverFileRegex::BreakpointResolverFileRegex 30 ( 31 Breakpoint *bkpt, 32 RegularExpression ®ex, 33 const std::unordered_set<std::string> &func_names, 34 bool exact_match 35 ) : 36 BreakpointResolver (bkpt, BreakpointResolver::FileLineResolver), 37 m_regex (regex), 38 m_exact_match (exact_match), 39 m_function_names(func_names) 40 { 41 } 42 43 BreakpointResolverFileRegex::~BreakpointResolverFileRegex () 44 { 45 } 46 47 Searcher::CallbackReturn 48 BreakpointResolverFileRegex::SearchCallback 49 ( 50 SearchFilter &filter, 51 SymbolContext &context, 52 Address *addr, 53 bool containing 54 ) 55 { 56 57 assert (m_breakpoint != NULL); 58 if (!context.target_sp) 59 return eCallbackReturnContinue; 60 61 CompileUnit *cu = context.comp_unit; 62 FileSpec cu_file_spec = *(static_cast<FileSpec *>(cu)); 63 std::vector<uint32_t> line_matches; 64 context.target_sp->GetSourceManager().FindLinesMatchingRegex(cu_file_spec, m_regex, 1, UINT32_MAX, line_matches); 65 66 uint32_t num_matches = line_matches.size(); 67 for (uint32_t i = 0; i < num_matches; i++) 68 { 69 SymbolContextList sc_list; 70 const bool search_inlines = false; 71 72 cu->ResolveSymbolContext (cu_file_spec, line_matches[i], search_inlines, m_exact_match, eSymbolContextEverything, sc_list); 73 // Find all the function names: 74 if (!m_function_names.empty()) 75 { 76 std::vector<size_t> sc_to_remove; 77 for (size_t i = 0; i < sc_list.GetSize(); i++) 78 { 79 SymbolContext sc_ctx; 80 sc_list.GetContextAtIndex(i, sc_ctx); 81 std::string name(sc_ctx.GetFunctionName(Mangled::NamePreference::ePreferDemangledWithoutArguments).AsCString()); 82 if (!m_function_names.count(name)) 83 { 84 sc_to_remove.push_back(i); 85 } 86 } 87 88 if (!sc_to_remove.empty()) 89 { 90 std::vector<size_t>::reverse_iterator iter; 91 std::vector<size_t>::reverse_iterator rend = sc_to_remove.rend(); 92 for (iter = sc_to_remove.rbegin(); iter != rend; iter++) 93 { 94 sc_list.RemoveContextAtIndex(*iter); 95 } 96 } 97 } 98 99 const bool skip_prologue = true; 100 101 BreakpointResolver::SetSCMatchesByLine (filter, sc_list, skip_prologue, m_regex.GetText()); 102 } 103 assert (m_breakpoint != NULL); 104 105 return Searcher::eCallbackReturnContinue; 106 } 107 108 Searcher::Depth 109 BreakpointResolverFileRegex::GetDepth() 110 { 111 return Searcher::eDepthCompUnit; 112 } 113 114 void 115 BreakpointResolverFileRegex::GetDescription (Stream *s) 116 { 117 s->Printf ("source regex = \"%s\", exact_match = %d", m_regex.GetText(), m_exact_match); 118 } 119 120 void 121 BreakpointResolverFileRegex::Dump (Stream *s) const 122 { 123 124 } 125 126 lldb::BreakpointResolverSP 127 BreakpointResolverFileRegex::CopyForBreakpoint (Breakpoint &breakpoint) 128 { 129 lldb::BreakpointResolverSP ret_sp(new BreakpointResolverFileRegex(&breakpoint, m_regex, m_function_names, m_exact_match)); 130 return ret_sp; 131 } 132 133 void 134 BreakpointResolverFileRegex::AddFunctionName(const char *func_name) 135 { 136 m_function_names.insert(func_name); 137 } 138 139