OSDN Git Service

2005-12-11 Andrew Pinski <pinskia@physics.uc.edu>
[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, 2005 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, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, 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           
81           gcc_assert (!(name[0] == '_' && name[1] == '_'
82                         && name[len - 1] == '_' && name[len - 2] == '_'));
83           
84           /* The minimum and maximum lengths must be consistent.  */
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           
91           /* An attribute cannot require both a DECL and a TYPE.  */
92           gcc_assert (!attribute_tables[i][j].decl_required
93                       || !attribute_tables[i][j].type_required);
94           
95           /* If an attribute requires a function type, in particular
96              it requires a type.  */
97           gcc_assert (!attribute_tables[i][j].function_type_required
98                       || attribute_tables[i][j].type_required);
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           gcc_assert (strcmp (attribute_tables[i][j].name,
109                               attribute_tables[i][k].name));
110     }
111   /* Check that no name occurs in more than one table.  */
112   for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
113     {
114       size_t j, k, l;
115
116       for (j = i + 1; j < ARRAY_SIZE (attribute_tables); j++)
117         for (k = 0; attribute_tables[i][k].name != NULL; k++)
118           for (l = 0; attribute_tables[j][l].name != NULL; l++)
119             gcc_assert (strcmp (attribute_tables[i][k].name,
120                                 attribute_tables[j][l].name));
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
134    a decl attribute to the declaration rather than to its type).  */
135
136 tree
137 decl_attributes (tree *node, tree attributes, int flags)
138 {
139   tree a;
140   tree returned_attrs = NULL_TREE;
141
142   if (!attributes_initialized)
143     init_attributes ();
144
145   targetm.insert_attributes (*node, &attributes);
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;
154       tree fn_ptr_tmp = NULL_TREE;
155       size_t i;
156
157       for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
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         {
175           warning (OPT_Wattributes, "%qs attribute directive ignored",
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         {
183           error ("wrong number of arguments specified for %qs attribute",
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             {
200               warning (OPT_Wattributes, "%qs attribute does not apply to types",
201                        IDENTIFIER_POINTER (name));
202               continue;
203             }
204         }
205
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.  */
210       if (spec->type_required && DECL_P (*anode))
211         {
212           anode = &TREE_TYPE (*anode);
213           flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
214         }
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             {
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;
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             {
246               warning (OPT_Wattributes,
247                        "%qs attribute only applies to function types",
248                        IDENTIFIER_POINTER (name));
249               continue;
250             }
251         }
252
253       if (spec->handler != NULL)
254         returned_attrs = chainon ((*spec->handler) (anode, name, args,
255                                                     flags, &no_add_attrs),
256                                   returned_attrs);
257
258       /* Layout the decl in case anything changed.  */
259       if (spec->type_required && DECL_P (*node)
260           && (TREE_CODE (*node) == VAR_DECL
261               || TREE_CODE (*node) == PARM_DECL
262               || TREE_CODE (*node) == RESULT_DECL))
263         relayout_decl (*node);
264
265       if (!no_add_attrs)
266         {
267           tree old_attrs;
268           tree a;
269
270           if (DECL_P (*anode))
271             old_attrs = DECL_ATTRIBUTES (*anode);
272           else
273             old_attrs = TYPE_ATTRIBUTES (*anode);
274
275           for (a = lookup_attribute (spec->name, old_attrs);
276                a != NULL_TREE;
277                a = lookup_attribute (spec->name, TREE_CHAIN (a)))
278             {
279               if (simple_cst_equal (TREE_VALUE (a), args) == 1)
280                 break;
281             }
282
283           if (a == NULL_TREE)
284             {
285               /* This attribute isn't already in the list.  */
286               if (DECL_P (*anode))
287                 DECL_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
288               else if (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
289                 {
290                   TYPE_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
291                   /* If this is the main variant, also push the attributes
292                      out to the other variants.  */
293                   if (*anode == TYPE_MAIN_VARIANT (*anode))
294                     {
295                       tree variant;
296                       for (variant = *anode; variant;
297                            variant = TYPE_NEXT_VARIANT (variant))
298                         {
299                           if (TYPE_ATTRIBUTES (variant) == old_attrs)
300                             TYPE_ATTRIBUTES (variant)
301                               = TYPE_ATTRIBUTES (*anode);
302                           else if (!lookup_attribute
303                                    (spec->name, TYPE_ATTRIBUTES (variant)))
304                             TYPE_ATTRIBUTES (variant) = tree_cons
305                               (name, args, TYPE_ATTRIBUTES (variant));
306                         }
307                     }
308                 }
309               else
310                 *anode = build_type_attribute_variant (*anode,
311                                                        tree_cons (name, args,
312                                                                   old_attrs));
313             }
314         }
315
316       if (fn_ptr_tmp)
317         {
318           /* Rebuild the function pointer type and put it in the
319              appropriate place.  */
320           fn_ptr_tmp = build_pointer_type (fn_ptr_tmp);
321           if (DECL_P (*node))
322             TREE_TYPE (*node) = fn_ptr_tmp;
323           else
324             {
325               gcc_assert (TREE_CODE (*node) == POINTER_TYPE);
326               *node = fn_ptr_tmp;
327             }
328         }
329     }
330
331   return returned_attrs;
332 }