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
28namespace lldb_private {
29
30class BreakpointName {
31public:
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
199private:
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 // LLDB_BREAKPOINT_BREAKPOINTNAME_H
209