]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/attribs.c
Trivial comment typo in previous change.
[thirdparty/gcc.git] / gcc / attribs.c
CommitLineData
e3f6ce11 1/* Functions dealing with attribute handling, used by most front ends.
80fabb90 2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
883b2e73 3 2002, 2003, 2004 Free Software Foundation, Inc.
e3f6ce11 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"
805e22b2 24#include "coretypes.h"
25#include "tm.h"
e3f6ce11 26#include "tree.h"
27#include "flags.h"
28#include "toplev.h"
29#include "output.h"
30#include "rtl.h"
31#include "ggc.h"
32#include "expr.h"
33#include "tm_p.h"
e3f6ce11 34#include "cpplib.h"
35#include "target.h"
26ca6c20 36#include "langhooks.h"
e3f6ce11 37
aecda0d6 38static void init_attributes (void);
e3f6ce11 39
f8e93a2e 40/* Table of the tables of attributes (common, language, format, machine)
e3f6ce11 41 searched. */
42static const struct attribute_spec *attribute_tables[4];
43
44static bool attributes_initialized = false;
45
e3f6ce11 46/* Default empty table of attributes. */
47static const struct attribute_spec empty_attribute_table[] =
48{
49 { NULL, 0, 0, false, false, false, NULL }
50};
51
e3f6ce11 52/* Initialize attribute tables, and make some sanity checks
53 if --enable-checking. */
54
55static void
aecda0d6 56init_attributes (void)
e3f6ce11 57{
3585dac7 58 size_t i;
e3f6ce11 59
f8e93a2e 60 attribute_tables[0] = lang_hooks.common_attribute_table;
61 attribute_tables[1] = lang_hooks.attribute_table;
62 attribute_tables[2] = lang_hooks.format_attribute_table;
e3f6ce11 63 attribute_tables[3] = targetm.attribute_table;
64
f8e93a2e 65 /* Translate NULL pointers to pointers to the empty table. */
66 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
67 if (attribute_tables[i] == NULL)
68 attribute_tables[i] = empty_attribute_table;
69
e3f6ce11 70#ifdef ENABLE_CHECKING
71 /* Make some sanity checks on the attribute tables. */
3585dac7 72 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
e3f6ce11 73 {
74 int j;
75
76 for (j = 0; attribute_tables[i][j].name != NULL; j++)
77 {
78 /* The name must not begin and end with __. */
79 const char *name = attribute_tables[i][j].name;
80 int len = strlen (name);
81 if (name[0] == '_' && name[1] == '_'
82 && name[len - 1] == '_' && name[len - 2] == '_')
83 abort ();
84 /* The minimum and maximum lengths must be consistent. */
85 if (attribute_tables[i][j].min_length < 0)
86 abort ();
87 if (attribute_tables[i][j].max_length != -1
88 && (attribute_tables[i][j].max_length
89 < attribute_tables[i][j].min_length))
90 abort ();
91 /* An attribute cannot require both a DECL and a TYPE. */
92 if (attribute_tables[i][j].decl_required
93 && attribute_tables[i][j].type_required)
94 abort ();
95 /* If an attribute requires a function type, in particular
96 it requires a type. */
97 if (attribute_tables[i][j].function_type_required
98 && !attribute_tables[i][j].type_required)
99 abort ();
100 }
101 }
102
103 /* Check that each name occurs just once in each table. */
3585dac7 104 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
e3f6ce11 105 {
106 int j, k;
107 for (j = 0; attribute_tables[i][j].name != NULL; j++)
108 for (k = j + 1; attribute_tables[i][k].name != NULL; k++)
109 if (!strcmp (attribute_tables[i][j].name,
110 attribute_tables[i][k].name))
111 abort ();
112 }
113 /* Check that no name occurs in more than one table. */
3585dac7 114 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
e3f6ce11 115 {
3585dac7 116 size_t j, k, l;
e3f6ce11 117
3585dac7 118 for (j = i + 1; j < ARRAY_SIZE (attribute_tables); j++)
e3f6ce11 119 for (k = 0; attribute_tables[i][k].name != NULL; k++)
120 for (l = 0; attribute_tables[j][l].name != NULL; l++)
121 if (!strcmp (attribute_tables[i][k].name,
122 attribute_tables[j][l].name))
123 abort ();
124 }
125#endif
126
127 attributes_initialized = true;
128}
129\f
130/* Process the attributes listed in ATTRIBUTES and install them in *NODE,
131 which is either a DECL (including a TYPE_DECL) or a TYPE. If a DECL,
132 it should be modified in place; if a TYPE, a copy should be created
133 unless ATTR_FLAG_TYPE_IN_PLACE is set in FLAGS. FLAGS gives further
134 information, in the form of a bitwise OR of flags in enum attribute_flags
135 from tree.h. Depending on these flags, some attributes may be
136 returned to be applied at a later stage (for example, to apply
101cc430 137 a decl attribute to the declaration rather than to its type). */
e3f6ce11 138
139tree
aecda0d6 140decl_attributes (tree *node, tree attributes, int flags)
e3f6ce11 141{
142 tree a;
143 tree returned_attrs = NULL_TREE;
144
145 if (!attributes_initialized)
146 init_attributes ();
147
883b2e73 148 targetm.insert_attributes (*node, &attributes);
e3f6ce11 149
150 for (a = attributes; a; a = TREE_CHAIN (a))
151 {
152 tree name = TREE_PURPOSE (a);
153 tree args = TREE_VALUE (a);
154 tree *anode = node;
155 const struct attribute_spec *spec = NULL;
156 bool no_add_attrs = 0;
79bdd5ff 157 tree fn_ptr_tmp = NULL_TREE;
40265b77 158 size_t i;
e3f6ce11 159
3585dac7 160 for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
e3f6ce11 161 {
162 int j;
163
164 for (j = 0; attribute_tables[i][j].name != NULL; j++)
165 {
166 if (is_attribute_p (attribute_tables[i][j].name, name))
167 {
168 spec = &attribute_tables[i][j];
169 break;
170 }
171 }
172 if (spec != NULL)
173 break;
174 }
175
176 if (spec == NULL)
177 {
178 warning ("`%s' attribute directive ignored",
179 IDENTIFIER_POINTER (name));
180 continue;
181 }
182 else if (list_length (args) < spec->min_length
183 || (spec->max_length >= 0
184 && list_length (args) > spec->max_length))
185 {
186 error ("wrong number of arguments specified for `%s' attribute",
187 IDENTIFIER_POINTER (name));
188 continue;
189 }
190
191 if (spec->decl_required && !DECL_P (*anode))
192 {
193 if (flags & ((int) ATTR_FLAG_DECL_NEXT
194 | (int) ATTR_FLAG_FUNCTION_NEXT
195 | (int) ATTR_FLAG_ARRAY_NEXT))
196 {
197 /* Pass on this attribute to be tried again. */
198 returned_attrs = tree_cons (name, args, returned_attrs);
199 continue;
200 }
201 else
202 {
203 warning ("`%s' attribute does not apply to types",
204 IDENTIFIER_POINTER (name));
205 continue;
206 }
207 }
208
aa9c60c1 209 /* If we require a type, but were passed a decl, set up to make a
210 new type and update the one in the decl. ATTR_FLAG_TYPE_IN_PLACE
211 would have applied if we'd been passed a type, but we cannot modify
212 the decl's type in place here. */
e3f6ce11 213 if (spec->type_required && DECL_P (*anode))
aa9c60c1 214 {
215 anode = &TREE_TYPE (*anode);
216 flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
217 }
e3f6ce11 218
219 if (spec->function_type_required && TREE_CODE (*anode) != FUNCTION_TYPE
220 && TREE_CODE (*anode) != METHOD_TYPE)
221 {
222 if (TREE_CODE (*anode) == POINTER_TYPE
223 && (TREE_CODE (TREE_TYPE (*anode)) == FUNCTION_TYPE
224 || TREE_CODE (TREE_TYPE (*anode)) == METHOD_TYPE))
225 {
79bdd5ff 226 /* OK, this is a bit convoluted. We can't just make a copy
227 of the pointer type and modify its TREE_TYPE, because if
228 we change the attributes of the target type the pointer
229 type needs to have a different TYPE_MAIN_VARIANT. So we
230 pull out the target type now, frob it as appropriate, and
231 rebuild the pointer type later.
232
233 This would all be simpler if attributes were part of the
234 declarator, grumble grumble. */
235 fn_ptr_tmp = TREE_TYPE (*anode);
236 anode = &fn_ptr_tmp;
237 flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
e3f6ce11 238 }
239 else if (flags & (int) ATTR_FLAG_FUNCTION_NEXT)
240 {
241 /* Pass on this attribute to be tried again. */
242 returned_attrs = tree_cons (name, args, returned_attrs);
243 continue;
244 }
245
246 if (TREE_CODE (*anode) != FUNCTION_TYPE
247 && TREE_CODE (*anode) != METHOD_TYPE)
248 {
249 warning ("`%s' attribute only applies to function types",
250 IDENTIFIER_POINTER (name));
251 continue;
252 }
253 }
254
255 if (spec->handler != NULL)
256 returned_attrs = chainon ((*spec->handler) (anode, name, args,
257 flags, &no_add_attrs),
258 returned_attrs);
ae4718db 259
260 /* Layout the decl in case anything changed. */
261 if (spec->type_required && DECL_P (*node)
e56de52f 262 && (TREE_CODE (*node) == VAR_DECL
263 || TREE_CODE (*node) == PARM_DECL
264 || TREE_CODE (*node) == RESULT_DECL))
ae4718db 265 {
266 /* Force a recalculation of mode and size. */
267 DECL_MODE (*node) = VOIDmode;
268 DECL_SIZE (*node) = 0;
269
270 layout_decl (*node, 0);
271 }
272
e3f6ce11 273 if (!no_add_attrs)
274 {
275 tree old_attrs;
276 tree a;
277
278 if (DECL_P (*anode))
279 old_attrs = DECL_ATTRIBUTES (*anode);
280 else
281 old_attrs = TYPE_ATTRIBUTES (*anode);
282
283 for (a = lookup_attribute (spec->name, old_attrs);
284 a != NULL_TREE;
285 a = lookup_attribute (spec->name, TREE_CHAIN (a)))
286 {
287 if (simple_cst_equal (TREE_VALUE (a), args) == 1)
288 break;
289 }
290
291 if (a == NULL_TREE)
292 {
293 /* This attribute isn't already in the list. */
294 if (DECL_P (*anode))
295 DECL_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
296 else if (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
297 TYPE_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
298 else
299 *anode = build_type_attribute_variant (*anode,
300 tree_cons (name, args,
301 old_attrs));
302 }
303 }
79bdd5ff 304
305 if (fn_ptr_tmp)
306 {
307 /* Rebuild the function pointer type and put it in the
308 appropriate place. */
309 fn_ptr_tmp = build_pointer_type (fn_ptr_tmp);
310 if (DECL_P (*node))
311 TREE_TYPE (*node) = fn_ptr_tmp;
312 else if (TREE_CODE (*node) == POINTER_TYPE)
313 *node = fn_ptr_tmp;
314 else
315 abort ();
316 }
e3f6ce11 317 }
318
319 return returned_attrs;
320}
321
e3f6ce11 322/* Split SPECS_ATTRS, a list of declspecs and prefix attributes, into two
323 lists. SPECS_ATTRS may also be just a typespec (eg: RECORD_TYPE).
324
325 The head of the declspec list is stored in DECLSPECS.
326 The head of the attribute list is stored in PREFIX_ATTRIBUTES.
327
328 Note that attributes in SPECS_ATTRS are stored in the TREE_PURPOSE of
329 the list elements. We drop the containing TREE_LIST nodes and link the
330 resulting attributes together the way decl_attributes expects them. */
331
332void
aecda0d6 333split_specs_attrs (tree specs_attrs, tree *declspecs, tree *prefix_attributes)
e3f6ce11 334{
335 tree t, s, a, next, specs, attrs;
336
337 /* This can happen after an __extension__ in pedantic mode. */
9342ee68 338 if (specs_attrs != NULL_TREE
e3f6ce11 339 && TREE_CODE (specs_attrs) == INTEGER_CST)
340 {
341 *declspecs = NULL_TREE;
342 *prefix_attributes = NULL_TREE;
343 return;
344 }
345
346 /* This can happen in c++ (eg: decl: typespec initdecls ';'). */
347 if (specs_attrs != NULL_TREE
348 && TREE_CODE (specs_attrs) != TREE_LIST)
349 {
350 *declspecs = specs_attrs;
351 *prefix_attributes = NULL_TREE;
352 return;
353 }
354
355 /* Remember to keep the lists in the same order, element-wise. */
356
357 specs = s = NULL_TREE;
358 attrs = a = NULL_TREE;
359 for (t = specs_attrs; t; t = next)
360 {
361 next = TREE_CHAIN (t);
362 /* Declspecs have a non-NULL TREE_VALUE. */
363 if (TREE_VALUE (t) != NULL_TREE)
364 {
365 if (specs == NULL_TREE)
366 specs = s = t;
367 else
368 {
369 TREE_CHAIN (s) = t;
370 s = t;
371 }
372 }
373 /* The TREE_PURPOSE may also be empty in the case of
374 __attribute__(()). */
375 else if (TREE_PURPOSE (t) != NULL_TREE)
376 {
377 if (attrs == NULL_TREE)
378 attrs = a = TREE_PURPOSE (t);
379 else
380 {
381 TREE_CHAIN (a) = TREE_PURPOSE (t);
382 a = TREE_PURPOSE (t);
383 }
384 /* More attrs can be linked here, move A to the end. */
385 while (TREE_CHAIN (a) != NULL_TREE)
386 a = TREE_CHAIN (a);
387 }
388 }
389
390 /* Terminate the lists. */
391 if (s != NULL_TREE)
392 TREE_CHAIN (s) = NULL_TREE;
393 if (a != NULL_TREE)
394 TREE_CHAIN (a) = NULL_TREE;
395
396 /* All done. */
397 *declspecs = specs;
398 *prefix_attributes = attrs;
399}
400
401/* Strip attributes from SPECS_ATTRS, a list of declspecs and attributes.
402 This function is used by the parser when a rule will accept attributes
403 in a particular position, but we don't want to support that just yet.
404
405 A warning is issued for every ignored attribute. */
406
407tree
aecda0d6 408strip_attrs (tree specs_attrs)
e3f6ce11 409{
410 tree specs, attrs;
411
412 split_specs_attrs (specs_attrs, &specs, &attrs);
413
414 while (attrs)
415 {
416 warning ("`%s' attribute ignored",
417 IDENTIFIER_POINTER (TREE_PURPOSE (attrs)));
418 attrs = TREE_CHAIN (attrs);
419 }
420
421 return specs;
422}