Merge branch 'master' of ssh://crater.dragonflybsd.org/repository/git/dragonfly
[dragonfly.git] / contrib / gcc-3.4 / 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           if (!DECL_USER_ALIGN (*node))
270             DECL_ALIGN (*node) = 0;
271
272           layout_decl (*node, 0);
273         }
274
275       if (!no_add_attrs)
276         {
277           tree old_attrs;
278           tree a;
279
280           if (DECL_P (*anode))
281             old_attrs = DECL_ATTRIBUTES (*anode);
282           else
283             old_attrs = TYPE_ATTRIBUTES (*anode);
284
285           for (a = lookup_attribute (spec->name, old_attrs);
286                a != NULL_TREE;
287                a = lookup_attribute (spec->name, TREE_CHAIN (a)))
288             {
289               if (simple_cst_equal (TREE_VALUE (a), args) == 1)
290                 break;
291             }
292
293           if (a == NULL_TREE)
294             {
295               /* This attribute isn't already in the list.  */
296               if (DECL_P (*anode))
297                 DECL_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
298               else if (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
299                 TYPE_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
300               else
301                 *anode = build_type_attribute_variant (*anode,
302                                                        tree_cons (name, args,
303                                                                   old_attrs));
304             }
305         }
306
307       if (fn_ptr_tmp)
308         {
309           /* Rebuild the function pointer type and put it in the
310              appropriate place.  */
311           fn_ptr_tmp = build_pointer_type (fn_ptr_tmp);
312           if (DECL_P (*node))
313             TREE_TYPE (*node) = fn_ptr_tmp;
314           else if (TREE_CODE (*node) == POINTER_TYPE)
315             *node = fn_ptr_tmp;
316           else
317             abort ();
318         }
319     }
320
321   return returned_attrs;
322 }
323
324 /* Split SPECS_ATTRS, a list of declspecs and prefix attributes, into two
325    lists.  SPECS_ATTRS may also be just a typespec (eg: RECORD_TYPE).
326
327    The head of the declspec list is stored in DECLSPECS.
328    The head of the attribute list is stored in PREFIX_ATTRIBUTES.
329
330    Note that attributes in SPECS_ATTRS are stored in the TREE_PURPOSE of
331    the list elements.  We drop the containing TREE_LIST nodes and link the
332    resulting attributes together the way decl_attributes expects them.  */
333
334 void
335 split_specs_attrs (tree specs_attrs, tree *declspecs, tree *prefix_attributes)
336 {
337   tree t, s, a, next, specs, attrs;
338
339   /* This can happen after an __extension__ in pedantic mode.  */
340   if (specs_attrs != NULL_TREE
341       && TREE_CODE (specs_attrs) == INTEGER_CST)
342     {
343       *declspecs = NULL_TREE;
344       *prefix_attributes = NULL_TREE;
345       return;
346     }
347
348   /* This can happen in c++ (eg: decl: typespec initdecls ';').  */
349   if (specs_attrs != NULL_TREE
350       && TREE_CODE (specs_attrs) != TREE_LIST)
351     {
352       *declspecs = specs_attrs;
353       *prefix_attributes = NULL_TREE;
354       return;
355     }
356
357   /* Remember to keep the lists in the same order, element-wise.  */
358
359   specs = s = NULL_TREE;
360   attrs = a = NULL_TREE;
361   for (t = specs_attrs; t; t = next)
362     {
363       next = TREE_CHAIN (t);
364       /* Declspecs have a non-NULL TREE_VALUE.  */
365       if (TREE_VALUE (t) != NULL_TREE)
366         {
367           if (specs == NULL_TREE)
368             specs = s = t;
369           else
370             {
371               TREE_CHAIN (s) = t;
372               s = t;
373             }
374         }
375       /* The TREE_PURPOSE may also be empty in the case of
376          __attribute__(()).  */
377       else if (TREE_PURPOSE (t) != NULL_TREE)
378         {
379           if (attrs == NULL_TREE)
380             attrs = a = TREE_PURPOSE (t);
381           else
382             {
383               TREE_CHAIN (a) = TREE_PURPOSE (t);
384               a = TREE_PURPOSE (t);
385             }
386           /* More attrs can be linked here, move A to the end.  */
387           while (TREE_CHAIN (a) != NULL_TREE)
388             a = TREE_CHAIN (a);
389         }
390     }
391
392   /* Terminate the lists.  */
393   if (s != NULL_TREE)
394     TREE_CHAIN (s) = NULL_TREE;
395   if (a != NULL_TREE)
396     TREE_CHAIN (a) = NULL_TREE;
397
398   /* All done.  */
399   *declspecs = specs;
400   *prefix_attributes = attrs;
401 }
402
403 /* Strip attributes from SPECS_ATTRS, a list of declspecs and attributes.
404    This function is used by the parser when a rule will accept attributes
405    in a particular position, but we don't want to support that just yet.
406
407    A warning is issued for every ignored attribute.  */
408
409 tree
410 strip_attrs (tree specs_attrs)
411 {
412   tree specs, attrs;
413
414   split_specs_attrs (specs_attrs, &specs, &attrs);
415
416   while (attrs)
417     {
418       warning ("`%s' attribute ignored",
419                IDENTIFIER_POINTER (TREE_PURPOSE (attrs)));
420       attrs = TREE_CHAIN (attrs);
421     }
422
423   return specs;
424 }