]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/source/Breakpoint/BreakpointList.cpp
Move all sources from the llvm project into contrib/llvm-project.
[FreeBSD/FreeBSD.git] / contrib / llvm-project / lldb / source / Breakpoint / BreakpointList.cpp
1 //===-- BreakpointList.cpp --------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "lldb/Breakpoint/BreakpointList.h"
10
11 #include "lldb/Target/Target.h"
12
13 using namespace lldb;
14 using namespace lldb_private;
15
16 static void NotifyChange(const BreakpointSP &bp, BreakpointEventType event) {
17   Target &target = bp->GetTarget();
18   if (target.EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
19     target.BroadcastEvent(Target::eBroadcastBitBreakpointChanged,
20                           new Breakpoint::BreakpointEventData(event, bp));
21 }
22
23 BreakpointList::BreakpointList(bool is_internal)
24     : m_mutex(), m_breakpoints(), m_next_break_id(0),
25       m_is_internal(is_internal) {}
26
27 BreakpointList::~BreakpointList() {}
28
29 break_id_t BreakpointList::Add(BreakpointSP &bp_sp, bool notify) {
30   std::lock_guard<std::recursive_mutex> guard(m_mutex);
31
32   // Internal breakpoint IDs are negative, normal ones are positive
33   bp_sp->SetID(m_is_internal ? --m_next_break_id : ++m_next_break_id);
34
35   m_breakpoints.push_back(bp_sp);
36
37   if (notify)
38     NotifyChange(bp_sp, eBreakpointEventTypeAdded);
39
40   return bp_sp->GetID();
41 }
42
43 bool BreakpointList::Remove(break_id_t break_id, bool notify) {
44   std::lock_guard<std::recursive_mutex> guard(m_mutex);
45
46   auto it = std::find_if(
47       m_breakpoints.begin(), m_breakpoints.end(),
48       [&](const BreakpointSP &bp) { return bp->GetID() == break_id; });
49
50   if (it == m_breakpoints.end())
51     return false;
52
53   if (notify)
54     NotifyChange(*it, eBreakpointEventTypeRemoved);
55
56   m_breakpoints.erase(it);
57
58   return true;
59 }
60
61 void BreakpointList::RemoveInvalidLocations(const ArchSpec &arch) {
62   std::lock_guard<std::recursive_mutex> guard(m_mutex);
63   for (const auto &bp_sp : m_breakpoints)
64     bp_sp->RemoveInvalidLocations(arch);
65 }
66
67 void BreakpointList::SetEnabledAll(bool enabled) {
68   std::lock_guard<std::recursive_mutex> guard(m_mutex);
69   for (const auto &bp_sp : m_breakpoints)
70     bp_sp->SetEnabled(enabled);
71 }
72
73 void BreakpointList::SetEnabledAllowed(bool enabled) {
74   std::lock_guard<std::recursive_mutex> guard(m_mutex);
75   for (const auto &bp_sp : m_breakpoints)
76     if (bp_sp->AllowDisable())
77       bp_sp->SetEnabled(enabled);
78 }
79
80 void BreakpointList::RemoveAll(bool notify) {
81   std::lock_guard<std::recursive_mutex> guard(m_mutex);
82   ClearAllBreakpointSites();
83
84   if (notify) {
85     for (const auto &bp_sp : m_breakpoints)
86       NotifyChange(bp_sp, eBreakpointEventTypeRemoved);
87   }
88
89   m_breakpoints.clear();
90 }
91
92 void BreakpointList::RemoveAllowed(bool notify) {
93   std::lock_guard<std::recursive_mutex> guard(m_mutex);
94
95   for (const auto &bp_sp : m_breakpoints) {
96     if (bp_sp->AllowDelete())
97       bp_sp->ClearAllBreakpointSites();
98     if (notify)
99       NotifyChange(bp_sp, eBreakpointEventTypeRemoved);
100   }
101
102   m_breakpoints.erase(
103       std::remove_if(m_breakpoints.begin(), m_breakpoints.end(),
104                      [&](const BreakpointSP &bp) { return bp->AllowDelete(); }),
105       m_breakpoints.end());
106 }
107
108 BreakpointList::bp_collection::iterator
109 BreakpointList::GetBreakpointIDIterator(break_id_t break_id) {
110   return std::find_if(
111       m_breakpoints.begin(), m_breakpoints.end(),
112       [&](const BreakpointSP &bp) { return bp->GetID() == break_id; });
113 }
114
115 BreakpointList::bp_collection::const_iterator
116 BreakpointList::GetBreakpointIDConstIterator(break_id_t break_id) const {
117   return std::find_if(
118       m_breakpoints.begin(), m_breakpoints.end(),
119       [&](const BreakpointSP &bp) { return bp->GetID() == break_id; });
120 }
121
122 BreakpointSP BreakpointList::FindBreakpointByID(break_id_t break_id) const {
123   std::lock_guard<std::recursive_mutex> guard(m_mutex);
124
125   auto it = GetBreakpointIDConstIterator(break_id);
126   if (it != m_breakpoints.end())
127     return *it;
128   return {};
129 }
130
131 bool BreakpointList::FindBreakpointsByName(const char *name,
132                                            BreakpointList &matching_bps) {
133   Status error;
134   if (!name)
135     return false;
136
137   if (!BreakpointID::StringIsBreakpointName(llvm::StringRef(name), error))
138     return false;
139
140   for (BreakpointSP bkpt_sp : Breakpoints()) {
141     if (bkpt_sp->MatchesName(name)) {
142       matching_bps.Add(bkpt_sp, false);
143     }
144   }
145
146   return true;
147 }
148
149 void BreakpointList::Dump(Stream *s) const {
150   std::lock_guard<std::recursive_mutex> guard(m_mutex);
151   s->Printf("%p: ", static_cast<const void *>(this));
152   s->Indent();
153   s->Printf("BreakpointList with %u Breakpoints:\n",
154             (uint32_t)m_breakpoints.size());
155   s->IndentMore();
156   for (const auto &bp_sp : m_breakpoints)
157     bp_sp->Dump(s);
158   s->IndentLess();
159 }
160
161 BreakpointSP BreakpointList::GetBreakpointAtIndex(size_t i) const {
162   std::lock_guard<std::recursive_mutex> guard(m_mutex);
163   if (i < m_breakpoints.size())
164     return m_breakpoints[i];
165   return {};
166 }
167
168 void BreakpointList::UpdateBreakpoints(ModuleList &module_list, bool added,
169                                        bool delete_locations) {
170   std::lock_guard<std::recursive_mutex> guard(m_mutex);
171   for (const auto &bp_sp : m_breakpoints)
172     bp_sp->ModulesChanged(module_list, added, delete_locations);
173 }
174
175 void BreakpointList::UpdateBreakpointsWhenModuleIsReplaced(
176     ModuleSP old_module_sp, ModuleSP new_module_sp) {
177   std::lock_guard<std::recursive_mutex> guard(m_mutex);
178   for (const auto &bp_sp : m_breakpoints)
179     bp_sp->ModuleReplaced(old_module_sp, new_module_sp);
180 }
181
182 void BreakpointList::ClearAllBreakpointSites() {
183   std::lock_guard<std::recursive_mutex> guard(m_mutex);
184   for (const auto &bp_sp : m_breakpoints)
185     bp_sp->ClearAllBreakpointSites();
186 }
187
188 void BreakpointList::GetListMutex(
189     std::unique_lock<std::recursive_mutex> &lock) {
190   lock = std::unique_lock<std::recursive_mutex>(m_mutex);
191 }