OSDN Git Service

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