Fix library segment-address for 64bit values
[deliverable/binutils-gdb.git] / gdb / registry.h
CommitLineData
8e260fc0
TT
1/* Macros for general registry objects.
2
11bc5fe4 3 Copyright (C) 2011-2020 Free Software Foundation, Inc.
8e260fc0
TT
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
5f6e90a0
TT
23#include <type_traits>
24
8e260fc0
TT
25/* The macros here implement a template type and functions for
26 associating some user data with a container object.
27
6b81941e
TT
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
8e260fc0
TT
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
8e260fc0
TT
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.
487ad57c
YQ
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
8e260fc0
TT
52 functions are called.
53 Then all FREE functions are called.
487ad57c
YQ
54 Either or both may be NULL. DATA is the data associated with the
55 container object OBJECT.
8e260fc0
TT
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
6b81941e
TT
68/* This structure is used in a container to hold the data that the
69 registry uses. */
70
71struct registry_fields
72{
73 void **data;
74 unsigned num_data;
75};
76
8e260fc0
TT
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 \
6b81941e
TT
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)
8e260fc0 89
aa0fbdd8
PA
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. */
96struct registry_container;
97
98/* Registry callbacks have this type. */
99typedef void (*registry_data_callback) (struct registry_container *, void *);
100
101struct registry_data
102{
103 unsigned index;
104 registry_data_callback save;
105 registry_data_callback free;
106};
107
108struct registry_data_registration
109{
110 struct registry_data *data;
111 struct registry_data_registration *next;
112};
113
114struct 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
123const struct registry_data *register_data_with_cleanup
124 (struct registry_data_registry *registry,
125 registry_data_callback save,
126 registry_data_callback free);
127
128void 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. */
133typedef void (*registry_callback_adaptor) (registry_data_callback func,
134 struct registry_container *container,
135 void *data);
136
137void 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
142void 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
147void registry_set_data (struct registry_fields *fields,
148 const struct registry_data *data,
149 void *value);
150
151void *registry_data (struct registry_fields *fields,
152 const struct registry_data *data);
153
8e260fc0
TT
154/* Define a new registry implementation. */
155
6b81941e 156#define DEFINE_REGISTRY(TAG, ACCESS) \
aa0fbdd8 157struct registry_data_registry TAG ## _data_registry = { NULL, 0 }; \
8e260fc0
TT
158 \
159const struct TAG ## _data * \
160register_ ## TAG ## _data_with_cleanup (void (*save) (struct TAG *, void *), \
aa0fbdd8 161 void (*free) (struct TAG *, void *)) \
8e260fc0 162{ \
aa0fbdd8
PA
163 return (struct TAG ## _data *) \
164 register_data_with_cleanup (&TAG ## _data_registry, \
165 (registry_data_callback) save, \
166 (registry_data_callback) free); \
8e260fc0
TT
167} \
168 \
169const struct TAG ## _data * \
170register_ ## TAG ## _data (void) \
171{ \
172 return register_ ## TAG ## _data_with_cleanup (NULL, NULL); \
173} \
174 \
175static void \
176TAG ## _alloc_data (struct TAG *container) \
177{ \
6b81941e 178 struct registry_fields *rdata = &ACCESS (container)->registry_data; \
aa0fbdd8
PA
179 \
180 registry_alloc_data (&TAG ## _data_registry, rdata); \
8e260fc0
TT
181} \
182 \
aa0fbdd8
PA
183static void \
184TAG ## registry_callback_adaptor (registry_data_callback func, \
185 struct registry_container *container, \
186 void *data) \
8e260fc0 187{ \
aa0fbdd8 188 struct TAG *tagged_container = (struct TAG *) container; \
8e260fc0 189 \
aa0fbdd8
PA
190 registry_ ## TAG ## _callback tagged_func \
191 = (registry_ ## TAG ## _callback) func; \
8e260fc0 192 \
aa0fbdd8
PA
193 tagged_func (tagged_container, data); \
194} \
8e260fc0 195 \
aa0fbdd8
PA
196void \
197clear_ ## TAG ## _data (struct TAG *container) \
198{ \
199 struct registry_fields *rdata = &ACCESS (container)->registry_data; \
8e260fc0 200 \
aa0fbdd8
PA
201 registry_clear_data (&TAG ## _data_registry, \
202 TAG ## registry_callback_adaptor, \
203 (struct registry_container *) container, \
204 rdata); \
8e260fc0
TT
205} \
206 \
207static void \
208TAG ## _free_data (struct TAG *container) \
209{ \
6b81941e 210 struct registry_fields *rdata = &ACCESS (container)->registry_data; \
aa0fbdd8
PA
211 \
212 registry_container_free_data (&TAG ## _data_registry, \
213 TAG ## registry_callback_adaptor, \
214 (struct registry_container *) container, \
215 rdata); \
8e260fc0
TT
216} \
217 \
218void \
aa0fbdd8
PA
219set_ ## TAG ## _data (struct TAG *container, \
220 const struct TAG ## _data *data, \
221 void *value) \
8e260fc0 222{ \
6b81941e 223 struct registry_fields *rdata = &ACCESS (container)->registry_data; \
aa0fbdd8
PA
224 \
225 registry_set_data (rdata, \
226 (struct registry_data *) data, \
227 value); \
8e260fc0
TT
228} \
229 \
230void * \
231TAG ## _data (struct TAG *container, const struct TAG ## _data *data) \
232{ \
6b81941e 233 struct registry_fields *rdata = &ACCESS (container)->registry_data; \
aa0fbdd8
PA
234 \
235 return registry_data (rdata, \
236 (struct registry_data *) data); \
8e260fc0
TT
237}
238
239
240/* External declarations for the registry functions. */
241
242#define DECLARE_REGISTRY(TAG) \
aa0fbdd8
PA
243struct TAG ## _data; \
244typedef void (*registry_ ## TAG ## _callback) (struct TAG *, void *); \
8e260fc0
TT
245extern const struct TAG ## _data *register_ ## TAG ## _data (void); \
246extern const struct TAG ## _data *register_ ## TAG ## _data_with_cleanup \
aa0fbdd8 247 (registry_ ## TAG ## _callback save, registry_ ## TAG ## _callback free); \
5f6e90a0
TT
248extern void clear_ ## TAG ## _data (struct TAG *); \
249extern void set_ ## TAG ## _data (struct TAG *, \
250 const struct TAG ## _data *data, \
251 void *value); \
252extern void *TAG ## _data (struct TAG *, \
253 const struct TAG ## _data *data); \
254 \
255template<typename DATA, typename Deleter = std::default_delete<DATA>> \
256class TAG ## _key \
257{ \
258public: \
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 \
297private: \
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};
8e260fc0
TT
308
309#endif /* REGISTRY_H */
This page took 0.751016 seconds and 4 git commands to generate.