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 LLDB_BREAKPOINT_BREAKPOINTNAME_H
10 #define LLDB_BREAKPOINT_BREAKPOINTNAME_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 
Permissions(bool in_list,bool in_disable,bool in_delete)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 
Permissions(const Permissions & rhs)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 
Permissions()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 
Clear()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.
MergeInto(const Permissions & incoming)80     void MergeInto(const Permissions &incoming)
81     {
82       MergePermission(incoming, listPerm);
83       MergePermission(incoming, disablePerm);
84       MergePermission(incoming, deletePerm);
85     }
86 
GetAllowList()87     bool GetAllowList() const { return GetPermission(listPerm); }
SetAllowList(bool value)88     bool SetAllowList(bool value) { return SetPermission(listPerm, value); }
89 
GetAllowDelete()90     bool GetAllowDelete() const { return GetPermission(deletePerm); }
SetAllowDelete(bool value)91     bool SetAllowDelete(bool value) { return SetPermission(deletePerm, value); }
92 
GetAllowDisable()93     bool GetAllowDisable() const { return GetPermission(disablePerm); }
SetAllowDisable(bool value)94     bool SetAllowDisable(bool value) { return SetPermission(disablePerm,
95                                                             value); }
96 
GetPermission(enum PermissionKinds permission)97     bool GetPermission(enum PermissionKinds permission) const
98     {
99       return m_permissions[permission];
100     }
101 
102     bool GetDescription(Stream *s, lldb::DescriptionLevel level);
103 
IsSet(enum PermissionKinds permission)104     bool IsSet(enum PermissionKinds permission) const
105     {
106       return m_set_mask.Test(permissions_mask[permission]);
107     }
108 
AnySet()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 
SetPermission(enum PermissionKinds permission,bool value)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.
MergePermission(const Permissions & incoming,enum PermissionKinds permission)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) :
m_name(name)140       m_name(name), m_options(false)
141    {
142      SetHelp(help);
143    }
144 
BreakpointName(const BreakpointName & rhs)145   BreakpointName(const BreakpointName &rhs) :
146       m_name(rhs.m_name), m_options(rhs.m_options),
147       m_permissions(rhs.m_permissions), m_help(rhs.m_help)
148   {}
149 
GetName()150   ConstString GetName() const { return m_name; }
GetOptions()151   BreakpointOptions &GetOptions() { return m_options; }
GetOptions()152   const BreakpointOptions &GetOptions() const { return m_options; }
153 
SetOptions(const BreakpointOptions & options)154   void SetOptions(const BreakpointOptions &options) {
155     m_options = options;
156   }
157 
GetPermissions()158   Permissions &GetPermissions() { return m_permissions; }
GetPermissions()159   const Permissions &GetPermissions() const { return m_permissions; }
SetPermissions(const Permissions & permissions)160   void SetPermissions(const Permissions &permissions) {
161     m_permissions = permissions;
162   }
163 
GetPermission(Permissions::PermissionKinds permission)164   bool GetPermission(Permissions::PermissionKinds permission) const
165   {
166     return m_permissions.GetPermission(permission);
167   }
168 
SetHelp(const char * description)169   void SetHelp(const char *description)
170   {
171     if (description)
172       m_help.assign(description);
173     else
174       m_help.clear();
175   }
176 
GetHelp()177   const char *GetHelp()
178   {
179     return m_help.c_str();
180   }
181 
182   // Returns true if any options were set in the name
183   bool GetDescription(Stream *s, lldb::DescriptionLevel level);
184 
185   void ConfigureBreakpoint(lldb::BreakpointSP bp_sp);
186 
187 private:
188   ConstString        m_name;
189   BreakpointOptions  m_options;
190   Permissions        m_permissions;
191   std::string        m_help;
192 };
193 
194 } // namespace lldb_private
195 
196 #endif // LLDB_BREAKPOINT_BREAKPOINTNAME_H
197