1 //===-- BreakpointName.h --------------------------------------------*- 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 #ifndef liblldb_Breakpoint_Name_h_
10 #define liblldb_Breakpoint_Name_h_
11 
12 #include <memory>
13 #include <string>
14 #include <unordered_set>
15 #include <vector>
16 
17 #include "lldb/Breakpoint/BreakpointID.h"
18 #include "lldb/Breakpoint/BreakpointLocationCollection.h"
19 #include "lldb/Breakpoint/BreakpointLocationList.h"
20 #include "lldb/Breakpoint/BreakpointOptions.h"
21 #include "lldb/Breakpoint/Stoppoint.h"
22 #include "lldb/Core/SearchFilter.h"
23 #include "lldb/Utility/Event.h"
24 #include "lldb/Utility/Flags.h"
25 #include "lldb/Utility/StringList.h"
26 #include "lldb/Utility/StructuredData.h"
27 
28 namespace lldb_private {
29 
30 class BreakpointName {
31 public:
32   class Permissions
33   {
34   public:
35 
36     enum PermissionKinds { listPerm = 0, disablePerm = 1,
37                        deletePerm = 2, allPerms = 3 };
38 
39     Permissions(bool in_list, bool in_disable, bool in_delete)
40     {
41       m_permissions[listPerm]    = in_list;
42       m_permissions[disablePerm] = in_disable;
43       m_permissions[deletePerm]  = in_delete;
44       m_set_mask.Set(permissions_mask[allPerms]);
45     }
46 
47     Permissions(const Permissions &rhs)
48     {
49       m_permissions[listPerm]    = rhs.m_permissions[listPerm];
50       m_permissions[disablePerm] = rhs.m_permissions[disablePerm];
51       m_permissions[deletePerm]  = rhs.m_permissions[deletePerm];
52       m_set_mask = rhs.m_set_mask;
53     }
54 
55     Permissions()
56     {
57       m_permissions[listPerm]    = true;
58       m_permissions[disablePerm] = true;
59       m_permissions[deletePerm]  = true;
60       m_set_mask.Clear();
61     }
62 
63     const Permissions &operator= (const Permissions &rhs)
64     {
65       if (this != &rhs) {
66         m_permissions[listPerm]    = rhs.m_permissions[listPerm];
67         m_permissions[disablePerm] = rhs.m_permissions[disablePerm];
68         m_permissions[deletePerm]  = rhs.m_permissions[deletePerm];
69         m_set_mask = rhs.m_set_mask;
70       }
71       return *this;
72     }
73 
74     void Clear() {
75       *this = Permissions();
76     }
77 
78     // Merge the permissions from incoming into this set of permissions. Only
79     // merge set permissions, and most restrictive permission wins.
80     void MergeInto(const Permissions &incoming)
81     {
82       MergePermission(incoming, listPerm);
83       MergePermission(incoming, disablePerm);
84       MergePermission(incoming, deletePerm);
85     }
86 
87     bool GetAllowList() const { return GetPermission(listPerm); }
88     bool SetAllowList(bool value) { return SetPermission(listPerm, value); }
89 
90     bool GetAllowDelete() const { return GetPermission(deletePerm); }
91     bool SetAllowDelete(bool value) { return SetPermission(deletePerm, value); }
92 
93     bool GetAllowDisable() const { return GetPermission(disablePerm); }
94     bool SetAllowDisable(bool value) { return SetPermission(disablePerm,
95                                                             value); }
96 
97     bool GetPermission(enum PermissionKinds permission) const
98     {
99       return m_permissions[permission];
100     }
101 
102     bool GetDescription(Stream *s, lldb::DescriptionLevel level);
103 
104     bool IsSet(enum PermissionKinds permission) const
105     {
106       return m_set_mask.Test(permissions_mask[permission]);
107     }
108 
109     bool AnySet() {
110       return m_set_mask.AnySet(permissions_mask[allPerms]);
111     }
112 
113   private:
114     static const Flags::ValueType permissions_mask[allPerms + 1];
115 
116     bool m_permissions[allPerms];
117     Flags m_set_mask;
118 
119     bool SetPermission(enum PermissionKinds permission, bool value)
120     {
121       bool old_value = m_permissions[permission];
122       m_permissions[permission] = value;
123       m_set_mask.Set(permissions_mask[permission]);
124       return old_value;
125     }
126 
127     // If either side disallows the permission, the resultant disallows it.
128     void MergePermission(const Permissions &incoming,
129                          enum PermissionKinds permission)
130     {
131       if (incoming.IsSet(permission))
132       {
133         SetPermission(permission, !(m_permissions[permission] |
134             incoming.m_permissions[permission]));
135       }
136     }
137   };
138 
139   BreakpointName(ConstString name, const char *help = nullptr) :
140       m_name(name), m_options(false)
141    {
142      SetHelp(help);
143    }
144 
145   BreakpointName(ConstString name,
146                  BreakpointOptions &options,
147                  const Permissions &permissions = Permissions(),
148                  const char *help = nullptr) :
149       m_name(name), m_options(options),
150       m_permissions(permissions) {
151         SetHelp(help);
152   };
153 
154   BreakpointName(const BreakpointName &rhs) :
155       m_name(rhs.m_name), m_options(rhs.m_options),
156       m_permissions(rhs.m_permissions), m_help(rhs.m_help)
157   {}
158 
159   BreakpointName(ConstString name, const Breakpoint &bkpt,
160                  const char *help);
161 
162   ConstString GetName() const { return m_name; }
163   BreakpointOptions &GetOptions() { return m_options; }
164   const BreakpointOptions &GetOptions() const { return m_options; }
165 
166   void SetOptions(const BreakpointOptions &options) {
167     m_options = options;
168   }
169 
170   Permissions &GetPermissions() { return m_permissions; }
171   const Permissions &GetPermissions() const { return m_permissions; }
172   void SetPermissions(const Permissions &permissions) {
173     m_permissions = permissions;
174   }
175 
176   bool GetPermission(Permissions::PermissionKinds permission) const
177   {
178     return m_permissions.GetPermission(permission);
179   }
180 
181   void SetHelp(const char *description)
182   {
183     if (description)
184       m_help.assign(description);
185     else
186       m_help.clear();
187   }
188 
189   const char *GetHelp()
190   {
191     return m_help.c_str();
192   }
193 
194   // Returns true if any options were set in the name
195   bool GetDescription(Stream *s, lldb::DescriptionLevel level);
196 
197   void ConfigureBreakpoint(lldb::BreakpointSP bp_sp);
198 
199 private:
200   ConstString        m_name;
201   BreakpointOptions  m_options;
202   Permissions        m_permissions;
203   std::string        m_help;
204 };
205 
206 } // namespace lldb_private
207 
208 #endif // liblldb_Breakpoint_Name_h_
209