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