1*e4b17023SJohn Marino /* Functions dealing with attribute handling, used by most front ends.
2*e4b17023SJohn Marino Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
3*e4b17023SJohn Marino 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
4*e4b17023SJohn Marino Free Software Foundation, Inc.
5*e4b17023SJohn Marino
6*e4b17023SJohn Marino This file is part of GCC.
7*e4b17023SJohn Marino
8*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
9*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
10*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
11*e4b17023SJohn Marino version.
12*e4b17023SJohn Marino
13*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
15*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16*e4b17023SJohn Marino for more details.
17*e4b17023SJohn Marino
18*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
20*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
21*e4b17023SJohn Marino
22*e4b17023SJohn Marino #include "config.h"
23*e4b17023SJohn Marino #include "system.h"
24*e4b17023SJohn Marino #include "coretypes.h"
25*e4b17023SJohn Marino #include "tm.h"
26*e4b17023SJohn Marino #include "tree.h"
27*e4b17023SJohn Marino #include "flags.h"
28*e4b17023SJohn Marino #include "diagnostic-core.h"
29*e4b17023SJohn Marino #include "ggc.h"
30*e4b17023SJohn Marino #include "tm_p.h"
31*e4b17023SJohn Marino #include "cpplib.h"
32*e4b17023SJohn Marino #include "target.h"
33*e4b17023SJohn Marino #include "langhooks.h"
34*e4b17023SJohn Marino #include "hashtab.h"
35*e4b17023SJohn Marino #include "plugin.h"
36*e4b17023SJohn Marino
37*e4b17023SJohn Marino /* Table of the tables of attributes (common, language, format, machine)
38*e4b17023SJohn Marino searched. */
39*e4b17023SJohn Marino static const struct attribute_spec *attribute_tables[4];
40*e4b17023SJohn Marino
41*e4b17023SJohn Marino /* Hashtable mapping names (represented as substrings) to attribute specs. */
42*e4b17023SJohn Marino static htab_t attribute_hash;
43*e4b17023SJohn Marino
44*e4b17023SJohn Marino /* Substring representation. */
45*e4b17023SJohn Marino
46*e4b17023SJohn Marino struct substring
47*e4b17023SJohn Marino {
48*e4b17023SJohn Marino const char *str;
49*e4b17023SJohn Marino int length;
50*e4b17023SJohn Marino };
51*e4b17023SJohn Marino
52*e4b17023SJohn Marino static bool attributes_initialized = false;
53*e4b17023SJohn Marino
54*e4b17023SJohn Marino /* Default empty table of attributes. */
55*e4b17023SJohn Marino
56*e4b17023SJohn Marino static const struct attribute_spec empty_attribute_table[] =
57*e4b17023SJohn Marino {
58*e4b17023SJohn Marino { NULL, 0, 0, false, false, false, NULL, false }
59*e4b17023SJohn Marino };
60*e4b17023SJohn Marino
61*e4b17023SJohn Marino /* Return base name of the attribute. Ie '__attr__' is turned into 'attr'.
62*e4b17023SJohn Marino To avoid need for copying, we simply return length of the string. */
63*e4b17023SJohn Marino
64*e4b17023SJohn Marino static void
extract_attribute_substring(struct substring * str)65*e4b17023SJohn Marino extract_attribute_substring (struct substring *str)
66*e4b17023SJohn Marino {
67*e4b17023SJohn Marino if (str->length > 4 && str->str[0] == '_' && str->str[1] == '_'
68*e4b17023SJohn Marino && str->str[str->length - 1] == '_' && str->str[str->length - 2] == '_')
69*e4b17023SJohn Marino {
70*e4b17023SJohn Marino str->length -= 4;
71*e4b17023SJohn Marino str->str += 2;
72*e4b17023SJohn Marino }
73*e4b17023SJohn Marino }
74*e4b17023SJohn Marino
75*e4b17023SJohn Marino /* Simple hash function to avoid need to scan whole string. */
76*e4b17023SJohn Marino
77*e4b17023SJohn Marino static inline hashval_t
substring_hash(const char * str,int l)78*e4b17023SJohn Marino substring_hash (const char *str, int l)
79*e4b17023SJohn Marino {
80*e4b17023SJohn Marino return str[0] + str[l - 1] * 256 + l * 65536;
81*e4b17023SJohn Marino }
82*e4b17023SJohn Marino
83*e4b17023SJohn Marino /* Used for attribute_hash. */
84*e4b17023SJohn Marino
85*e4b17023SJohn Marino static hashval_t
hash_attr(const void * p)86*e4b17023SJohn Marino hash_attr (const void *p)
87*e4b17023SJohn Marino {
88*e4b17023SJohn Marino const struct attribute_spec *const spec = (const struct attribute_spec *) p;
89*e4b17023SJohn Marino const int l = strlen (spec->name);
90*e4b17023SJohn Marino
91*e4b17023SJohn Marino return substring_hash (spec->name, l);
92*e4b17023SJohn Marino }
93*e4b17023SJohn Marino
94*e4b17023SJohn Marino /* Used for attribute_hash. */
95*e4b17023SJohn Marino
96*e4b17023SJohn Marino static int
eq_attr(const void * p,const void * q)97*e4b17023SJohn Marino eq_attr (const void *p, const void *q)
98*e4b17023SJohn Marino {
99*e4b17023SJohn Marino const struct attribute_spec *const spec = (const struct attribute_spec *) p;
100*e4b17023SJohn Marino const struct substring *const str = (const struct substring *) q;
101*e4b17023SJohn Marino
102*e4b17023SJohn Marino return (!strncmp (spec->name, str->str, str->length) && !spec->name[str->length]);
103*e4b17023SJohn Marino }
104*e4b17023SJohn Marino
105*e4b17023SJohn Marino /* Initialize attribute tables, and make some sanity checks
106*e4b17023SJohn Marino if --enable-checking. */
107*e4b17023SJohn Marino
108*e4b17023SJohn Marino void
init_attributes(void)109*e4b17023SJohn Marino init_attributes (void)
110*e4b17023SJohn Marino {
111*e4b17023SJohn Marino size_t i;
112*e4b17023SJohn Marino int k;
113*e4b17023SJohn Marino
114*e4b17023SJohn Marino if (attributes_initialized)
115*e4b17023SJohn Marino return;
116*e4b17023SJohn Marino
117*e4b17023SJohn Marino attribute_tables[0] = lang_hooks.common_attribute_table;
118*e4b17023SJohn Marino attribute_tables[1] = lang_hooks.attribute_table;
119*e4b17023SJohn Marino attribute_tables[2] = lang_hooks.format_attribute_table;
120*e4b17023SJohn Marino attribute_tables[3] = targetm.attribute_table;
121*e4b17023SJohn Marino
122*e4b17023SJohn Marino /* Translate NULL pointers to pointers to the empty table. */
123*e4b17023SJohn Marino for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
124*e4b17023SJohn Marino if (attribute_tables[i] == NULL)
125*e4b17023SJohn Marino attribute_tables[i] = empty_attribute_table;
126*e4b17023SJohn Marino
127*e4b17023SJohn Marino #ifdef ENABLE_CHECKING
128*e4b17023SJohn Marino /* Make some sanity checks on the attribute tables. */
129*e4b17023SJohn Marino for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
130*e4b17023SJohn Marino {
131*e4b17023SJohn Marino int j;
132*e4b17023SJohn Marino
133*e4b17023SJohn Marino for (j = 0; attribute_tables[i][j].name != NULL; j++)
134*e4b17023SJohn Marino {
135*e4b17023SJohn Marino /* The name must not begin and end with __. */
136*e4b17023SJohn Marino const char *name = attribute_tables[i][j].name;
137*e4b17023SJohn Marino int len = strlen (name);
138*e4b17023SJohn Marino
139*e4b17023SJohn Marino gcc_assert (!(name[0] == '_' && name[1] == '_'
140*e4b17023SJohn Marino && name[len - 1] == '_' && name[len - 2] == '_'));
141*e4b17023SJohn Marino
142*e4b17023SJohn Marino /* The minimum and maximum lengths must be consistent. */
143*e4b17023SJohn Marino gcc_assert (attribute_tables[i][j].min_length >= 0);
144*e4b17023SJohn Marino
145*e4b17023SJohn Marino gcc_assert (attribute_tables[i][j].max_length == -1
146*e4b17023SJohn Marino || (attribute_tables[i][j].max_length
147*e4b17023SJohn Marino >= attribute_tables[i][j].min_length));
148*e4b17023SJohn Marino
149*e4b17023SJohn Marino /* An attribute cannot require both a DECL and a TYPE. */
150*e4b17023SJohn Marino gcc_assert (!attribute_tables[i][j].decl_required
151*e4b17023SJohn Marino || !attribute_tables[i][j].type_required);
152*e4b17023SJohn Marino
153*e4b17023SJohn Marino /* If an attribute requires a function type, in particular
154*e4b17023SJohn Marino it requires a type. */
155*e4b17023SJohn Marino gcc_assert (!attribute_tables[i][j].function_type_required
156*e4b17023SJohn Marino || attribute_tables[i][j].type_required);
157*e4b17023SJohn Marino }
158*e4b17023SJohn Marino }
159*e4b17023SJohn Marino
160*e4b17023SJohn Marino /* Check that each name occurs just once in each table. */
161*e4b17023SJohn Marino for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
162*e4b17023SJohn Marino {
163*e4b17023SJohn Marino int j, k;
164*e4b17023SJohn Marino for (j = 0; attribute_tables[i][j].name != NULL; j++)
165*e4b17023SJohn Marino for (k = j + 1; attribute_tables[i][k].name != NULL; k++)
166*e4b17023SJohn Marino gcc_assert (strcmp (attribute_tables[i][j].name,
167*e4b17023SJohn Marino attribute_tables[i][k].name));
168*e4b17023SJohn Marino }
169*e4b17023SJohn Marino /* Check that no name occurs in more than one table. Names that
170*e4b17023SJohn Marino begin with '*' are exempt, and may be overridden. */
171*e4b17023SJohn Marino for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
172*e4b17023SJohn Marino {
173*e4b17023SJohn Marino size_t j, k, l;
174*e4b17023SJohn Marino
175*e4b17023SJohn Marino for (j = i + 1; j < ARRAY_SIZE (attribute_tables); j++)
176*e4b17023SJohn Marino for (k = 0; attribute_tables[i][k].name != NULL; k++)
177*e4b17023SJohn Marino for (l = 0; attribute_tables[j][l].name != NULL; l++)
178*e4b17023SJohn Marino gcc_assert (attribute_tables[i][k].name[0] == '*'
179*e4b17023SJohn Marino || strcmp (attribute_tables[i][k].name,
180*e4b17023SJohn Marino attribute_tables[j][l].name));
181*e4b17023SJohn Marino }
182*e4b17023SJohn Marino #endif
183*e4b17023SJohn Marino
184*e4b17023SJohn Marino attribute_hash = htab_create (200, hash_attr, eq_attr, NULL);
185*e4b17023SJohn Marino for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
186*e4b17023SJohn Marino for (k = 0; attribute_tables[i][k].name != NULL; k++)
187*e4b17023SJohn Marino {
188*e4b17023SJohn Marino register_attribute (&attribute_tables[i][k]);
189*e4b17023SJohn Marino }
190*e4b17023SJohn Marino invoke_plugin_callbacks (PLUGIN_ATTRIBUTES, NULL);
191*e4b17023SJohn Marino attributes_initialized = true;
192*e4b17023SJohn Marino }
193*e4b17023SJohn Marino
194*e4b17023SJohn Marino /* Insert a single ATTR into the attribute table. */
195*e4b17023SJohn Marino
196*e4b17023SJohn Marino void
register_attribute(const struct attribute_spec * attr)197*e4b17023SJohn Marino register_attribute (const struct attribute_spec *attr)
198*e4b17023SJohn Marino {
199*e4b17023SJohn Marino struct substring str;
200*e4b17023SJohn Marino void **slot;
201*e4b17023SJohn Marino
202*e4b17023SJohn Marino str.str = attr->name;
203*e4b17023SJohn Marino str.length = strlen (str.str);
204*e4b17023SJohn Marino
205*e4b17023SJohn Marino /* Attribute names in the table must be in the form 'text' and not
206*e4b17023SJohn Marino in the form '__text__'. */
207*e4b17023SJohn Marino gcc_assert (str.length > 0 && str.str[0] != '_');
208*e4b17023SJohn Marino
209*e4b17023SJohn Marino slot = htab_find_slot_with_hash (attribute_hash, &str,
210*e4b17023SJohn Marino substring_hash (str.str, str.length),
211*e4b17023SJohn Marino INSERT);
212*e4b17023SJohn Marino gcc_assert (!*slot || attr->name[0] == '*');
213*e4b17023SJohn Marino *slot = (void *) CONST_CAST (struct attribute_spec *, attr);
214*e4b17023SJohn Marino }
215*e4b17023SJohn Marino
216*e4b17023SJohn Marino /* Return the spec for the attribute named NAME. */
217*e4b17023SJohn Marino
218*e4b17023SJohn Marino const struct attribute_spec *
lookup_attribute_spec(const_tree name)219*e4b17023SJohn Marino lookup_attribute_spec (const_tree name)
220*e4b17023SJohn Marino {
221*e4b17023SJohn Marino struct substring attr;
222*e4b17023SJohn Marino
223*e4b17023SJohn Marino attr.str = IDENTIFIER_POINTER (name);
224*e4b17023SJohn Marino attr.length = IDENTIFIER_LENGTH (name);
225*e4b17023SJohn Marino extract_attribute_substring (&attr);
226*e4b17023SJohn Marino return (const struct attribute_spec *)
227*e4b17023SJohn Marino htab_find_with_hash (attribute_hash, &attr,
228*e4b17023SJohn Marino substring_hash (attr.str, attr.length));
229*e4b17023SJohn Marino }
230*e4b17023SJohn Marino
231*e4b17023SJohn Marino /* Process the attributes listed in ATTRIBUTES and install them in *NODE,
232*e4b17023SJohn Marino which is either a DECL (including a TYPE_DECL) or a TYPE. If a DECL,
233*e4b17023SJohn Marino it should be modified in place; if a TYPE, a copy should be created
234*e4b17023SJohn Marino unless ATTR_FLAG_TYPE_IN_PLACE is set in FLAGS. FLAGS gives further
235*e4b17023SJohn Marino information, in the form of a bitwise OR of flags in enum attribute_flags
236*e4b17023SJohn Marino from tree.h. Depending on these flags, some attributes may be
237*e4b17023SJohn Marino returned to be applied at a later stage (for example, to apply
238*e4b17023SJohn Marino a decl attribute to the declaration rather than to its type). */
239*e4b17023SJohn Marino
240*e4b17023SJohn Marino tree
decl_attributes(tree * node,tree attributes,int flags)241*e4b17023SJohn Marino decl_attributes (tree *node, tree attributes, int flags)
242*e4b17023SJohn Marino {
243*e4b17023SJohn Marino tree a;
244*e4b17023SJohn Marino tree returned_attrs = NULL_TREE;
245*e4b17023SJohn Marino
246*e4b17023SJohn Marino if (TREE_TYPE (*node) == error_mark_node)
247*e4b17023SJohn Marino return NULL_TREE;
248*e4b17023SJohn Marino
249*e4b17023SJohn Marino if (!attributes_initialized)
250*e4b17023SJohn Marino init_attributes ();
251*e4b17023SJohn Marino
252*e4b17023SJohn Marino /* If this is a function and the user used #pragma GCC optimize, add the
253*e4b17023SJohn Marino options to the attribute((optimize(...))) list. */
254*e4b17023SJohn Marino if (TREE_CODE (*node) == FUNCTION_DECL && current_optimize_pragma)
255*e4b17023SJohn Marino {
256*e4b17023SJohn Marino tree cur_attr = lookup_attribute ("optimize", attributes);
257*e4b17023SJohn Marino tree opts = copy_list (current_optimize_pragma);
258*e4b17023SJohn Marino
259*e4b17023SJohn Marino if (! cur_attr)
260*e4b17023SJohn Marino attributes
261*e4b17023SJohn Marino = tree_cons (get_identifier ("optimize"), opts, attributes);
262*e4b17023SJohn Marino else
263*e4b17023SJohn Marino TREE_VALUE (cur_attr) = chainon (opts, TREE_VALUE (cur_attr));
264*e4b17023SJohn Marino }
265*e4b17023SJohn Marino
266*e4b17023SJohn Marino if (TREE_CODE (*node) == FUNCTION_DECL
267*e4b17023SJohn Marino && optimization_current_node != optimization_default_node
268*e4b17023SJohn Marino && !DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node))
269*e4b17023SJohn Marino DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node) = optimization_current_node;
270*e4b17023SJohn Marino
271*e4b17023SJohn Marino /* If this is a function and the user used #pragma GCC target, add the
272*e4b17023SJohn Marino options to the attribute((target(...))) list. */
273*e4b17023SJohn Marino if (TREE_CODE (*node) == FUNCTION_DECL
274*e4b17023SJohn Marino && current_target_pragma
275*e4b17023SJohn Marino && targetm.target_option.valid_attribute_p (*node, NULL_TREE,
276*e4b17023SJohn Marino current_target_pragma, 0))
277*e4b17023SJohn Marino {
278*e4b17023SJohn Marino tree cur_attr = lookup_attribute ("target", attributes);
279*e4b17023SJohn Marino tree opts = copy_list (current_target_pragma);
280*e4b17023SJohn Marino
281*e4b17023SJohn Marino if (! cur_attr)
282*e4b17023SJohn Marino attributes = tree_cons (get_identifier ("target"), opts, attributes);
283*e4b17023SJohn Marino else
284*e4b17023SJohn Marino TREE_VALUE (cur_attr) = chainon (opts, TREE_VALUE (cur_attr));
285*e4b17023SJohn Marino }
286*e4b17023SJohn Marino
287*e4b17023SJohn Marino /* A "naked" function attribute implies "noinline" and "noclone" for
288*e4b17023SJohn Marino those targets that support it. */
289*e4b17023SJohn Marino if (TREE_CODE (*node) == FUNCTION_DECL
290*e4b17023SJohn Marino && attributes
291*e4b17023SJohn Marino && lookup_attribute_spec (get_identifier ("naked"))
292*e4b17023SJohn Marino && lookup_attribute ("naked", attributes) != NULL)
293*e4b17023SJohn Marino {
294*e4b17023SJohn Marino if (lookup_attribute ("noinline", attributes) == NULL)
295*e4b17023SJohn Marino attributes = tree_cons (get_identifier ("noinline"), NULL, attributes);
296*e4b17023SJohn Marino
297*e4b17023SJohn Marino if (lookup_attribute ("noclone", attributes) == NULL)
298*e4b17023SJohn Marino attributes = tree_cons (get_identifier ("noclone"), NULL, attributes);
299*e4b17023SJohn Marino }
300*e4b17023SJohn Marino
301*e4b17023SJohn Marino targetm.insert_attributes (*node, &attributes);
302*e4b17023SJohn Marino
303*e4b17023SJohn Marino for (a = attributes; a; a = TREE_CHAIN (a))
304*e4b17023SJohn Marino {
305*e4b17023SJohn Marino tree name = TREE_PURPOSE (a);
306*e4b17023SJohn Marino tree args = TREE_VALUE (a);
307*e4b17023SJohn Marino tree *anode = node;
308*e4b17023SJohn Marino const struct attribute_spec *spec = lookup_attribute_spec (name);
309*e4b17023SJohn Marino bool no_add_attrs = 0;
310*e4b17023SJohn Marino int fn_ptr_quals = 0;
311*e4b17023SJohn Marino tree fn_ptr_tmp = NULL_TREE;
312*e4b17023SJohn Marino
313*e4b17023SJohn Marino if (spec == NULL)
314*e4b17023SJohn Marino {
315*e4b17023SJohn Marino warning (OPT_Wattributes, "%qE attribute directive ignored",
316*e4b17023SJohn Marino name);
317*e4b17023SJohn Marino continue;
318*e4b17023SJohn Marino }
319*e4b17023SJohn Marino else if (list_length (args) < spec->min_length
320*e4b17023SJohn Marino || (spec->max_length >= 0
321*e4b17023SJohn Marino && list_length (args) > spec->max_length))
322*e4b17023SJohn Marino {
323*e4b17023SJohn Marino error ("wrong number of arguments specified for %qE attribute",
324*e4b17023SJohn Marino name);
325*e4b17023SJohn Marino continue;
326*e4b17023SJohn Marino }
327*e4b17023SJohn Marino gcc_assert (is_attribute_p (spec->name, name));
328*e4b17023SJohn Marino
329*e4b17023SJohn Marino if (spec->decl_required && !DECL_P (*anode))
330*e4b17023SJohn Marino {
331*e4b17023SJohn Marino if (flags & ((int) ATTR_FLAG_DECL_NEXT
332*e4b17023SJohn Marino | (int) ATTR_FLAG_FUNCTION_NEXT
333*e4b17023SJohn Marino | (int) ATTR_FLAG_ARRAY_NEXT))
334*e4b17023SJohn Marino {
335*e4b17023SJohn Marino /* Pass on this attribute to be tried again. */
336*e4b17023SJohn Marino returned_attrs = tree_cons (name, args, returned_attrs);
337*e4b17023SJohn Marino continue;
338*e4b17023SJohn Marino }
339*e4b17023SJohn Marino else
340*e4b17023SJohn Marino {
341*e4b17023SJohn Marino warning (OPT_Wattributes, "%qE attribute does not apply to types",
342*e4b17023SJohn Marino name);
343*e4b17023SJohn Marino continue;
344*e4b17023SJohn Marino }
345*e4b17023SJohn Marino }
346*e4b17023SJohn Marino
347*e4b17023SJohn Marino /* If we require a type, but were passed a decl, set up to make a
348*e4b17023SJohn Marino new type and update the one in the decl. ATTR_FLAG_TYPE_IN_PLACE
349*e4b17023SJohn Marino would have applied if we'd been passed a type, but we cannot modify
350*e4b17023SJohn Marino the decl's type in place here. */
351*e4b17023SJohn Marino if (spec->type_required && DECL_P (*anode))
352*e4b17023SJohn Marino {
353*e4b17023SJohn Marino anode = &TREE_TYPE (*anode);
354*e4b17023SJohn Marino /* Allow ATTR_FLAG_TYPE_IN_PLACE for the type's naming decl. */
355*e4b17023SJohn Marino if (!(TREE_CODE (*anode) == TYPE_DECL
356*e4b17023SJohn Marino && *anode == TYPE_NAME (TYPE_MAIN_VARIANT
357*e4b17023SJohn Marino (TREE_TYPE (*anode)))))
358*e4b17023SJohn Marino flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
359*e4b17023SJohn Marino }
360*e4b17023SJohn Marino
361*e4b17023SJohn Marino if (spec->function_type_required && TREE_CODE (*anode) != FUNCTION_TYPE
362*e4b17023SJohn Marino && TREE_CODE (*anode) != METHOD_TYPE)
363*e4b17023SJohn Marino {
364*e4b17023SJohn Marino if (TREE_CODE (*anode) == POINTER_TYPE
365*e4b17023SJohn Marino && (TREE_CODE (TREE_TYPE (*anode)) == FUNCTION_TYPE
366*e4b17023SJohn Marino || TREE_CODE (TREE_TYPE (*anode)) == METHOD_TYPE))
367*e4b17023SJohn Marino {
368*e4b17023SJohn Marino /* OK, this is a bit convoluted. We can't just make a copy
369*e4b17023SJohn Marino of the pointer type and modify its TREE_TYPE, because if
370*e4b17023SJohn Marino we change the attributes of the target type the pointer
371*e4b17023SJohn Marino type needs to have a different TYPE_MAIN_VARIANT. So we
372*e4b17023SJohn Marino pull out the target type now, frob it as appropriate, and
373*e4b17023SJohn Marino rebuild the pointer type later.
374*e4b17023SJohn Marino
375*e4b17023SJohn Marino This would all be simpler if attributes were part of the
376*e4b17023SJohn Marino declarator, grumble grumble. */
377*e4b17023SJohn Marino fn_ptr_tmp = TREE_TYPE (*anode);
378*e4b17023SJohn Marino fn_ptr_quals = TYPE_QUALS (*anode);
379*e4b17023SJohn Marino anode = &fn_ptr_tmp;
380*e4b17023SJohn Marino flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
381*e4b17023SJohn Marino }
382*e4b17023SJohn Marino else if (flags & (int) ATTR_FLAG_FUNCTION_NEXT)
383*e4b17023SJohn Marino {
384*e4b17023SJohn Marino /* Pass on this attribute to be tried again. */
385*e4b17023SJohn Marino returned_attrs = tree_cons (name, args, returned_attrs);
386*e4b17023SJohn Marino continue;
387*e4b17023SJohn Marino }
388*e4b17023SJohn Marino
389*e4b17023SJohn Marino if (TREE_CODE (*anode) != FUNCTION_TYPE
390*e4b17023SJohn Marino && TREE_CODE (*anode) != METHOD_TYPE)
391*e4b17023SJohn Marino {
392*e4b17023SJohn Marino warning (OPT_Wattributes,
393*e4b17023SJohn Marino "%qE attribute only applies to function types",
394*e4b17023SJohn Marino name);
395*e4b17023SJohn Marino continue;
396*e4b17023SJohn Marino }
397*e4b17023SJohn Marino }
398*e4b17023SJohn Marino
399*e4b17023SJohn Marino if (TYPE_P (*anode)
400*e4b17023SJohn Marino && (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
401*e4b17023SJohn Marino && TYPE_SIZE (*anode) != NULL_TREE)
402*e4b17023SJohn Marino {
403*e4b17023SJohn Marino warning (OPT_Wattributes, "type attributes ignored after type is already defined");
404*e4b17023SJohn Marino continue;
405*e4b17023SJohn Marino }
406*e4b17023SJohn Marino
407*e4b17023SJohn Marino if (spec->handler != NULL)
408*e4b17023SJohn Marino returned_attrs = chainon ((*spec->handler) (anode, name, args,
409*e4b17023SJohn Marino flags, &no_add_attrs),
410*e4b17023SJohn Marino returned_attrs);
411*e4b17023SJohn Marino
412*e4b17023SJohn Marino /* Layout the decl in case anything changed. */
413*e4b17023SJohn Marino if (spec->type_required && DECL_P (*node)
414*e4b17023SJohn Marino && (TREE_CODE (*node) == VAR_DECL
415*e4b17023SJohn Marino || TREE_CODE (*node) == PARM_DECL
416*e4b17023SJohn Marino || TREE_CODE (*node) == RESULT_DECL))
417*e4b17023SJohn Marino relayout_decl (*node);
418*e4b17023SJohn Marino
419*e4b17023SJohn Marino if (!no_add_attrs)
420*e4b17023SJohn Marino {
421*e4b17023SJohn Marino tree old_attrs;
422*e4b17023SJohn Marino tree a;
423*e4b17023SJohn Marino
424*e4b17023SJohn Marino if (DECL_P (*anode))
425*e4b17023SJohn Marino old_attrs = DECL_ATTRIBUTES (*anode);
426*e4b17023SJohn Marino else
427*e4b17023SJohn Marino old_attrs = TYPE_ATTRIBUTES (*anode);
428*e4b17023SJohn Marino
429*e4b17023SJohn Marino for (a = lookup_attribute (spec->name, old_attrs);
430*e4b17023SJohn Marino a != NULL_TREE;
431*e4b17023SJohn Marino a = lookup_attribute (spec->name, TREE_CHAIN (a)))
432*e4b17023SJohn Marino {
433*e4b17023SJohn Marino if (simple_cst_equal (TREE_VALUE (a), args) == 1)
434*e4b17023SJohn Marino break;
435*e4b17023SJohn Marino }
436*e4b17023SJohn Marino
437*e4b17023SJohn Marino if (a == NULL_TREE)
438*e4b17023SJohn Marino {
439*e4b17023SJohn Marino /* This attribute isn't already in the list. */
440*e4b17023SJohn Marino if (DECL_P (*anode))
441*e4b17023SJohn Marino DECL_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
442*e4b17023SJohn Marino else if (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
443*e4b17023SJohn Marino {
444*e4b17023SJohn Marino TYPE_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
445*e4b17023SJohn Marino /* If this is the main variant, also push the attributes
446*e4b17023SJohn Marino out to the other variants. */
447*e4b17023SJohn Marino if (*anode == TYPE_MAIN_VARIANT (*anode))
448*e4b17023SJohn Marino {
449*e4b17023SJohn Marino tree variant;
450*e4b17023SJohn Marino for (variant = *anode; variant;
451*e4b17023SJohn Marino variant = TYPE_NEXT_VARIANT (variant))
452*e4b17023SJohn Marino {
453*e4b17023SJohn Marino if (TYPE_ATTRIBUTES (variant) == old_attrs)
454*e4b17023SJohn Marino TYPE_ATTRIBUTES (variant)
455*e4b17023SJohn Marino = TYPE_ATTRIBUTES (*anode);
456*e4b17023SJohn Marino else if (!lookup_attribute
457*e4b17023SJohn Marino (spec->name, TYPE_ATTRIBUTES (variant)))
458*e4b17023SJohn Marino TYPE_ATTRIBUTES (variant) = tree_cons
459*e4b17023SJohn Marino (name, args, TYPE_ATTRIBUTES (variant));
460*e4b17023SJohn Marino }
461*e4b17023SJohn Marino }
462*e4b17023SJohn Marino }
463*e4b17023SJohn Marino else
464*e4b17023SJohn Marino *anode = build_type_attribute_variant (*anode,
465*e4b17023SJohn Marino tree_cons (name, args,
466*e4b17023SJohn Marino old_attrs));
467*e4b17023SJohn Marino }
468*e4b17023SJohn Marino }
469*e4b17023SJohn Marino
470*e4b17023SJohn Marino if (fn_ptr_tmp)
471*e4b17023SJohn Marino {
472*e4b17023SJohn Marino /* Rebuild the function pointer type and put it in the
473*e4b17023SJohn Marino appropriate place. */
474*e4b17023SJohn Marino fn_ptr_tmp = build_pointer_type (fn_ptr_tmp);
475*e4b17023SJohn Marino if (fn_ptr_quals)
476*e4b17023SJohn Marino fn_ptr_tmp = build_qualified_type (fn_ptr_tmp, fn_ptr_quals);
477*e4b17023SJohn Marino if (DECL_P (*node))
478*e4b17023SJohn Marino TREE_TYPE (*node) = fn_ptr_tmp;
479*e4b17023SJohn Marino else
480*e4b17023SJohn Marino {
481*e4b17023SJohn Marino gcc_assert (TREE_CODE (*node) == POINTER_TYPE);
482*e4b17023SJohn Marino *node = fn_ptr_tmp;
483*e4b17023SJohn Marino }
484*e4b17023SJohn Marino }
485*e4b17023SJohn Marino }
486*e4b17023SJohn Marino
487*e4b17023SJohn Marino return returned_attrs;
488*e4b17023SJohn Marino }
489*e4b17023SJohn Marino
490*e4b17023SJohn Marino /* Subroutine of set_method_tm_attributes. Apply TM attribute ATTR
491*e4b17023SJohn Marino to the method FNDECL. */
492*e4b17023SJohn Marino
493*e4b17023SJohn Marino void
apply_tm_attr(tree fndecl,tree attr)494*e4b17023SJohn Marino apply_tm_attr (tree fndecl, tree attr)
495*e4b17023SJohn Marino {
496*e4b17023SJohn Marino decl_attributes (&TREE_TYPE (fndecl), tree_cons (attr, NULL, NULL), 0);
497*e4b17023SJohn Marino }
498