* gcc-plugin.h (enum plugin_event): Add PLUGIN_ALL_IPA_PASSES_START,
[official-gcc.git] / gcc / feature.c
blob1c141b694632b907f8840b9613c2247459498abc
1 /* Features: a high-level mechanism for accessing global compiler state in GCC.
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"
31 #include "feature-internal.h"
33 htab_t features_hash = NULL;
36 /* Hash dependent functions. */
38 static hashval_t
39 features_htab_hash (const void *x)
41 const struct feature *p = (const struct feature *) x;
43 if (!p)
44 internal_error ("features_htab_hash: called with NULL feature pointer!");
46 if (p->name != NULL)
47 return htab_hash_string(p->name);
48 else
49 internal_error ("features_htab_hash: NULL-named feature!\n");
53 static int
54 features_htab_eq (const void *x, const void *y)
56 const struct feature *p1 = (const struct feature *) x;
57 const struct feature *p2 = (const struct feature *) y;
59 return !strcmp (p1->name, p2->name);
63 /* Add feature to hash table. */
64 void register_feature (const struct feature *feature)
66 void **slot;
68 if (!feature)
69 internal_error ("register_feature() called with NULL feature!\n");
71 if (feature->name == NULL)
72 internal_error ("register_feature() called with NULL-named feature!\n");
74 if(features_hash == NULL)
75 features_hash = htab_create_alloc (150, features_htab_hash,
76 features_htab_eq, NULL, xcalloc, free);
78 if(features_hash != NULL)
80 slot = (void **) htab_find_slot (features_hash, feature, INSERT);
81 *slot = CONST_CAST2 (void *, const struct feature *, feature);
86 /* FICI0: ici_find_feature: find the feature with a given name.
87 * Return values:
88 * - pointer to 'struct feature' if the named feature was found;
89 * - NULL if the feature could not be found.
91 struct feature *find_feature (const char *feature_name)
93 struct feature tmp_feature;
95 tmp_feature.name = feature_name;
97 return (struct feature *) htab_find (features_hash, &tmp_feature);
101 /* Get pointer to feature with <feature_name>. */
102 const void *get_feature (const char *feature_name)
104 const struct feature *feature;
106 feature = find_feature (feature_name);
108 if(feature == NULL)
109 return NULL;
111 if(feature->data != NULL)
112 return (const void *) feature->data;
113 else if (feature->callback != NULL)
114 /* Call only non-NULL callbacks */
115 return feature->callback ();
116 else
117 return NULL;
121 /* Return the size of the data associated with feature */
122 int get_feature_size (const char *feature_name)
124 const struct feature *feature;
126 feature = find_feature (feature_name);
128 if(feature == NULL)
129 return -1;
131 return feature->data_size;
135 /* FICI0: get specific sub-feature of a main feature.
136 * Prerequisites: both feature and subfeature must exist (no diagnostics).
137 * Return values:
138 * - string subfeatures: pointer-to-char corresponding to the string;
139 * - integer/boolean/bit subfeatures: integer converted to pointer-to-void.
141 const void *
142 get_subfeature (const char *feature_name, const char *subfeat_name)
144 const struct feature *feature;
146 feature = find_feature (feature_name);
148 /* no feature or no subfeature callback: bail out. */
149 if (!feature || !feature->get_subfeature)
150 return NULL;
152 return (feature->get_subfeature (subfeat_name));
156 /* FICI0: set sub-feature */
157 void *set_subfeature (const char *feature_name,
158 const char *subfeat_name,
159 void *subfeat_value)
161 struct feature *feature = find_feature (feature_name);
163 /* no feature or no subfeature callback: bail out. */
164 if (!feature || !feature->set_subfeature) return NULL;
166 return feature->set_subfeature (subfeat_name, subfeat_value);
170 static int
171 add_feature_name (void **slot, void *data)
173 const char ***crnt_name_ptr = (const char ***) data;
174 struct feature *feature = *(struct feature **) slot;
176 /* store the name of the current fearute at the corresponding
177 location */
178 **crnt_name_ptr = feature->name;
180 /* advance the current location */
181 (*crnt_name_ptr)++;
183 /* return "OK" */
184 return 1;
188 /* return the array of all feature names, terminated by NULL */
189 const char **
190 list_features (void)
192 size_t num_features = htab_elements (features_hash);
194 /* allocate space for all names + the terminating NULL */
195 const char **all_features = (const char **)
196 xmalloc (sizeof (const char *) * (num_features+1));
198 const char ***data = &all_features; /* data ptr for mapped function */
199 const char **first_feature = all_features; /* keep track of actual start */
201 /* mark end-of-array */
202 all_features[num_features] = NULL;
204 /* collect all feature names */
205 htab_traverse_noresize (features_hash, add_feature_name, data);
207 /* use the stored start-of-array - all_features has changed during
208 htab_traverse_noresize */
209 return first_feature;