1 //===-- BreakpointLocationCollection.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 
11 // C Includes
12 // C++ Includes
13 // Other libraries and framework includes
14 // Project includes
15 #include "lldb/Breakpoint/BreakpointLocationCollection.h"
16 #include "lldb/Core/ModuleList.h"
17 #include "lldb/Breakpoint/Breakpoint.h"
18 #include "lldb/Breakpoint/BreakpointLocation.h"
19 #include "lldb/Breakpoint/BreakpointLocationList.h"
20 #include "lldb/Target/Thread.h"
21 #include "lldb/Target/ThreadSpec.h"
22 
23 using namespace lldb;
24 using namespace lldb_private;
25 
26 //----------------------------------------------------------------------
27 // BreakpointLocationCollection constructor
28 //----------------------------------------------------------------------
29 BreakpointLocationCollection::BreakpointLocationCollection() :
30     m_break_loc_collection()
31 {
32 }
33 
34 //----------------------------------------------------------------------
35 // Destructor
36 //----------------------------------------------------------------------
37 BreakpointLocationCollection::~BreakpointLocationCollection()
38 {
39 }
40 
41 void
42 BreakpointLocationCollection::Add(const BreakpointLocationSP &bp_loc)
43 {
44     BreakpointLocationSP old_bp_loc = FindByIDPair (bp_loc->GetBreakpoint().GetID(), bp_loc->GetID());
45     if (!old_bp_loc.get())
46         m_break_loc_collection.push_back(bp_loc);
47 }
48 
49 bool
50 BreakpointLocationCollection::Remove (lldb::break_id_t bp_id, lldb::break_id_t bp_loc_id)
51 {
52     collection::iterator pos = GetIDPairIterator(bp_id, bp_loc_id);    // Predicate
53     if (pos != m_break_loc_collection.end())
54     {
55         m_break_loc_collection.erase(pos);
56         return true;
57     }
58     return false;
59 
60 }
61 
62 class BreakpointIDPairMatches
63 {
64 public:
65     BreakpointIDPairMatches (lldb::break_id_t break_id, lldb::break_id_t break_loc_id) :
66         m_break_id(break_id),
67         m_break_loc_id (break_loc_id)
68     {
69     }
70 
71     bool operator() (const BreakpointLocationSP &bp_loc) const
72     {
73         return m_break_id == bp_loc->GetBreakpoint().GetID()
74             && m_break_loc_id == bp_loc->GetID();
75     }
76 
77 private:
78    const lldb::break_id_t m_break_id;
79    const lldb::break_id_t m_break_loc_id;
80 };
81 
82 BreakpointLocationCollection::collection::iterator
83 BreakpointLocationCollection::GetIDPairIterator (lldb::break_id_t break_id, lldb::break_id_t break_loc_id)
84 {
85     return std::find_if(m_break_loc_collection.begin(), m_break_loc_collection.end(),   // Search full range
86                         BreakpointIDPairMatches(break_id, break_loc_id));               // Predicate
87 }
88 
89 BreakpointLocationCollection::collection::const_iterator
90 BreakpointLocationCollection::GetIDPairConstIterator (lldb::break_id_t break_id, lldb::break_id_t break_loc_id) const
91 {
92     return std::find_if(m_break_loc_collection.begin(), m_break_loc_collection.end(),   // Search full range
93                         BreakpointIDPairMatches(break_id, break_loc_id));               // Predicate
94 }
95 
96 BreakpointLocationSP
97 BreakpointLocationCollection::FindByIDPair (lldb::break_id_t break_id, lldb::break_id_t break_loc_id)
98 {
99     BreakpointLocationSP stop_sp;
100     collection::iterator pos = GetIDPairIterator(break_id, break_loc_id);
101     if (pos != m_break_loc_collection.end())
102         stop_sp = *pos;
103 
104     return stop_sp;
105 }
106 
107 const BreakpointLocationSP
108 BreakpointLocationCollection::FindByIDPair (lldb::break_id_t break_id, lldb::break_id_t break_loc_id) const
109 {
110     BreakpointLocationSP stop_sp;
111     collection::const_iterator pos = GetIDPairConstIterator(break_id, break_loc_id);
112     if (pos != m_break_loc_collection.end())
113         stop_sp = *pos;
114 
115     return stop_sp;
116 }
117 
118 BreakpointLocationSP
119 BreakpointLocationCollection::GetByIndex (uint32_t i)
120 {
121     BreakpointLocationSP stop_sp;
122     if (i < m_break_loc_collection.size())
123         stop_sp = m_break_loc_collection[i];
124 
125     return stop_sp;
126 }
127 
128 const BreakpointLocationSP
129 BreakpointLocationCollection::GetByIndex (uint32_t i) const
130 {
131     BreakpointLocationSP stop_sp;
132     if (i < m_break_loc_collection.size())
133         stop_sp = m_break_loc_collection[i];
134 
135     return stop_sp;
136 }
137 
138 bool
139 BreakpointLocationCollection::ShouldStop (StoppointCallbackContext *context)
140 {
141     bool shouldStop = false;
142     const size_t count = GetSize();
143     for (size_t i = 0; i < count; i++)
144     {
145         if (GetByIndex(i)->ShouldStop(context))
146             shouldStop = true;
147     }
148     return shouldStop;
149 }
150 
151 bool
152 BreakpointLocationCollection::ValidForThisThread (Thread *thread)
153 {
154     collection::iterator pos,
155         begin = m_break_loc_collection.begin(),
156         end = m_break_loc_collection.end();
157 
158     for (pos = begin; pos != end; ++pos)
159     {
160         if ((*pos)->ValidForThisThread (thread))
161             return true;
162     }
163     return false;
164 }
165 
166 
167 void
168 BreakpointLocationCollection::GetDescription (Stream *s, lldb::DescriptionLevel level)
169 {
170     collection::iterator pos,
171         begin = m_break_loc_collection.begin(),
172         end = m_break_loc_collection.end();
173 
174     for (pos = begin; pos != end; ++pos)
175     {
176         if (pos != begin)
177             s->PutChar(' ');
178         (*pos)->GetDescription(s, level);
179     }
180 }
181