1 /* Macros for general registry objects.
3 Copyright (C) 2011-2020 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
23 #include <type_traits>
25 /* The macros here implement a template type and functions for
26 associating some user data with a container object.
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.
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.
43 The exported API is best used via the wrapper macros:
45 - register_TAG_data(TAG)
46 Get a new key for the container type TAG.
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
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.
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.
61 - set_TAG_data(TAG, OBJECT, KEY, DATA)
62 Set the data on an object.
64 - TAG_data(TAG, OBJECT, KEY)
65 Fetch the data for an object; returns NULL if it has not been set.
68 /* This structure is used in a container to hold the data that the
71 struct registry_fields
77 /* This macro is used in a container struct definition to define the
78 fields used by the registry code. */
80 #define REGISTRY_FIELDS \
81 struct registry_fields registry_data
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. */
87 #define REGISTRY_ACCESS_FIELD(CONTAINER) \
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
;
98 /* Registry callbacks have this type. */
99 typedef void (*registry_data_callback
) (struct registry_container
*, void *);
104 registry_data_callback save
;
105 registry_data_callback free
;
108 struct registry_data_registration
110 struct registry_data
*data
;
111 struct registry_data_registration
*next
;
114 struct registry_data_registry
116 struct registry_data_registration
*registrations
;
117 unsigned num_registrations
;
120 /* Registry backend functions. Client code uses the frontend
121 functions defined by DEFINE_REGISTRY below instead. */
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
);
128 void registry_alloc_data (struct registry_data_registry
*registry
,
129 struct registry_fields
*registry_fields
);
131 /* Cast FUNC and CONTAINER to the real types, and call FUNC, also
133 typedef void (*registry_callback_adaptor
) (registry_data_callback func
,
134 struct registry_container
*container
,
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
);
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
);
147 void registry_set_data (struct registry_fields
*fields
,
148 const struct registry_data
*data
,
151 void *registry_data (struct registry_fields
*fields
,
152 const struct registry_data
*data
);
154 /* Define a new registry implementation. */
156 #define DEFINE_REGISTRY(TAG, ACCESS) \
157 struct registry_data_registry TAG ## _data_registry = { NULL, 0 }; \
159 const struct TAG ## _data * \
160 register_ ## TAG ## _data_with_cleanup (void (*save) (struct TAG *, void *), \
161 void (*free) (struct TAG *, void *)) \
163 return (struct TAG ## _data *) \
164 register_data_with_cleanup (&TAG ## _data_registry, \
165 (registry_data_callback) save, \
166 (registry_data_callback) free); \
169 const struct TAG ## _data * \
170 register_ ## TAG ## _data (void) \
172 return register_ ## TAG ## _data_with_cleanup (NULL, NULL); \
176 TAG ## _alloc_data (struct TAG *container) \
178 struct registry_fields *rdata = &ACCESS (container)->registry_data; \
180 registry_alloc_data (&TAG ## _data_registry, rdata); \
184 TAG ## registry_callback_adaptor (registry_data_callback func, \
185 struct registry_container *container, \
188 struct TAG *tagged_container = (struct TAG *) container; \
190 registry_ ## TAG ## _callback tagged_func \
191 = (registry_ ## TAG ## _callback) func; \
193 tagged_func (tagged_container, data); \
197 clear_ ## TAG ## _data (struct TAG *container) \
199 struct registry_fields *rdata = &ACCESS (container)->registry_data; \
201 registry_clear_data (&TAG ## _data_registry, \
202 TAG ## registry_callback_adaptor, \
203 (struct registry_container *) container, \
208 TAG ## _free_data (struct TAG *container) \
210 struct registry_fields *rdata = &ACCESS (container)->registry_data; \
212 registry_container_free_data (&TAG ## _data_registry, \
213 TAG ## registry_callback_adaptor, \
214 (struct registry_container *) container, \
219 set_ ## TAG ## _data (struct TAG *container, \
220 const struct TAG ## _data *data, \
223 struct registry_fields *rdata = &ACCESS (container)->registry_data; \
225 registry_set_data (rdata, \
226 (struct registry_data *) data, \
231 TAG ## _data (struct TAG *container, const struct TAG ## _data *data) \
233 struct registry_fields *rdata = &ACCESS (container)->registry_data; \
235 return registry_data (rdata, \
236 (struct registry_data *) data); \
240 /* External declarations for the registry functions. */
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, \
252 extern void *TAG ## _data (struct TAG *, \
253 const struct TAG ## _data *data); \
255 template<typename DATA, typename Deleter = std::default_delete<DATA>> \
261 : m_key (register_ ## TAG ## _data_with_cleanup (nullptr, \
266 DATA *get (struct TAG *obj) const \
268 return (DATA *) TAG ## _data (obj, m_key); \
271 void set (struct TAG *obj, DATA *data) const \
273 set_ ## TAG ## _data (obj, m_key, data); \
276 template<typename Dummy = DATA *, typename... Args> \
277 typename std::enable_if<std::is_same<Deleter, \
278 std::default_delete<DATA>>::value, \
280 emplace (struct TAG *obj, Args &&...args) const \
282 DATA *result = new DATA (std::forward<Args> (args)...); \
287 void clear (struct TAG *obj) const \
289 DATA *datum = get (obj); \
290 if (datum != nullptr) \
292 cleanup (obj, datum); \
293 set (obj, nullptr); \
299 static void cleanup (struct TAG *obj, void *arg) \
301 DATA *datum = (DATA *) arg; \
306 const struct TAG ## _data *m_key; \
309 #endif /* REGISTRY_H */