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
22using namespace lldb;
23using namespace lldb_private;
24
25//----------------------------------------------------------------------
26// BreakpointLocationCollection constructor
27//----------------------------------------------------------------------
28BreakpointLocationCollection::BreakpointLocationCollection() :
29    m_break_loc_collection()
30{
31}
32
33//----------------------------------------------------------------------
34// Destructor
35//----------------------------------------------------------------------
36BreakpointLocationCollection::~BreakpointLocationCollection()
37{
38}
39
40void
41BreakpointLocationCollection::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
48bool
49BreakpointLocationCollection::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
61class BreakpointIDPairMatches
62{
63public:
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
76private:
77   const lldb::break_id_t m_break_id;
78   const lldb::break_id_t m_break_loc_id;
79};
80
81BreakpointLocationCollection::collection::iterator
82BreakpointLocationCollection::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
88BreakpointLocationCollection::collection::const_iterator
89BreakpointLocationCollection::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
95BreakpointLocationSP
96BreakpointLocationCollection::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
106const BreakpointLocationSP
107BreakpointLocationCollection::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
117BreakpointLocationSP
118BreakpointLocationCollection::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
127const BreakpointLocationSP
128BreakpointLocationCollection::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
137bool
138BreakpointLocationCollection::ShouldStop (StoppointCallbackContext *context)
139{
140    bool shouldStop = false;
141    const size_t count = GetSize();
142    for (size_t i = 0; i < count; i++)
143    {
144        if (GetByIndex(i)->ShouldStop(context))
145            shouldStop = true;
146    }
147    return shouldStop;
148}
149
150bool
151BreakpointLocationCollection::ValidForThisThread (Thread *thread)
152{
153    collection::iterator pos,
154        begin = m_break_loc_collection.begin(),
155        end = m_break_loc_collection.end();
156
157    for (pos = begin; pos != end; ++pos)
158    {
159        if ((*pos)->ValidForThisThread (thread))
160            return true;
161    }
162    return false;
163}
164
165bool
166BreakpointLocationCollection::IsInternal () const
167{
168    collection::const_iterator pos,
169        begin = m_break_loc_collection.begin(),
170        end = m_break_loc_collection.end();
171
172    bool is_internal = true;
173
174    for (pos = begin; pos != end; ++pos)
175    {
176        if (!(*pos)->GetBreakpoint().IsInternal ())
177        {
178            is_internal = false;
179            break;
180        }
181    }
182    return is_internal;
183}
184
185void
186BreakpointLocationCollection::GetDescription (Stream *s, lldb::DescriptionLevel level)
187{
188    collection::iterator pos,
189        begin = m_break_loc_collection.begin(),
190        end = m_break_loc_collection.end();
191
192    for (pos = begin; pos != end; ++pos)
193    {
194        if (pos != begin)
195            s->PutChar(' ');
196        (*pos)->GetDescription(s, level);
197    }
198}
199