]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/attribs.c
c-common.c (shorten_compare): Don't special-case min/maxval for C enumerations.
[thirdparty/gcc.git] / gcc / attribs.c
CommitLineData
bb9f8221 1/* Functions dealing with attribute handling, used by most front ends.
2cc2d4bb 2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
5fd9b178 3 2002, 2003, 2004 Free Software Foundation, Inc.
bb9f8221
RK
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING. If not, write to the Free
19Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2002111-1307, USA. */
21
22#include "config.h"
23#include "system.h"
4977bab6
ZW
24#include "coretypes.h"
25#include "tm.h"
bb9f8221
RK
26#include "tree.h"
27#include "flags.h"
28#include "toplev.h"
29#include "output.h"
30#include "rtl.h"
31#include "ggc.h"
bb9f8221 32#include "tm_p.h"
bb9f8221
RK
33#include "cpplib.h"
34#include "target.h"
7ffb4fd2 35#include "langhooks.h"
bb9f8221 36
4682ae04 37static void init_attributes (void);
bb9f8221 38
349ae713 39/* Table of the tables of attributes (common, language, format, machine)
bb9f8221
RK
40 searched. */
41static const struct attribute_spec *attribute_tables[4];
42
43static bool attributes_initialized = false;
44
bb9f8221
RK
45/* Default empty table of attributes. */
46static const struct attribute_spec empty_attribute_table[] =
47{
48 { NULL, 0, 0, false, false, false, NULL }
49};
50
bb9f8221
RK
51/* Initialize attribute tables, and make some sanity checks
52 if --enable-checking. */
53
54static void
4682ae04 55init_attributes (void)
bb9f8221 56{
ca7558fc 57 size_t i;
bb9f8221 58
349ae713
NB
59 attribute_tables[0] = lang_hooks.common_attribute_table;
60 attribute_tables[1] = lang_hooks.attribute_table;
61 attribute_tables[2] = lang_hooks.format_attribute_table;
bb9f8221
RK
62 attribute_tables[3] = targetm.attribute_table;
63
349ae713
NB
64 /* Translate NULL pointers to pointers to the empty table. */
65 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
66 if (attribute_tables[i] == NULL)
67 attribute_tables[i] = empty_attribute_table;
68
bb9f8221
RK
69#ifdef ENABLE_CHECKING
70 /* Make some sanity checks on the attribute tables. */
ca7558fc 71 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
bb9f8221
RK
72 {
73 int j;
74
75 for (j = 0; attribute_tables[i][j].name != NULL; j++)
76 {
77 /* The name must not begin and end with __. */
78 const char *name = attribute_tables[i][j].name;
79 int len = strlen (name);
298e6adc
NS
80
81 gcc_assert (!(name[0] == '_' && name[1] == '_'
82 && name[len - 1] == '_' && name[len - 2] == '_'));
83
bb9f8221 84 /* The minimum and maximum lengths must be consistent. */
298e6adc
NS
85 gcc_assert (attribute_tables[i][j].min_length >= 0);
86
87 gcc_assert (attribute_tables[i][j].max_length == -1
88 || (attribute_tables[i][j].max_length
89 >= attribute_tables[i][j].min_length));
90
bb9f8221 91 /* An attribute cannot require both a DECL and a TYPE. */
298e6adc
NS
92 gcc_assert (!attribute_tables[i][j].decl_required
93 || !attribute_tables[i][j].type_required);
94
bb9f8221
RK
95 /* If an attribute requires a function type, in particular
96 it requires a type. */
298e6adc
NS
97 gcc_assert (!attribute_tables[i][j].function_type_required
98 || attribute_tables[i][j].type_required);
bb9f8221
RK
99 }
100 }
101
102 /* Check that each name occurs just once in each table. */
ca7558fc 103 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
bb9f8221
RK
104 {
105 int j, k;
106 for (j = 0; attribute_tables[i][j].name != NULL; j++)
107 for (k = j + 1; attribute_tables[i][k].name != NULL; k++)
298e6adc
NS
108 gcc_assert (strcmp (attribute_tables[i][j].name,
109 attribute_tables[i][k].name));
bb9f8221
RK
110 }
111 /* Check that no name occurs in more than one table. */
ca7558fc 112 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
bb9f8221 113 {
ca7558fc 114 size_t j, k, l;
bb9f8221 115
ca7558fc 116 for (j = i + 1; j < ARRAY_SIZE (attribute_tables); j++)
bb9f8221
RK
117 for (k = 0; attribute_tables[i][k].name != NULL; k++)
118 for (l = 0; attribute_tables[j][l].name != NULL; l++)
298e6adc
NS
119 gcc_assert (strcmp (attribute_tables[i][k].name,
120 attribute_tables[j][l].name));
bb9f8221
RK
121 }
122#endif
123
124 attributes_initialized = true;
125}
126\f
127/* Process the attributes listed in ATTRIBUTES and install them in *NODE,
128 which is either a DECL (including a TYPE_DECL) or a TYPE. If a DECL,
129 it should be modified in place; if a TYPE, a copy should be created
130 unless ATTR_FLAG_TYPE_IN_PLACE is set in FLAGS. FLAGS gives further
131 information, in the form of a bitwise OR of flags in enum attribute_flags
132 from tree.h. Depending on these flags, some attributes may be
133 returned to be applied at a later stage (for example, to apply
03aa99d4 134 a decl attribute to the declaration rather than to its type). */
bb9f8221
RK
135
136tree
4682ae04 137decl_attributes (tree *node, tree attributes, int flags)
bb9f8221
RK
138{
139 tree a;
140 tree returned_attrs = NULL_TREE;
141
142 if (!attributes_initialized)
143 init_attributes ();
144
5fd9b178 145 targetm.insert_attributes (*node, &attributes);
bb9f8221
RK
146
147 for (a = attributes; a; a = TREE_CHAIN (a))
148 {
149 tree name = TREE_PURPOSE (a);
150 tree args = TREE_VALUE (a);
151 tree *anode = node;
152 const struct attribute_spec *spec = NULL;
153 bool no_add_attrs = 0;
3acef2ae 154 tree fn_ptr_tmp = NULL_TREE;
2b03d201 155 size_t i;
bb9f8221 156
ca7558fc 157 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
bb9f8221
RK
158 {
159 int j;
160
161 for (j = 0; attribute_tables[i][j].name != NULL; j++)
162 {
163 if (is_attribute_p (attribute_tables[i][j].name, name))
164 {
165 spec = &attribute_tables[i][j];
166 break;
167 }
168 }
169 if (spec != NULL)
170 break;
171 }
172
173 if (spec == NULL)
174 {
971801ff 175 warning ("%qs attribute directive ignored",
bb9f8221
RK
176 IDENTIFIER_POINTER (name));
177 continue;
178 }
179 else if (list_length (args) < spec->min_length
180 || (spec->max_length >= 0
181 && list_length (args) > spec->max_length))
182 {
971801ff 183 error ("wrong number of arguments specified for %qs attribute",
bb9f8221
RK
184 IDENTIFIER_POINTER (name));
185 continue;
186 }
187
188 if (spec->decl_required && !DECL_P (*anode))
189 {
190 if (flags & ((int) ATTR_FLAG_DECL_NEXT
191 | (int) ATTR_FLAG_FUNCTION_NEXT
192 | (int) ATTR_FLAG_ARRAY_NEXT))
193 {
194 /* Pass on this attribute to be tried again. */
195 returned_attrs = tree_cons (name, args, returned_attrs);
196 continue;
197 }
198 else
199 {
971801ff 200 warning ("%qs attribute does not apply to types",
bb9f8221
RK
201 IDENTIFIER_POINTER (name));
202 continue;
203 }
204 }
205
dd4dc3cd
RK
206 /* If we require a type, but were passed a decl, set up to make a
207 new type and update the one in the decl. ATTR_FLAG_TYPE_IN_PLACE
208 would have applied if we'd been passed a type, but we cannot modify
209 the decl's type in place here. */
bb9f8221 210 if (spec->type_required && DECL_P (*anode))
dd4dc3cd
RK
211 {
212 anode = &TREE_TYPE (*anode);
213 flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
214 }
bb9f8221
RK
215
216 if (spec->function_type_required && TREE_CODE (*anode) != FUNCTION_TYPE
217 && TREE_CODE (*anode) != METHOD_TYPE)
218 {
219 if (TREE_CODE (*anode) == POINTER_TYPE
220 && (TREE_CODE (TREE_TYPE (*anode)) == FUNCTION_TYPE
221 || TREE_CODE (TREE_TYPE (*anode)) == METHOD_TYPE))
222 {
3acef2ae
JM
223 /* OK, this is a bit convoluted. We can't just make a copy
224 of the pointer type and modify its TREE_TYPE, because if
225 we change the attributes of the target type the pointer
226 type needs to have a different TYPE_MAIN_VARIANT. So we
227 pull out the target type now, frob it as appropriate, and
228 rebuild the pointer type later.
229
230 This would all be simpler if attributes were part of the
231 declarator, grumble grumble. */
232 fn_ptr_tmp = TREE_TYPE (*anode);
233 anode = &fn_ptr_tmp;
234 flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
bb9f8221
RK
235 }
236 else if (flags & (int) ATTR_FLAG_FUNCTION_NEXT)
237 {
238 /* Pass on this attribute to be tried again. */
239 returned_attrs = tree_cons (name, args, returned_attrs);
240 continue;
241 }
242
243 if (TREE_CODE (*anode) != FUNCTION_TYPE
244 && TREE_CODE (*anode) != METHOD_TYPE)
245 {
971801ff 246 warning ("%qs attribute only applies to function types",
bb9f8221
RK
247 IDENTIFIER_POINTER (name));
248 continue;
249 }
250 }
251
252 if (spec->handler != NULL)
253 returned_attrs = chainon ((*spec->handler) (anode, name, args,
254 flags, &no_add_attrs),
255 returned_attrs);
1b9191d2
AH
256
257 /* Layout the decl in case anything changed. */
258 if (spec->type_required && DECL_P (*node)
67282790
JM
259 && (TREE_CODE (*node) == VAR_DECL
260 || TREE_CODE (*node) == PARM_DECL
261 || TREE_CODE (*node) == RESULT_DECL))
1b9191d2
AH
262 {
263 /* Force a recalculation of mode and size. */
264 DECL_MODE (*node) = VOIDmode;
265 DECL_SIZE (*node) = 0;
266
267 layout_decl (*node, 0);
268 }
269
bb9f8221
RK
270 if (!no_add_attrs)
271 {
272 tree old_attrs;
273 tree a;
274
275 if (DECL_P (*anode))
276 old_attrs = DECL_ATTRIBUTES (*anode);
277 else
278 old_attrs = TYPE_ATTRIBUTES (*anode);
279
280 for (a = lookup_attribute (spec->name, old_attrs);
281 a != NULL_TREE;
282 a = lookup_attribute (spec->name, TREE_CHAIN (a)))
283 {
284 if (simple_cst_equal (TREE_VALUE (a), args) == 1)
285 break;
286 }
287
288 if (a == NULL_TREE)
289 {
290 /* This attribute isn't already in the list. */
291 if (DECL_P (*anode))
292 DECL_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
293 else if (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
67214984
JM
294 {
295 TYPE_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
296 /* If this is the main variant, also push the attributes
297 out to the other variants. */
298 if (*anode == TYPE_MAIN_VARIANT (*anode))
299 {
300 tree variant;
301 for (variant = *anode; variant;
302 variant = TYPE_NEXT_VARIANT (variant))
303 {
304 if (TYPE_ATTRIBUTES (variant) == old_attrs)
305 TYPE_ATTRIBUTES (variant)
306 = TYPE_ATTRIBUTES (*anode);
307 else if (!lookup_attribute
308 (spec->name, TYPE_ATTRIBUTES (variant)))
309 TYPE_ATTRIBUTES (variant) = tree_cons
310 (name, args, TYPE_ATTRIBUTES (variant));
311 }
312 }
313 }
bb9f8221
RK
314 else
315 *anode = build_type_attribute_variant (*anode,
316 tree_cons (name, args,
317 old_attrs));
318 }
319 }
3acef2ae
JM
320
321 if (fn_ptr_tmp)
322 {
323 /* Rebuild the function pointer type and put it in the
324 appropriate place. */
325 fn_ptr_tmp = build_pointer_type (fn_ptr_tmp);
326 if (DECL_P (*node))
327 TREE_TYPE (*node) = fn_ptr_tmp;
3acef2ae 328 else
298e6adc
NS
329 {
330 gcc_assert (TREE_CODE (*node) == POINTER_TYPE);
331 *node = fn_ptr_tmp;
332 }
3acef2ae 333 }
bb9f8221
RK
334 }
335
336 return returned_attrs;
337}