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