]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/gcc/attribs.c
MFC r368207,368607:
[FreeBSD/stable/10.git] / contrib / 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           /* APPLE LOCAL radar 6246527 */
220           if ((TREE_CODE (*anode) == POINTER_TYPE || TREE_CODE (*anode) == BLOCK_POINTER_TYPE)
221               && (TREE_CODE (TREE_TYPE (*anode)) == FUNCTION_TYPE
222                   || TREE_CODE (TREE_TYPE (*anode)) == METHOD_TYPE))
223             {
224               /* OK, this is a bit convoluted.  We can't just make a copy
225                  of the pointer type and modify its TREE_TYPE, because if
226                  we change the attributes of the target type the pointer
227                  type needs to have a different TYPE_MAIN_VARIANT.  So we
228                  pull out the target type now, frob it as appropriate, and
229                  rebuild the pointer type later.
230
231                  This would all be simpler if attributes were part of the
232                  declarator, grumble grumble.  */
233               fn_ptr_tmp = TREE_TYPE (*anode);
234               anode = &fn_ptr_tmp;
235               flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
236             }
237           else if (flags & (int) ATTR_FLAG_FUNCTION_NEXT)
238             {
239               /* Pass on this attribute to be tried again.  */
240               returned_attrs = tree_cons (name, args, returned_attrs);
241               continue;
242             }
243
244           if (TREE_CODE (*anode) != FUNCTION_TYPE
245               && TREE_CODE (*anode) != METHOD_TYPE)
246             {
247               warning (OPT_Wattributes,
248                        "%qs attribute only applies to function types",
249                        IDENTIFIER_POINTER (name));
250               continue;
251             }
252         }
253
254       if (TYPE_P (*anode)
255           && (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
256           && TYPE_SIZE (*anode) != NULL_TREE)
257         {
258           warning (OPT_Wattributes, "type attributes ignored after type is already defined");
259           continue;
260         }
261
262       if (spec->handler != NULL)
263         returned_attrs = chainon ((*spec->handler) (anode, name, args,
264                                                     flags, &no_add_attrs),
265                                   returned_attrs);
266
267       /* Layout the decl in case anything changed.  */
268       if (spec->type_required && DECL_P (*node)
269           && (TREE_CODE (*node) == VAR_DECL
270               || TREE_CODE (*node) == PARM_DECL
271               || TREE_CODE (*node) == RESULT_DECL))
272         relayout_decl (*node);
273
274       if (!no_add_attrs)
275         {
276           tree old_attrs;
277           tree a;
278
279           if (DECL_P (*anode))
280             old_attrs = DECL_ATTRIBUTES (*anode);
281           else
282             old_attrs = TYPE_ATTRIBUTES (*anode);
283
284           for (a = lookup_attribute (spec->name, old_attrs);
285                a != NULL_TREE;
286                a = lookup_attribute (spec->name, TREE_CHAIN (a)))
287             {
288               if (simple_cst_equal (TREE_VALUE (a), args) == 1)
289                 break;
290             }
291
292           if (a == NULL_TREE)
293             {
294               /* This attribute isn't already in the list.  */
295               if (DECL_P (*anode))
296                 DECL_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
297               else if (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
298                 {
299                   TYPE_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
300                   /* If this is the main variant, also push the attributes
301                      out to the other variants.  */
302                   if (*anode == TYPE_MAIN_VARIANT (*anode))
303                     {
304                       tree variant;
305                       for (variant = *anode; variant;
306                            variant = TYPE_NEXT_VARIANT (variant))
307                         {
308                           if (TYPE_ATTRIBUTES (variant) == old_attrs)
309                             TYPE_ATTRIBUTES (variant)
310                               = TYPE_ATTRIBUTES (*anode);
311                           else if (!lookup_attribute
312                                    (spec->name, TYPE_ATTRIBUTES (variant)))
313                             TYPE_ATTRIBUTES (variant) = tree_cons
314                               (name, args, TYPE_ATTRIBUTES (variant));
315                         }
316                     }
317                 }
318               else
319                 *anode = build_type_attribute_variant (*anode,
320                                                        tree_cons (name, args,
321                                                                   old_attrs));
322             }
323         }
324
325       if (fn_ptr_tmp)
326         {
327            /* APPLE LOCAL begin radar 6246527 */
328            if (DECL_P (*node) && TREE_TYPE (*node) && 
329                TREE_CODE (TREE_TYPE (*node)) == BLOCK_POINTER_TYPE)
330              /* Rebuild the block pointer type and put it in the
331                 appropriate place.  */
332              fn_ptr_tmp = build_block_pointer_type (fn_ptr_tmp);
333            else
334            /* APPLE LOCAL end radar 6246527 */
335           /* Rebuild the function pointer type and put it in the
336              appropriate place.  */
337           fn_ptr_tmp = build_pointer_type (fn_ptr_tmp);
338           if (DECL_P (*node))
339             TREE_TYPE (*node) = fn_ptr_tmp;
340           else
341             {
342               gcc_assert (TREE_CODE (*node) == POINTER_TYPE);
343               *node = fn_ptr_tmp;
344             }
345         }
346     }
347
348   return returned_attrs;
349 }