Make some TUI globals "static"
[deliverable/binutils-gdb.git] / gdb / registry.h
1 /* Macros for general registry objects.
2
3 Copyright (C) 2011-2019 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20 #ifndef REGISTRY_H
21 #define REGISTRY_H
22
23 #include <type_traits>
24
25 /* The macros here implement a template type and functions for
26 associating some user data with a container object.
27
28 A registry is associated with a struct tag name. To attach a
29 registry to a structure, use DEFINE_REGISTRY. This takes the
30 structure tag and an access method as arguments. In the usual
31 case, where the registry fields appear directly in the struct, you
32 can use the 'REGISTRY_FIELDS' macro to declare the fields in the
33 struct definition, and you can pass 'REGISTRY_ACCESS_FIELD' as the
34 access argument to DEFINE_REGISTRY. In other cases, use
35 REGISTRY_FIELDS to define the fields in the appropriate spot, and
36 then define your own accessor to find the registry field structure
37 given an instance of your type.
38
39 The API user requests a key from a registry during gdb
40 initialization. Later this key can be used to associate some
41 module-specific data with a specific container object.
42
43 The exported API is best used via the wrapper macros:
44
45 - register_TAG_data(TAG)
46 Get a new key for the container type TAG.
47
48 - register_TAG_data_with_cleanup(TAG, SAVE, FREE)
49 Get a new key for the container type TAG.
50 SAVE and FREE are defined as void (*) (struct TAG *object, void *data)
51 When the container object OBJECT is destroyed, first all registered SAVE
52 functions are called.
53 Then all FREE functions are called.
54 Either or both may be NULL. DATA is the data associated with the
55 container object OBJECT.
56
57 - clear_TAG_data(TAG, OBJECT)
58 Clear all the data associated with OBJECT. Should be called by the
59 container implementation when a container object is destroyed.
60
61 - set_TAG_data(TAG, OBJECT, KEY, DATA)
62 Set the data on an object.
63
64 - TAG_data(TAG, OBJECT, KEY)
65 Fetch the data for an object; returns NULL if it has not been set.
66 */
67
68 /* This structure is used in a container to hold the data that the
69 registry uses. */
70
71 struct registry_fields
72 {
73 void **data;
74 unsigned num_data;
75 };
76
77 /* This macro is used in a container struct definition to define the
78 fields used by the registry code. */
79
80 #define REGISTRY_FIELDS \
81 struct registry_fields registry_data
82
83 /* A convenience macro for the typical case where the registry data is
84 kept as fields of the object. This can be passed as the ACCESS
85 method to DEFINE_REGISTRY. */
86
87 #define REGISTRY_ACCESS_FIELD(CONTAINER) \
88 (CONTAINER)
89
90 /* Opaque type representing a container type with a registry. This
91 type is never defined. This is used to factor out common
92 functionality of all struct tag names into common code. IOW,
93 "struct tag name" pointers are cast to and from "struct
94 registry_container" pointers when calling the common registry
95 "backend" functions. */
96 struct registry_container;
97
98 /* Registry callbacks have this type. */
99 typedef void (*registry_data_callback) (struct registry_container *, void *);
100
101 struct registry_data
102 {
103 unsigned index;
104 registry_data_callback save;
105 registry_data_callback free;
106 };
107
108 struct registry_data_registration
109 {
110 struct registry_data *data;
111 struct registry_data_registration *next;
112 };
113
114 struct registry_data_registry
115 {
116 struct registry_data_registration *registrations;
117 unsigned num_registrations;
118 };
119
120 /* Registry backend functions. Client code uses the frontend
121 functions defined by DEFINE_REGISTRY below instead. */
122
123 const struct registry_data *register_data_with_cleanup
124 (struct registry_data_registry *registry,
125 registry_data_callback save,
126 registry_data_callback free);
127
128 void registry_alloc_data (struct registry_data_registry *registry,
129 struct registry_fields *registry_fields);
130
131 /* Cast FUNC and CONTAINER to the real types, and call FUNC, also
132 passing DATA. */
133 typedef void (*registry_callback_adaptor) (registry_data_callback func,
134 struct registry_container *container,
135 void *data);
136
137 void registry_clear_data (struct registry_data_registry *data_registry,
138 registry_callback_adaptor adaptor,
139 struct registry_container *container,
140 struct registry_fields *fields);
141
142 void registry_container_free_data (struct registry_data_registry *data_registry,
143 registry_callback_adaptor adaptor,
144 struct registry_container *container,
145 struct registry_fields *fields);
146
147 void registry_set_data (struct registry_fields *fields,
148 const struct registry_data *data,
149 void *value);
150
151 void *registry_data (struct registry_fields *fields,
152 const struct registry_data *data);
153
154 /* Define a new registry implementation. */
155
156 #define DEFINE_REGISTRY(TAG, ACCESS) \
157 struct registry_data_registry TAG ## _data_registry = { NULL, 0 }; \
158 \
159 const struct TAG ## _data * \
160 register_ ## TAG ## _data_with_cleanup (void (*save) (struct TAG *, void *), \
161 void (*free) (struct TAG *, void *)) \
162 { \
163 return (struct TAG ## _data *) \
164 register_data_with_cleanup (&TAG ## _data_registry, \
165 (registry_data_callback) save, \
166 (registry_data_callback) free); \
167 } \
168 \
169 const struct TAG ## _data * \
170 register_ ## TAG ## _data (void) \
171 { \
172 return register_ ## TAG ## _data_with_cleanup (NULL, NULL); \
173 } \
174 \
175 static void \
176 TAG ## _alloc_data (struct TAG *container) \
177 { \
178 struct registry_fields *rdata = &ACCESS (container)->registry_data; \
179 \
180 registry_alloc_data (&TAG ## _data_registry, rdata); \
181 } \
182 \
183 static void \
184 TAG ## registry_callback_adaptor (registry_data_callback func, \
185 struct registry_container *container, \
186 void *data) \
187 { \
188 struct TAG *tagged_container = (struct TAG *) container; \
189 \
190 registry_ ## TAG ## _callback tagged_func \
191 = (registry_ ## TAG ## _callback) func; \
192 \
193 tagged_func (tagged_container, data); \
194 } \
195 \
196 void \
197 clear_ ## TAG ## _data (struct TAG *container) \
198 { \
199 struct registry_fields *rdata = &ACCESS (container)->registry_data; \
200 \
201 registry_clear_data (&TAG ## _data_registry, \
202 TAG ## registry_callback_adaptor, \
203 (struct registry_container *) container, \
204 rdata); \
205 } \
206 \
207 static void \
208 TAG ## _free_data (struct TAG *container) \
209 { \
210 struct registry_fields *rdata = &ACCESS (container)->registry_data; \
211 \
212 registry_container_free_data (&TAG ## _data_registry, \
213 TAG ## registry_callback_adaptor, \
214 (struct registry_container *) container, \
215 rdata); \
216 } \
217 \
218 void \
219 set_ ## TAG ## _data (struct TAG *container, \
220 const struct TAG ## _data *data, \
221 void *value) \
222 { \
223 struct registry_fields *rdata = &ACCESS (container)->registry_data; \
224 \
225 registry_set_data (rdata, \
226 (struct registry_data *) data, \
227 value); \
228 } \
229 \
230 void * \
231 TAG ## _data (struct TAG *container, const struct TAG ## _data *data) \
232 { \
233 struct registry_fields *rdata = &ACCESS (container)->registry_data; \
234 \
235 return registry_data (rdata, \
236 (struct registry_data *) data); \
237 }
238
239
240 /* External declarations for the registry functions. */
241
242 #define DECLARE_REGISTRY(TAG) \
243 struct TAG ## _data; \
244 typedef void (*registry_ ## TAG ## _callback) (struct TAG *, void *); \
245 extern const struct TAG ## _data *register_ ## TAG ## _data (void); \
246 extern const struct TAG ## _data *register_ ## TAG ## _data_with_cleanup \
247 (registry_ ## TAG ## _callback save, registry_ ## TAG ## _callback free); \
248 extern void clear_ ## TAG ## _data (struct TAG *); \
249 extern void set_ ## TAG ## _data (struct TAG *, \
250 const struct TAG ## _data *data, \
251 void *value); \
252 extern void *TAG ## _data (struct TAG *, \
253 const struct TAG ## _data *data); \
254 \
255 template<typename DATA, typename Deleter = std::default_delete<DATA>> \
256 class TAG ## _key \
257 { \
258 public: \
259 \
260 TAG ## _key () \
261 : m_key (register_ ## TAG ## _data_with_cleanup (nullptr, \
262 cleanup)) \
263 { \
264 } \
265 \
266 DATA *get (struct TAG *obj) const \
267 { \
268 return (DATA *) TAG ## _data (obj, m_key); \
269 } \
270 \
271 void set (struct TAG *obj, DATA *data) const \
272 { \
273 set_ ## TAG ## _data (obj, m_key, data); \
274 } \
275 \
276 template<typename Dummy = DATA *, typename... Args> \
277 typename std::enable_if<std::is_same<Deleter, \
278 std::default_delete<DATA>>::value, \
279 Dummy>::type \
280 emplace (struct TAG *obj, Args &&...args) const \
281 { \
282 DATA *result = new DATA (std::forward<Args> (args)...); \
283 set (obj, result); \
284 return result; \
285 } \
286 \
287 void clear (struct TAG *obj) const \
288 { \
289 DATA *datum = get (obj); \
290 if (datum != nullptr) \
291 { \
292 cleanup (obj, datum); \
293 set (obj, nullptr); \
294 } \
295 } \
296 \
297 private: \
298 \
299 static void cleanup (struct TAG *obj, void *arg) \
300 { \
301 DATA *datum = (DATA *) arg; \
302 Deleter d; \
303 d (datum); \
304 } \
305 \
306 const struct TAG ## _data *m_key; \
307 };
308
309 #endif /* REGISTRY_H */
This page took 0.044861 seconds and 4 git commands to generate.