xref: /dflybsd-src/contrib/gcc-4.7/gcc/attribs.c (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
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