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