OSDN Git Service

2003-09-19 Joel Sherrill <joel@oarcorp.com>
[pf3gnuchains/gcc-fork.git] / gcc / attribs.c
1 /* Functions dealing with attribute handling, used by most front ends.
2    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
3    2002, 2003 Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING.  If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
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"
34 #include "cpplib.h"
35 #include "target.h"
36 #include "langhooks.h"
37
38 static void init_attributes (void);
39
40 /* Table of the tables of attributes (common, language, format, machine)
41    searched.  */
42 static const struct attribute_spec *attribute_tables[4];
43
44 static bool attributes_initialized = false;
45
46 /* Default empty table of attributes.  */
47 static const struct attribute_spec empty_attribute_table[] =
48 {
49   { NULL, 0, 0, false, false, false, NULL }
50 };
51
52 /* Initialize attribute tables, and make some sanity checks
53    if --enable-checking.  */
54
55 static void
56 init_attributes (void)
57 {
58   size_t i;
59
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;
63   attribute_tables[3] = targetm.attribute_table;
64
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
70 #ifdef ENABLE_CHECKING
71   /* Make some sanity checks on the attribute tables.  */
72   for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
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.  */
104   for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
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.  */
114   for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
115     {
116       size_t j, k, l;
117
118       for (j = i + 1; j < ARRAY_SIZE (attribute_tables); j++)
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
137    a decl attribute to the declaration rather than to its type).  */
138
139 tree
140 decl_attributes (tree *node, tree attributes, int flags)
141 {
142   tree a;
143   tree returned_attrs = NULL_TREE;
144
145   if (!attributes_initialized)
146     init_attributes ();
147
148   (*targetm.insert_attributes) (*node, &attributes);
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;
157       tree fn_ptr_tmp = NULL_TREE;
158       size_t i;
159
160       for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
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
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.  */
213       if (spec->type_required && DECL_P (*anode))
214         {
215           anode = &TREE_TYPE (*anode);
216           flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
217         }
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             {
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;
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);
259
260       /* Layout the decl in case anything changed.  */
261       if (spec->type_required && DECL_P (*node)
262           && (TREE_CODE (*node) == VAR_DECL
263               || TREE_CODE (*node) == PARM_DECL
264               || TREE_CODE (*node) == RESULT_DECL))
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
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         }
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         }
317     }
318
319   return returned_attrs;
320 }
321
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
332 void
333 split_specs_attrs (tree specs_attrs, tree *declspecs, tree *prefix_attributes)
334 {
335   tree t, s, a, next, specs, attrs;
336
337   /* This can happen after an __extension__ in pedantic mode.  */
338   if (specs_attrs != NULL_TREE
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
407 tree
408 strip_attrs (tree specs_attrs)
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 }