1 //===-- BreakpointList.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/BreakpointList.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 
17 using namespace lldb;
18 using namespace lldb_private;
19 
20 BreakpointList::BreakpointList (bool is_internal) :
21     m_mutex (Mutex::eMutexTypeRecursive),
22     m_breakpoints(),
23     m_next_break_id (0),
24     m_is_internal (is_internal)
25 {
26 }
27 
28 BreakpointList::~BreakpointList()
29 {
30 }
31 
32 
33 break_id_t
34 BreakpointList::Add (BreakpointSP &bp)
35 {
36     Mutex::Locker locker(m_mutex);
37     // Internal breakpoint IDs are negative, normal ones are positive
38     bp->SetID (m_is_internal ? --m_next_break_id : ++m_next_break_id);
39     m_breakpoints.push_back(bp);
40     return bp->GetID();
41 }
42 
43 bool
44 BreakpointList::Remove (break_id_t break_id)
45 {
46     Mutex::Locker locker(m_mutex);
47     bp_collection::iterator pos = GetBreakpointIDIterator(break_id);    // Predicate
48     if (pos != m_breakpoints.end())
49     {
50         m_breakpoints.erase(pos);
51         return true;
52     }
53     return false;
54 }
55 
56 void
57 BreakpointList::SetEnabledAll (bool enabled)
58 {
59     Mutex::Locker locker(m_mutex);
60     bp_collection::iterator pos, end = m_breakpoints.end();
61     for (pos = m_breakpoints.begin(); pos != end; ++pos)
62         (*pos)->SetEnabled (enabled);
63 }
64 
65 
66 void
67 BreakpointList::RemoveAll ()
68 {
69     Mutex::Locker locker(m_mutex);
70     ClearAllBreakpointSites ();
71 
72     m_breakpoints.erase (m_breakpoints.begin(), m_breakpoints.end());
73 }
74 
75 class BreakpointIDMatches
76 {
77 public:
78     BreakpointIDMatches (break_id_t break_id) :
79         m_break_id(break_id)
80     {
81     }
82 
83     bool operator() (const BreakpointSP &bp) const
84     {
85         return m_break_id == bp->GetID();
86     }
87 
88 private:
89    const break_id_t m_break_id;
90 };
91 
92 BreakpointList::bp_collection::iterator
93 BreakpointList::GetBreakpointIDIterator (break_id_t break_id)
94 {
95     return std::find_if(m_breakpoints.begin(), m_breakpoints.end(), // Search full range
96                         BreakpointIDMatches(break_id));             // Predicate
97 }
98 
99 BreakpointList::bp_collection::const_iterator
100 BreakpointList::GetBreakpointIDConstIterator (break_id_t break_id) const
101 {
102     return std::find_if(m_breakpoints.begin(), m_breakpoints.end(), // Search full range
103                         BreakpointIDMatches(break_id));             // Predicate
104 }
105 
106 BreakpointSP
107 BreakpointList::FindBreakpointByID (break_id_t break_id)
108 {
109     Mutex::Locker locker(m_mutex);
110     BreakpointSP stop_sp;
111     bp_collection::iterator pos = GetBreakpointIDIterator(break_id);
112     if (pos != m_breakpoints.end())
113         stop_sp = *pos;
114 
115     return stop_sp;
116 }
117 
118 const BreakpointSP
119 BreakpointList::FindBreakpointByID (break_id_t break_id) const
120 {
121     Mutex::Locker locker(m_mutex);
122     BreakpointSP stop_sp;
123     bp_collection::const_iterator pos = GetBreakpointIDConstIterator(break_id);
124     if (pos != m_breakpoints.end())
125         stop_sp = *pos;
126 
127     return stop_sp;
128 }
129 
130 void
131 BreakpointList::Dump (Stream *s) const
132 {
133     Mutex::Locker locker(m_mutex);
134     s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
135     s->Indent();
136     s->Printf("BreakpointList with %u Breakpoints:\n", (uint32_t)m_breakpoints.size());
137     s->IndentMore();
138     bp_collection::const_iterator pos;
139     bp_collection::const_iterator end = m_breakpoints.end();
140     for (pos = m_breakpoints.begin(); pos != end; ++pos)
141         (*pos)->Dump(s);
142     s->IndentLess();
143 }
144 
145 
146 BreakpointSP
147 BreakpointList::GetBreakpointByIndex (uint32_t i)
148 {
149     Mutex::Locker locker(m_mutex);
150     BreakpointSP stop_sp;
151     bp_collection::iterator end = m_breakpoints.end();
152     bp_collection::iterator pos;
153     uint32_t curr_i = 0;
154     for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
155     {
156         if (curr_i == i)
157             stop_sp = *pos;
158     }
159     return stop_sp;
160 }
161 
162 const BreakpointSP
163 BreakpointList::GetBreakpointByIndex (uint32_t i) const
164 {
165     Mutex::Locker locker(m_mutex);
166     BreakpointSP stop_sp;
167     bp_collection::const_iterator end = m_breakpoints.end();
168     bp_collection::const_iterator pos;
169     uint32_t curr_i = 0;
170     for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
171     {
172         if (curr_i == i)
173             stop_sp = *pos;
174     }
175     return stop_sp;
176 }
177 
178 void
179 BreakpointList::UpdateBreakpoints (ModuleList& module_list, bool added)
180 {
181     Mutex::Locker locker(m_mutex);
182     bp_collection::iterator end = m_breakpoints.end();
183     bp_collection::iterator pos;
184     for (pos = m_breakpoints.begin(); pos != end; ++pos)
185         (*pos)->ModulesChanged (module_list, added);
186 
187 }
188 
189 void
190 BreakpointList::ClearAllBreakpointSites ()
191 {
192     Mutex::Locker locker(m_mutex);
193     bp_collection::iterator end = m_breakpoints.end();
194     bp_collection::iterator pos;
195     for (pos = m_breakpoints.begin(); pos != end; ++pos)
196         (*pos)->ClearAllBreakpointSites ();
197 
198 }
199