OSDN Git Service

* attribs.c (strip_attrs): Remove.
[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           
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 ("`%s' 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 `%s' 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 ("`%s' 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 ("`%s' attribute only applies to function types",
247                        IDENTIFIER_POINTER (name));
248               continue;
249             }
250         }
251
252       if (spec->handler != NULL)
253         returned_attrs = chainon ((*spec->handler) (anode, name, args,
254                                                     flags, &no_add_attrs),
255                                   returned_attrs);
256
257       /* Layout the decl in case anything changed.  */
258       if (spec->type_required && DECL_P (*node)
259           && (TREE_CODE (*node) == VAR_DECL
260               || TREE_CODE (*node) == PARM_DECL
261               || TREE_CODE (*node) == RESULT_DECL))
262         {
263           /* Force a recalculation of mode and size.  */
264           DECL_MODE (*node) = VOIDmode;
265           DECL_SIZE (*node) = 0;
266
267           layout_decl (*node, 0);
268         }
269
270       if (!no_add_attrs)
271         {
272           tree old_attrs;
273           tree a;
274
275           if (DECL_P (*anode))
276             old_attrs = DECL_ATTRIBUTES (*anode);
277           else
278             old_attrs = TYPE_ATTRIBUTES (*anode);
279
280           for (a = lookup_attribute (spec->name, old_attrs);
281                a != NULL_TREE;
282                a = lookup_attribute (spec->name, TREE_CHAIN (a)))
283             {
284               if (simple_cst_equal (TREE_VALUE (a), args) == 1)
285                 break;
286             }
287
288           if (a == NULL_TREE)
289             {
290               /* This attribute isn't already in the list.  */
291               if (DECL_P (*anode))
292                 DECL_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
293               else if (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
294                 {
295                   TYPE_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
296                   /* If this is the main variant, also push the attributes
297                      out to the other variants.  */
298                   if (*anode == TYPE_MAIN_VARIANT (*anode))
299                     {
300                       tree variant;
301                       for (variant = *anode; variant;
302                            variant = TYPE_NEXT_VARIANT (variant))
303                         {
304                           if (TYPE_ATTRIBUTES (variant) == old_attrs)
305                             TYPE_ATTRIBUTES (variant)
306                               = TYPE_ATTRIBUTES (*anode);
307                           else if (!lookup_attribute
308                                    (spec->name, TYPE_ATTRIBUTES (variant)))
309                             TYPE_ATTRIBUTES (variant) = tree_cons
310                               (name, args, TYPE_ATTRIBUTES (variant));
311                         }
312                     }
313                 }
314               else
315                 *anode = build_type_attribute_variant (*anode,
316                                                        tree_cons (name, args,
317                                                                   old_attrs));
318             }
319         }
320
321       if (fn_ptr_tmp)
322         {
323           /* Rebuild the function pointer type and put it in the
324              appropriate place.  */
325           fn_ptr_tmp = build_pointer_type (fn_ptr_tmp);
326           if (DECL_P (*node))
327             TREE_TYPE (*node) = fn_ptr_tmp;
328           else
329             {
330               gcc_assert (TREE_CODE (*node) == POINTER_TYPE);
331               *node = fn_ptr_tmp;
332             }
333         }
334     }
335
336   return returned_attrs;
337 }