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 #include "lldb/lldb-private-log.h"
23 
24 using namespace lldb;
25 using namespace lldb_private;
26 
27 //----------------------------------------------------------------------
28 // BreakpointResolverFileRegex:
29 //----------------------------------------------------------------------
BreakpointResolverFileRegex(Breakpoint * bkpt,RegularExpression & regex)30 BreakpointResolverFileRegex::BreakpointResolverFileRegex
31 (
32     Breakpoint *bkpt,
33     RegularExpression &regex
34 ) :
35     BreakpointResolver (bkpt, BreakpointResolver::FileLineResolver),
36     m_regex (regex)
37 {
38 }
39 
~BreakpointResolverFileRegex()40 BreakpointResolverFileRegex::~BreakpointResolverFileRegex ()
41 {
42 }
43 
44 Searcher::CallbackReturn
SearchCallback(SearchFilter & filter,SymbolContext & context,Address * addr,bool containing)45 BreakpointResolverFileRegex::SearchCallback
46 (
47     SearchFilter &filter,
48     SymbolContext &context,
49     Address *addr,
50     bool containing
51 )
52 {
53 
54     assert (m_breakpoint != NULL);
55     if (!context.target_sp)
56         return eCallbackReturnContinue;
57 
58     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
59 
60     CompileUnit *cu = context.comp_unit;
61     FileSpec cu_file_spec = *(static_cast<FileSpec *>(cu));
62     std::vector<uint32_t> line_matches;
63     context.target_sp->GetSourceManager().FindLinesMatchingRegex(cu_file_spec, m_regex, 1, UINT32_MAX, line_matches);
64     uint32_t num_matches = line_matches.size();
65     for (uint32_t i = 0; i < num_matches; i++)
66     {
67         uint32_t start_idx = 0;
68         bool exact = false;
69         while (1)
70         {
71             LineEntry line_entry;
72 
73             // Cycle through all the line entries that might match this one:
74             start_idx = cu->FindLineEntry (start_idx, line_matches[i], NULL, exact, &line_entry);
75             if (start_idx == UINT32_MAX)
76                 break;
77             exact = true;
78             start_idx++;
79 
80             Address line_start = line_entry.range.GetBaseAddress();
81             if (line_start.IsValid())
82             {
83                 if (filter.AddressPasses(line_start))
84                 {
85                     BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(line_start));
86                     if (log && bp_loc_sp && !m_breakpoint->IsInternal())
87                     {
88                         StreamString s;
89                         bp_loc_sp->GetDescription (&s, lldb::eDescriptionLevelVerbose);
90                         log->Printf ("Added location: %s\n", s.GetData());
91                     }
92                 }
93                 else if (log)
94                 {
95                     log->Printf ("Breakpoint at file address 0x%" PRIx64 " for %s:%d didn't pass filter.\n",
96                                  line_start.GetFileAddress(),
97                                  cu_file_spec.GetFilename().AsCString("<Unknown>"),
98                                  line_matches[i]);
99                 }
100             }
101             else
102             {
103                 if (log)
104                     log->Printf ("error: Unable to set breakpoint at file address 0x%" PRIx64 " for %s:%d\n",
105                                  line_start.GetFileAddress(),
106                                  cu_file_spec.GetFilename().AsCString("<Unknown>"),
107                                  line_matches[i]);
108             }
109 
110         }
111     }
112     assert (m_breakpoint != NULL);
113 
114     return Searcher::eCallbackReturnContinue;
115 }
116 
117 Searcher::Depth
GetDepth()118 BreakpointResolverFileRegex::GetDepth()
119 {
120     return Searcher::eDepthCompUnit;
121 }
122 
123 void
GetDescription(Stream * s)124 BreakpointResolverFileRegex::GetDescription (Stream *s)
125 {
126     s->Printf ("source regex = \"%s\"", m_regex.GetText());
127 }
128 
129 void
Dump(Stream * s) const130 BreakpointResolverFileRegex::Dump (Stream *s) const
131 {
132 
133 }
134 
135