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 &regex,
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