* gcc-plugin.h (enum plugin_event): Add PLUGIN_ALL_IPA_PASSES_START,
[official-gcc.git] / gcc / events.c
blob9e32c623a1e1a194aa31f486c0e97f5464a9911c
1 /* High-level event callback mechanism for GCC plugins.
2 Copyright (C) 2009 Free Software Foundation, Inc.
4 Contributed by Inria.
6 Authors: Grigori Fursin <grigori.fursin@inria.fr>, Cupertino Miranda
7 <cupertinomiranda@gmail.com>, Zbigniew Chamski <zbigniew.chamski@gmail.com>.
9 This file is part of GCC.
11 GCC is free software; you can redistribute it and/or modify it under
12 the terms of the GNU General Public License as published by the Free
13 Software Foundation; either version 3, or (at your option) any later
14 version.
16 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17 WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 for more details.
21 You should have received a copy of the GNU General Public License
22 along with GCC; see the file COPYING3. If not see
23 <http://www.gnu.org/licenses/>. */
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "hashtab.h"
29 #include "toplev.h"
30 #include "gcc-plugin.h"
32 #include "highlev-plugin-internal.h"
34 /* Event structure. */
35 struct hl_plugin_event
37 int event; /* Number of the event */
38 event_callback_t run; /* Callback function */
42 /* Parameter structure. */
43 struct event_parameter
45 const char *name; /* Name for the parameter */
46 void *value; /* Pointer to data */
47 event_parameter_type type; /* Type enumeration of value */
51 static htab_t parameters_hash = NULL;
54 /* Hash dependent functions. */
55 static hashval_t
56 string_htab_hash (const void *x)
58 const char *p = *((const char * const *) x);
60 if (p != NULL)
61 return htab_hash_string (p);
63 return 0;
67 static int
68 string_htab_eq (const void *x, const void *y)
70 const char *s1 = *((const char * const *) x);
71 const char *s2 = *((const char * const *) y);
73 return !strcmp (s1, s2);
77 static void
78 parameter_htab_del (void *p)
80 struct parameter *param = (struct parameter *) p;
81 free (param);
85 static void
86 hash_param_callback (void *gcc_data, void *user_data)
88 struct hl_plugin_event *ev = (struct hl_plugin_event *) user_data;
89 va_list va;
90 const char *name;
91 int type;
92 void *value;
94 /* Possible extension:
95 Might interpret gcc_data differently for specific values of ev->event,
96 e.g. we could get a struct loop and put all the struct members in
97 named parameters. */
98 va_copy (va, * (va_list *) gcc_data);
100 while ((name = va_arg (va, const char *)) != NULL)
102 type = va_arg (va, int);
103 value = va_arg (va, void *);
104 register_event_parameter (name, value, type);
106 va_end (va);
107 ev->run ();
108 va_copy (va, * (va_list *) gcc_data);
109 while ((name = va_arg (va, const char *)) != NULL)
111 unregister_event_parameter (name);
112 va_arg (va, void *);
116 /* Register a new event into hash table. */
117 void
118 register_plugin_event (const char *event_name, event_callback_t func)
120 struct hl_plugin_event *ev = XCNEW (struct hl_plugin_event);
122 if (event_name == NULL)
123 internal_error ("Event cannot be registered with NULL name string\n");
125 ev->event = get_named_event_id (event_name, INSERT);
126 ev->run = func;
127 register_callback ("ICI", ev->event, hash_param_callback, ev);
131 /* Unregister an event. */
132 void
133 unregister_plugin_event (const char *event_name)
135 int event = get_named_event_id (event_name, NO_INSERT);
137 if (event < 0)
138 return;
140 unregister_callback ("ICI", event);
144 /* Return the array of all event names, terminated by NULL. */
145 const char **
146 list_plugin_events (void)
148 int i;
150 /* allocate space for all names + the terminating NULL */
151 const char **all_events = XNEWVEC (const char *, (event_last + 1));
153 /* collect all event names */
154 for (i = 0; i < event_last; i++)
155 all_events[i] = plugin_event_name[i];
157 /* mark end-of-array */
158 all_events[i] = NULL;
160 return all_events;
164 /* Register parameter.
165 * Insert parameter into hash table. Allocates hash table
166 * if needed. */
167 void
168 register_event_parameter (const char *name, void* value,
169 event_parameter_type type)
171 void **slot;
172 struct event_parameter *param = XCNEW (struct event_parameter);
174 param->name = name;
175 param->value = value;
176 param->type = type;
178 if (param->name == NULL || !strcmp ("", param->name))
179 internal_error ("Parameter cannot be registered with NULL name string\n");
181 if (parameters_hash == NULL)
182 parameters_hash =
183 htab_create_alloc (150, string_htab_hash,
184 string_htab_eq, parameter_htab_del, xcalloc, free);
186 if (parameters_hash != NULL)
188 slot = htab_find_slot (parameters_hash, param, INSERT);
189 *slot = (void *) param;
194 /* Unregister parameter. Remove it from hash table. */
195 void
196 unregister_event_parameter (const char *name)
198 struct event_parameter param;
199 param.name = name;
201 if (parameters_hash == NULL)
202 internal_error ("Parameter hash not initialized.\n");
204 if (parameters_hash != NULL)
205 htab_remove_elt (parameters_hash, &param);
209 /* Get parameter pointer to data.
210 Used by plugin to get pointer to data of the parameter <name>. */
211 void *
212 get_event_parameter (const char *name)
214 struct event_parameter tmp_param, *param;
215 tmp_param.name = name;
217 if (parameters_hash == NULL)
218 internal_error ("Parameter hash not initialized.\n");
220 if (parameters_hash != NULL)
222 param = (struct event_parameter *)
223 htab_find (parameters_hash, &tmp_param);
225 if (param != NULL && param->value != NULL)
226 return param->value;
228 return NULL;
231 /* Get parameter type.
232 Used by plugin to get type of data pointer of the parameter <name>. */
233 event_parameter_type
234 get_event_parameter_type (const char *name)
236 struct event_parameter tmp_param, *param;
237 tmp_param.name = name;
239 if (parameters_hash == NULL)
240 internal_error ("Parameter hash not initialized.\n");
242 if (parameters_hash != NULL)
244 param = (struct event_parameter *)
245 htab_find (parameters_hash, &tmp_param);
247 if (param != NULL && param->value != NULL)
248 return param->type;
250 return EP_VOID;
253 /* Get list of names of all registered ICI parameters.
254 * Traverse the hash table collecting the names of entries.
256 static int
257 add_parameter_name (void **slot, void *data)
259 const char ***crnt_name_ptr = (const char ***) data;
260 struct event_parameter *parameter = *(struct event_parameter **) slot;
262 /* store the name of the current parameter at the corresponding
263 location */
264 **crnt_name_ptr = parameter->name;
266 /* advance the current location */
267 (*crnt_name_ptr)++;
269 /* return "OK" */
270 return 1;
274 /* return the array of all parameter names, terminated by NULL */
275 const char **
276 list_event_parameters (void)
278 size_t num_parameters = htab_elements (parameters_hash);
280 /* allocate space for all names + the terminating NULL */
281 const char **all_parameters = (const char **)
282 xmalloc (sizeof (const char *) * (num_parameters+1));
284 const char ***data = &all_parameters; /* data ptr for mapped function */
285 const char **first_parameter = all_parameters; /* keep track of actual start */
287 /* mark end-of-array */
288 all_parameters[num_parameters] = NULL;
290 /* collect all parameter names */
291 htab_traverse_noresize (parameters_hash, add_parameter_name, data);
293 /* use the stored start-of-array - all_parameters has changed during
294 htab_traverse_noresize */
295 return first_parameter;