attribs.c revision 90075
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 Free Software Foundation, Inc.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING.  If not, write to the Free
19Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2002111-1307, USA.  */
21
22#include "config.h"
23#include "system.h"
24#include "tree.h"
25#include "flags.h"
26#include "toplev.h"
27#include "output.h"
28#include "rtl.h"
29#include "ggc.h"
30#include "expr.h"
31#include "tm_p.h"
32#include "obstack.h"
33#include "cpplib.h"
34#include "target.h"
35
36static void init_attributes		PARAMS ((void));
37
38/* Table of the tables of attributes (common, format, language, machine)
39   searched.  */
40static const struct attribute_spec *attribute_tables[4];
41
42static bool attributes_initialized = false;
43
44static tree handle_packed_attribute	PARAMS ((tree *, tree, tree, int,
45						 bool *));
46static tree handle_nocommon_attribute	PARAMS ((tree *, tree, tree, int,
47						 bool *));
48static tree handle_common_attribute	PARAMS ((tree *, tree, tree, int,
49						 bool *));
50static tree handle_noreturn_attribute	PARAMS ((tree *, tree, tree, int,
51						 bool *));
52static tree handle_noinline_attribute	PARAMS ((tree *, tree, tree, int,
53						 bool *));
54static tree handle_used_attribute	PARAMS ((tree *, tree, tree, int,
55						 bool *));
56static tree handle_unused_attribute	PARAMS ((tree *, tree, tree, int,
57						 bool *));
58static tree handle_const_attribute	PARAMS ((tree *, tree, tree, int,
59						 bool *));
60static tree handle_transparent_union_attribute PARAMS ((tree *, tree, tree,
61							int, bool *));
62static tree handle_constructor_attribute PARAMS ((tree *, tree, tree, int,
63						  bool *));
64static tree handle_destructor_attribute PARAMS ((tree *, tree, tree, int,
65						 bool *));
66static tree handle_mode_attribute	PARAMS ((tree *, tree, tree, int,
67						 bool *));
68static tree handle_section_attribute	PARAMS ((tree *, tree, tree, int,
69						 bool *));
70static tree handle_aligned_attribute	PARAMS ((tree *, tree, tree, int,
71						 bool *));
72static tree handle_weak_attribute	PARAMS ((tree *, tree, tree, int,
73						 bool *));
74static tree handle_alias_attribute	PARAMS ((tree *, tree, tree, int,
75						 bool *));
76static tree handle_no_instrument_function_attribute PARAMS ((tree *, tree,
77							     tree, int,
78							     bool *));
79static tree handle_malloc_attribute	PARAMS ((tree *, tree, tree, int,
80						 bool *));
81static tree handle_no_limit_stack_attribute PARAMS ((tree *, tree, tree, int,
82						     bool *));
83static tree handle_pure_attribute	PARAMS ((tree *, tree, tree, int,
84						 bool *));
85static tree handle_deprecated_attribute	PARAMS ((tree *, tree, tree, int,
86						 bool *));
87static tree handle_vector_size_attribute PARAMS ((tree *, tree, tree, int,
88						  bool *));
89static tree vector_size_helper PARAMS ((tree, tree));
90
91/* Table of machine-independent attributes common to all C-like languages.  */
92static const struct attribute_spec c_common_attribute_table[] =
93{
94  /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
95  { "packed",                 0, 0, false, false, false,
96      			      handle_packed_attribute },
97  { "nocommon",               0, 0, true,  false, false,
98			      handle_nocommon_attribute },
99  { "common",                 0, 0, true,  false, false,
100			      handle_common_attribute },
101  /* FIXME: logically, noreturn attributes should be listed as
102     "false, true, true" and apply to function types.  But implementing this
103     would require all the places in the compiler that use TREE_THIS_VOLATILE
104     on a decl to identify non-returning functions to be located and fixed
105     to check the function type instead.  */
106  { "noreturn",               0, 0, true,  false, false,
107			      handle_noreturn_attribute },
108  { "volatile",               0, 0, true,  false, false,
109			      handle_noreturn_attribute },
110  { "noinline",               0, 0, true,  false, false,
111			      handle_noinline_attribute },
112  { "used",                   0, 0, true,  false, false,
113			      handle_used_attribute },
114  { "unused",                 0, 0, false, false, false,
115			      handle_unused_attribute },
116  /* The same comments as for noreturn attributes apply to const ones.  */
117  { "const",                  0, 0, true,  false, false,
118			      handle_const_attribute },
119  { "transparent_union",      0, 0, false, false, false,
120			      handle_transparent_union_attribute },
121  { "constructor",            0, 0, true,  false, false,
122			      handle_constructor_attribute },
123  { "destructor",             0, 0, true,  false, false,
124			      handle_destructor_attribute },
125  { "mode",                   1, 1, false,  true, false,
126			      handle_mode_attribute },
127  { "section",                1, 1, true,  false, false,
128			      handle_section_attribute },
129  { "aligned",                0, 1, false, false, false,
130			      handle_aligned_attribute },
131  { "weak",                   0, 0, true,  false, false,
132			      handle_weak_attribute },
133  { "alias",                  1, 1, true,  false, false,
134			      handle_alias_attribute },
135  { "no_instrument_function", 0, 0, true,  false, false,
136			      handle_no_instrument_function_attribute },
137  { "malloc",                 0, 0, true,  false, false,
138			      handle_malloc_attribute },
139  { "no_stack_limit",         0, 0, true,  false, false,
140			      handle_no_limit_stack_attribute },
141  { "pure",                   0, 0, true,  false, false,
142			      handle_pure_attribute },
143  { "deprecated",             0, 0, false, false, false,
144			      handle_deprecated_attribute },
145  { "vector_size",	      1, 1, false, true, false,
146			      handle_vector_size_attribute },
147  { NULL,                     0, 0, false, false, false, NULL }
148};
149
150/* Default empty table of attributes.  */
151static const struct attribute_spec empty_attribute_table[] =
152{
153  { NULL, 0, 0, false, false, false, NULL }
154};
155
156/* Table of machine-independent attributes for checking formats, if used.  */
157const struct attribute_spec *format_attribute_table = empty_attribute_table;
158
159/* Table of machine-independent attributes for a particular language.  */
160const struct attribute_spec *lang_attribute_table = empty_attribute_table;
161
162/* Flag saying whether common language attributes are to be supported.  */
163int lang_attribute_common = 1;
164
165/* Initialize attribute tables, and make some sanity checks
166   if --enable-checking.  */
167
168static void
169init_attributes ()
170{
171#ifdef ENABLE_CHECKING
172  int i;
173#endif
174
175  attribute_tables[0]
176    = lang_attribute_common ? c_common_attribute_table : empty_attribute_table;
177  attribute_tables[1] = lang_attribute_table;
178  attribute_tables[2] = format_attribute_table;
179  attribute_tables[3] = targetm.attribute_table;
180
181#ifdef ENABLE_CHECKING
182  /* Make some sanity checks on the attribute tables.  */
183  for (i = 0;
184       i < (int) (sizeof (attribute_tables) / sizeof (attribute_tables[0]));
185       i++)
186    {
187      int j;
188
189      for (j = 0; attribute_tables[i][j].name != NULL; j++)
190	{
191	  /* The name must not begin and end with __.  */
192	  const char *name = attribute_tables[i][j].name;
193	  int len = strlen (name);
194	  if (name[0] == '_' && name[1] == '_'
195	      && name[len - 1] == '_' && name[len - 2] == '_')
196	    abort ();
197	  /* The minimum and maximum lengths must be consistent.  */
198	  if (attribute_tables[i][j].min_length < 0)
199	    abort ();
200	  if (attribute_tables[i][j].max_length != -1
201	      && (attribute_tables[i][j].max_length
202		  < attribute_tables[i][j].min_length))
203	    abort ();
204	  /* An attribute cannot require both a DECL and a TYPE.  */
205	  if (attribute_tables[i][j].decl_required
206	      && attribute_tables[i][j].type_required)
207	    abort ();
208	  /* If an attribute requires a function type, in particular
209	     it requires a type.  */
210	  if (attribute_tables[i][j].function_type_required
211	      && !attribute_tables[i][j].type_required)
212	    abort ();
213	}
214    }
215
216  /* Check that each name occurs just once in each table.  */
217  for (i = 0;
218       i < (int) (sizeof (attribute_tables) / sizeof (attribute_tables[0]));
219       i++)
220    {
221      int j, k;
222      for (j = 0; attribute_tables[i][j].name != NULL; j++)
223	for (k = j + 1; attribute_tables[i][k].name != NULL; k++)
224	  if (!strcmp (attribute_tables[i][j].name,
225		       attribute_tables[i][k].name))
226	    abort ();
227    }
228  /* Check that no name occurs in more than one table.  */
229  for (i = 0;
230       i < (int) (sizeof (attribute_tables) / sizeof (attribute_tables[0]));
231       i++)
232    {
233      int j, k, l;
234
235      for (j = i + 1;
236	   j < ((int) (sizeof (attribute_tables)
237		       / sizeof (attribute_tables[0])));
238	   j++)
239	for (k = 0; attribute_tables[i][k].name != NULL; k++)
240	  for (l = 0; attribute_tables[j][l].name != NULL; l++)
241	    if (!strcmp (attribute_tables[i][k].name,
242			 attribute_tables[j][l].name))
243	      abort ();
244    }
245#endif
246
247  attributes_initialized = true;
248}
249
250/* Process the attributes listed in ATTRIBUTES and install them in *NODE,
251   which is either a DECL (including a TYPE_DECL) or a TYPE.  If a DECL,
252   it should be modified in place; if a TYPE, a copy should be created
253   unless ATTR_FLAG_TYPE_IN_PLACE is set in FLAGS.  FLAGS gives further
254   information, in the form of a bitwise OR of flags in enum attribute_flags
255   from tree.h.  Depending on these flags, some attributes may be
256   returned to be applied at a later stage (for example, to apply
257   a decl attribute to the declaration rather than to its type).  If
258   ATTR_FLAG_BUILT_IN is not set and *NODE is a DECL, then also consider
259   whether there might be some default attributes to apply to this DECL;
260   if so, decl_attributes will be called recursively with those attributes
261   and ATTR_FLAG_BUILT_IN set.  */
262
263tree
264decl_attributes (node, attributes, flags)
265     tree *node, attributes;
266     int flags;
267{
268  tree a;
269  tree returned_attrs = NULL_TREE;
270
271  if (!attributes_initialized)
272    init_attributes ();
273
274  (*targetm.insert_attributes) (*node, &attributes);
275
276  if (DECL_P (*node) && TREE_CODE (*node) == FUNCTION_DECL
277      && !(flags & (int) ATTR_FLAG_BUILT_IN))
278    insert_default_attributes (*node);
279
280  for (a = attributes; a; a = TREE_CHAIN (a))
281    {
282      tree name = TREE_PURPOSE (a);
283      tree args = TREE_VALUE (a);
284      tree *anode = node;
285      const struct attribute_spec *spec = NULL;
286      bool no_add_attrs = 0;
287      int i;
288
289      for (i = 0;
290	   i < ((int) (sizeof (attribute_tables)
291		       / sizeof (attribute_tables[0])));
292	   i++)
293	{
294	  int j;
295
296	  for (j = 0; attribute_tables[i][j].name != NULL; j++)
297	    {
298	      if (is_attribute_p (attribute_tables[i][j].name, name))
299		{
300		  spec = &attribute_tables[i][j];
301		  break;
302		}
303	    }
304	  if (spec != NULL)
305	    break;
306	}
307
308      if (spec == NULL)
309	{
310	  warning ("`%s' attribute directive ignored",
311		   IDENTIFIER_POINTER (name));
312	  continue;
313	}
314      else if (list_length (args) < spec->min_length
315	       || (spec->max_length >= 0
316		   && list_length (args) > spec->max_length))
317	{
318	  error ("wrong number of arguments specified for `%s' attribute",
319		 IDENTIFIER_POINTER (name));
320	  continue;
321	}
322
323      if (spec->decl_required && !DECL_P (*anode))
324	{
325	  if (flags & ((int) ATTR_FLAG_DECL_NEXT
326		       | (int) ATTR_FLAG_FUNCTION_NEXT
327		       | (int) ATTR_FLAG_ARRAY_NEXT))
328	    {
329	      /* Pass on this attribute to be tried again.  */
330	      returned_attrs = tree_cons (name, args, returned_attrs);
331	      continue;
332	    }
333	  else
334	    {
335	      warning ("`%s' attribute does not apply to types",
336		       IDENTIFIER_POINTER (name));
337	      continue;
338	    }
339	}
340
341      /* If we require a type, but were passed a decl, set up to make a
342	 new type and update the one in the decl.  ATTR_FLAG_TYPE_IN_PLACE
343	 would have applied if we'd been passed a type, but we cannot modify
344	 the decl's type in place here.  */
345      if (spec->type_required && DECL_P (*anode))
346	{
347	  anode = &TREE_TYPE (*anode);
348	  flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
349	}
350
351      if (spec->function_type_required && TREE_CODE (*anode) != FUNCTION_TYPE
352	  && TREE_CODE (*anode) != METHOD_TYPE)
353	{
354	  if (TREE_CODE (*anode) == POINTER_TYPE
355	      && (TREE_CODE (TREE_TYPE (*anode)) == FUNCTION_TYPE
356		  || TREE_CODE (TREE_TYPE (*anode)) == METHOD_TYPE))
357	    {
358	      if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
359		*anode = build_type_copy (*anode);
360	      anode = &TREE_TYPE (*anode);
361	    }
362	  else if (flags & (int) ATTR_FLAG_FUNCTION_NEXT)
363	    {
364	      /* Pass on this attribute to be tried again.  */
365	      returned_attrs = tree_cons (name, args, returned_attrs);
366	      continue;
367	    }
368
369	  if (TREE_CODE (*anode) != FUNCTION_TYPE
370	      && TREE_CODE (*anode) != METHOD_TYPE)
371	    {
372	      warning ("`%s' attribute only applies to function types",
373		       IDENTIFIER_POINTER (name));
374	      continue;
375	    }
376	}
377
378      if (spec->handler != NULL)
379	returned_attrs = chainon ((*spec->handler) (anode, name, args,
380						    flags, &no_add_attrs),
381				  returned_attrs);
382
383      /* Layout the decl in case anything changed.  */
384      if (spec->type_required && DECL_P (*node)
385	  && TREE_CODE (*node) == VAR_DECL)
386	{
387	  /* Force a recalculation of mode and size.  */
388	  DECL_MODE (*node) = VOIDmode;
389	  DECL_SIZE (*node) = 0;
390
391	  layout_decl (*node, 0);
392	}
393
394      if (!no_add_attrs)
395	{
396	  tree old_attrs;
397	  tree a;
398
399	  if (DECL_P (*anode))
400	    old_attrs = DECL_ATTRIBUTES (*anode);
401	  else
402	    old_attrs = TYPE_ATTRIBUTES (*anode);
403
404	  for (a = lookup_attribute (spec->name, old_attrs);
405	       a != NULL_TREE;
406	       a = lookup_attribute (spec->name, TREE_CHAIN (a)))
407	    {
408	      if (simple_cst_equal (TREE_VALUE (a), args) == 1)
409		break;
410	    }
411
412	  if (a == NULL_TREE)
413	    {
414	      /* This attribute isn't already in the list.  */
415	      if (DECL_P (*anode))
416		DECL_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
417	      else if (flags & (int) ATTR_FLAG_TYPE_IN_PLACE)
418		TYPE_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs);
419	      else
420		*anode = build_type_attribute_variant (*anode,
421						       tree_cons (name, args,
422								  old_attrs));
423	    }
424	}
425    }
426
427  return returned_attrs;
428}
429
430/* Handle a "packed" attribute; arguments as in
431   struct attribute_spec.handler.  */
432
433static tree
434handle_packed_attribute (node, name, args, flags, no_add_attrs)
435     tree *node;
436     tree name;
437     tree args ATTRIBUTE_UNUSED;
438     int flags;
439     bool *no_add_attrs;
440{
441  tree *type = NULL;
442  if (DECL_P (*node))
443    {
444      if (TREE_CODE (*node) == TYPE_DECL)
445	type = &TREE_TYPE (*node);
446    }
447  else
448    type = node;
449
450  if (type)
451    {
452      if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
453	*type = build_type_copy (*type);
454      TYPE_PACKED (*type) = 1;
455    }
456  else if (TREE_CODE (*node) == FIELD_DECL)
457    DECL_PACKED (*node) = 1;
458  /* We can't set DECL_PACKED for a VAR_DECL, because the bit is
459     used for DECL_REGISTER.  It wouldn't mean anything anyway.  */
460  else
461    {
462      warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
463      *no_add_attrs = true;
464    }
465
466  return NULL_TREE;
467}
468
469/* Handle a "nocommon" attribute; arguments as in
470   struct attribute_spec.handler.  */
471
472static tree
473handle_nocommon_attribute (node, name, args, flags, no_add_attrs)
474     tree *node;
475     tree name;
476     tree args ATTRIBUTE_UNUSED;
477     int flags ATTRIBUTE_UNUSED;
478     bool *no_add_attrs;
479{
480  if (TREE_CODE (*node) == VAR_DECL)
481    DECL_COMMON (*node) = 0;
482  else
483    {
484      warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
485      *no_add_attrs = true;
486    }
487
488  return NULL_TREE;
489}
490
491/* Handle a "common" attribute; arguments as in
492   struct attribute_spec.handler.  */
493
494static tree
495handle_common_attribute (node, name, args, flags, no_add_attrs)
496     tree *node;
497     tree name;
498     tree args ATTRIBUTE_UNUSED;
499     int flags ATTRIBUTE_UNUSED;
500     bool *no_add_attrs;
501{
502  if (TREE_CODE (*node) == VAR_DECL)
503    DECL_COMMON (*node) = 1;
504  else
505    {
506      warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
507      *no_add_attrs = true;
508    }
509
510  return NULL_TREE;
511}
512
513/* Handle a "noreturn" attribute; arguments as in
514   struct attribute_spec.handler.  */
515
516static tree
517handle_noreturn_attribute (node, name, args, flags, no_add_attrs)
518     tree *node;
519     tree name;
520     tree args ATTRIBUTE_UNUSED;
521     int flags ATTRIBUTE_UNUSED;
522     bool *no_add_attrs;
523{
524  tree type = TREE_TYPE (*node);
525
526  /* See FIXME comment in c_common_attribute_table.  */
527  if (TREE_CODE (*node) == FUNCTION_DECL)
528    TREE_THIS_VOLATILE (*node) = 1;
529  else if (TREE_CODE (type) == POINTER_TYPE
530	   && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
531    TREE_TYPE (*node)
532      = build_pointer_type
533	(build_type_variant (TREE_TYPE (type),
534			     TREE_READONLY (TREE_TYPE (type)), 1));
535  else
536    {
537      warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
538      *no_add_attrs = true;
539    }
540
541  return NULL_TREE;
542}
543
544/* Handle a "noinline" attribute; arguments as in
545   struct attribute_spec.handler.  */
546
547static tree
548handle_noinline_attribute (node, name, args, flags, no_add_attrs)
549     tree *node;
550     tree name;
551     tree args ATTRIBUTE_UNUSED;
552     int flags ATTRIBUTE_UNUSED;
553     bool *no_add_attrs;
554{
555  if (TREE_CODE (*node) == FUNCTION_DECL)
556    DECL_UNINLINABLE (*node) = 1;
557  else
558    {
559      warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
560      *no_add_attrs = true;
561    }
562
563  return NULL_TREE;
564}
565
566/* Handle a "used" attribute; arguments as in
567   struct attribute_spec.handler.  */
568
569static tree
570handle_used_attribute (node, name, args, flags, no_add_attrs)
571     tree *node;
572     tree name;
573     tree args ATTRIBUTE_UNUSED;
574     int flags ATTRIBUTE_UNUSED;
575     bool *no_add_attrs;
576{
577  if (TREE_CODE (*node) == FUNCTION_DECL)
578    TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (*node))
579      = TREE_USED (*node) = 1;
580  else
581    {
582      warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
583      *no_add_attrs = true;
584    }
585
586  return NULL_TREE;
587}
588
589/* Handle a "unused" attribute; arguments as in
590   struct attribute_spec.handler.  */
591
592static tree
593handle_unused_attribute (node, name, args, flags, no_add_attrs)
594     tree *node;
595     tree name;
596     tree args ATTRIBUTE_UNUSED;
597     int flags;
598     bool *no_add_attrs;
599{
600  if (DECL_P (*node))
601    {
602      tree decl = *node;
603
604      if (TREE_CODE (decl) == PARM_DECL
605	  || TREE_CODE (decl) == VAR_DECL
606	  || TREE_CODE (decl) == FUNCTION_DECL
607	  || TREE_CODE (decl) == LABEL_DECL
608	  || TREE_CODE (decl) == TYPE_DECL)
609	TREE_USED (decl) = 1;
610      else
611	{
612	  warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
613	  *no_add_attrs = true;
614	}
615    }
616  else
617    {
618      if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
619	*node = build_type_copy (*node);
620      TREE_USED (*node) = 1;
621    }
622
623  return NULL_TREE;
624}
625
626/* Handle a "const" attribute; arguments as in
627   struct attribute_spec.handler.  */
628
629static tree
630handle_const_attribute (node, name, args, flags, no_add_attrs)
631     tree *node;
632     tree name;
633     tree args ATTRIBUTE_UNUSED;
634     int flags ATTRIBUTE_UNUSED;
635     bool *no_add_attrs;
636{
637  tree type = TREE_TYPE (*node);
638
639  /* See FIXME comment on noreturn in c_common_attribute_table.  */
640  if (TREE_CODE (*node) == FUNCTION_DECL)
641    TREE_READONLY (*node) = 1;
642  else if (TREE_CODE (type) == POINTER_TYPE
643	   && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
644    TREE_TYPE (*node)
645      = build_pointer_type
646	(build_type_variant (TREE_TYPE (type), 1,
647			     TREE_THIS_VOLATILE (TREE_TYPE (type))));
648  else
649    {
650      warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
651      *no_add_attrs = true;
652    }
653
654  return NULL_TREE;
655}
656
657/* Handle a "transparent_union" attribute; arguments as in
658   struct attribute_spec.handler.  */
659
660static tree
661handle_transparent_union_attribute (node, name, args, flags, no_add_attrs)
662     tree *node;
663     tree name;
664     tree args ATTRIBUTE_UNUSED;
665     int flags;
666     bool *no_add_attrs;
667{
668  tree decl = NULL_TREE;
669  tree *type = NULL;
670  int is_type = 0;
671
672  if (DECL_P (*node))
673    {
674      decl = *node;
675      type = &TREE_TYPE (decl);
676      is_type = TREE_CODE (*node) == TYPE_DECL;
677    }
678  else if (TYPE_P (*node))
679    type = node, is_type = 1;
680
681  if (is_type
682      && TREE_CODE (*type) == UNION_TYPE
683      && (decl == 0
684	  || (TYPE_FIELDS (*type) != 0
685	      && TYPE_MODE (*type) == DECL_MODE (TYPE_FIELDS (*type)))))
686    {
687      if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
688	*type = build_type_copy (*type);
689      TYPE_TRANSPARENT_UNION (*type) = 1;
690    }
691  else if (decl != 0 && TREE_CODE (decl) == PARM_DECL
692	   && TREE_CODE (*type) == UNION_TYPE
693	   && TYPE_MODE (*type) == DECL_MODE (TYPE_FIELDS (*type)))
694    DECL_TRANSPARENT_UNION (decl) = 1;
695  else
696    {
697      warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
698      *no_add_attrs = true;
699    }
700
701  return NULL_TREE;
702}
703
704/* Handle a "constructor" attribute; arguments as in
705   struct attribute_spec.handler.  */
706
707static tree
708handle_constructor_attribute (node, name, args, flags, no_add_attrs)
709     tree *node;
710     tree name;
711     tree args ATTRIBUTE_UNUSED;
712     int flags ATTRIBUTE_UNUSED;
713     bool *no_add_attrs;
714{
715  tree decl = *node;
716  tree type = TREE_TYPE (decl);
717
718  if (TREE_CODE (decl) == FUNCTION_DECL
719      && TREE_CODE (type) == FUNCTION_TYPE
720      && decl_function_context (decl) == 0)
721    {
722      DECL_STATIC_CONSTRUCTOR (decl) = 1;
723      TREE_USED (decl) = 1;
724    }
725  else
726    {
727      warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
728      *no_add_attrs = true;
729    }
730
731  return NULL_TREE;
732}
733
734/* Handle a "destructor" attribute; arguments as in
735   struct attribute_spec.handler.  */
736
737static tree
738handle_destructor_attribute (node, name, args, flags, no_add_attrs)
739     tree *node;
740     tree name;
741     tree args ATTRIBUTE_UNUSED;
742     int flags ATTRIBUTE_UNUSED;
743     bool *no_add_attrs;
744{
745  tree decl = *node;
746  tree type = TREE_TYPE (decl);
747
748  if (TREE_CODE (decl) == FUNCTION_DECL
749      && TREE_CODE (type) == FUNCTION_TYPE
750      && decl_function_context (decl) == 0)
751    {
752      DECL_STATIC_DESTRUCTOR (decl) = 1;
753      TREE_USED (decl) = 1;
754    }
755  else
756    {
757      warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
758      *no_add_attrs = true;
759    }
760
761  return NULL_TREE;
762}
763
764/* Handle a "mode" attribute; arguments as in
765   struct attribute_spec.handler.  */
766
767static tree
768handle_mode_attribute (node, name, args, flags, no_add_attrs)
769     tree *node;
770     tree name;
771     tree args;
772     int flags ATTRIBUTE_UNUSED;
773     bool *no_add_attrs;
774{
775  tree type = *node;
776
777  *no_add_attrs = true;
778
779  if (TREE_CODE (TREE_VALUE (args)) != IDENTIFIER_NODE)
780    warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
781  else
782    {
783      int j;
784      const char *p = IDENTIFIER_POINTER (TREE_VALUE (args));
785      int len = strlen (p);
786      enum machine_mode mode = VOIDmode;
787      tree typefm;
788
789      if (len > 4 && p[0] == '_' && p[1] == '_'
790	  && p[len - 1] == '_' && p[len - 2] == '_')
791	{
792	  char *newp = (char *) alloca (len - 1);
793
794	  strcpy (newp, &p[2]);
795	  newp[len - 4] = '\0';
796	  p = newp;
797	}
798
799      /* Change this type to have a type with the specified mode.
800	 First check for the special modes.  */
801      if (! strcmp (p, "byte"))
802	mode = byte_mode;
803      else if (!strcmp (p, "word"))
804	mode = word_mode;
805      else if (! strcmp (p, "pointer"))
806	mode = ptr_mode;
807      else
808	for (j = 0; j < NUM_MACHINE_MODES; j++)
809	  if (!strcmp (p, GET_MODE_NAME (j)))
810	    mode = (enum machine_mode) j;
811
812      if (mode == VOIDmode)
813	error ("unknown machine mode `%s'", p);
814      else if (0 == (typefm = type_for_mode (mode,
815					     TREE_UNSIGNED (type))))
816	error ("no data type for mode `%s'", p);
817      else
818	*node = typefm;
819        /* No need to layout the type here.  The caller should do this.  */
820    }
821
822  return NULL_TREE;
823}
824
825/* Handle a "section" attribute; arguments as in
826   struct attribute_spec.handler.  */
827
828static tree
829handle_section_attribute (node, name, args, flags, no_add_attrs)
830     tree *node;
831     tree name ATTRIBUTE_UNUSED;
832     tree args;
833     int flags ATTRIBUTE_UNUSED;
834     bool *no_add_attrs;
835{
836  tree decl = *node;
837
838  if (targetm.have_named_sections)
839    {
840      if ((TREE_CODE (decl) == FUNCTION_DECL
841	   || TREE_CODE (decl) == VAR_DECL)
842	  && TREE_CODE (TREE_VALUE (args)) == STRING_CST)
843	{
844	  if (TREE_CODE (decl) == VAR_DECL
845	      && current_function_decl != NULL_TREE
846	      && ! TREE_STATIC (decl))
847	    {
848	      error_with_decl (decl,
849			       "section attribute cannot be specified for local variables");
850	      *no_add_attrs = true;
851	    }
852
853	  /* The decl may have already been given a section attribute
854	     from a previous declaration.  Ensure they match.  */
855	  else if (DECL_SECTION_NAME (decl) != NULL_TREE
856		   && strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)),
857			      TREE_STRING_POINTER (TREE_VALUE (args))) != 0)
858	    {
859	      error_with_decl (*node,
860			       "section of `%s' conflicts with previous declaration");
861	      *no_add_attrs = true;
862	    }
863	  else
864	    DECL_SECTION_NAME (decl) = TREE_VALUE (args);
865	}
866      else
867	{
868	  error_with_decl (*node,
869			   "section attribute not allowed for `%s'");
870	  *no_add_attrs = true;
871	}
872    }
873  else
874    {
875      error_with_decl (*node,
876		       "section attributes are not supported for this target");
877      *no_add_attrs = true;
878    }
879
880  return NULL_TREE;
881}
882
883/* Handle a "aligned" attribute; arguments as in
884   struct attribute_spec.handler.  */
885
886static tree
887handle_aligned_attribute (node, name, args, flags, no_add_attrs)
888     tree *node;
889     tree name ATTRIBUTE_UNUSED;
890     tree args;
891     int flags;
892     bool *no_add_attrs;
893{
894  tree decl = NULL_TREE;
895  tree *type = NULL;
896  int is_type = 0;
897  tree align_expr = (args ? TREE_VALUE (args)
898		     : size_int (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
899  int i;
900
901  if (DECL_P (*node))
902    {
903      decl = *node;
904      type = &TREE_TYPE (decl);
905      is_type = TREE_CODE (*node) == TYPE_DECL;
906    }
907  else if (TYPE_P (*node))
908    type = node, is_type = 1;
909
910  /* Strip any NOPs of any kind.  */
911  while (TREE_CODE (align_expr) == NOP_EXPR
912	 || TREE_CODE (align_expr) == CONVERT_EXPR
913	 || TREE_CODE (align_expr) == NON_LVALUE_EXPR)
914    align_expr = TREE_OPERAND (align_expr, 0);
915
916  if (TREE_CODE (align_expr) != INTEGER_CST)
917    {
918      error ("requested alignment is not a constant");
919      *no_add_attrs = true;
920    }
921  else if ((i = tree_log2 (align_expr)) == -1)
922    {
923      error ("requested alignment is not a power of 2");
924      *no_add_attrs = true;
925    }
926  else if (i > HOST_BITS_PER_INT - 2)
927    {
928      error ("requested alignment is too large");
929      *no_add_attrs = true;
930    }
931  else if (is_type)
932    {
933      /* If we have a TYPE_DECL, then copy the type, so that we
934	 don't accidentally modify a builtin type.  See pushdecl.  */
935      if (decl && TREE_TYPE (decl) != error_mark_node
936	  && DECL_ORIGINAL_TYPE (decl) == NULL_TREE)
937	{
938	  tree tt = TREE_TYPE (decl);
939	  *type = build_type_copy (*type);
940	  DECL_ORIGINAL_TYPE (decl) = tt;
941	  TYPE_NAME (*type) = decl;
942	  TREE_USED (*type) = TREE_USED (decl);
943	  TREE_TYPE (decl) = *type;
944	}
945      else if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
946	*type = build_type_copy (*type);
947
948      TYPE_ALIGN (*type) = (1 << i) * BITS_PER_UNIT;
949      TYPE_USER_ALIGN (*type) = 1;
950    }
951  else if (TREE_CODE (decl) != VAR_DECL
952	   && TREE_CODE (decl) != FIELD_DECL)
953    {
954      error_with_decl (decl,
955		       "alignment may not be specified for `%s'");
956      *no_add_attrs = true;
957    }
958  else
959    {
960      DECL_ALIGN (decl) = (1 << i) * BITS_PER_UNIT;
961      DECL_USER_ALIGN (decl) = 1;
962    }
963
964  return NULL_TREE;
965}
966
967/* Handle a "weak" attribute; arguments as in
968   struct attribute_spec.handler.  */
969
970static tree
971handle_weak_attribute (node, name, args, flags, no_add_attrs)
972     tree *node;
973     tree name ATTRIBUTE_UNUSED;
974     tree args ATTRIBUTE_UNUSED;
975     int flags ATTRIBUTE_UNUSED;
976     bool *no_add_attrs ATTRIBUTE_UNUSED;
977{
978  declare_weak (*node);
979
980  return NULL_TREE;
981}
982
983/* Handle an "alias" attribute; arguments as in
984   struct attribute_spec.handler.  */
985
986static tree
987handle_alias_attribute (node, name, args, flags, no_add_attrs)
988     tree *node;
989     tree name;
990     tree args;
991     int flags ATTRIBUTE_UNUSED;
992     bool *no_add_attrs;
993{
994  tree decl = *node;
995
996  if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl))
997      || (TREE_CODE (decl) != FUNCTION_DECL && ! DECL_EXTERNAL (decl)))
998    {
999      error_with_decl (decl,
1000		       "`%s' defined both normally and as an alias");
1001      *no_add_attrs = true;
1002    }
1003  else if (decl_function_context (decl) == 0)
1004    {
1005      tree id;
1006
1007      id = TREE_VALUE (args);
1008      if (TREE_CODE (id) != STRING_CST)
1009	{
1010	  error ("alias arg not a string");
1011	  *no_add_attrs = true;
1012	  return NULL_TREE;
1013	}
1014      id = get_identifier (TREE_STRING_POINTER (id));
1015      /* This counts as a use of the object pointed to.  */
1016      TREE_USED (id) = 1;
1017
1018      if (TREE_CODE (decl) == FUNCTION_DECL)
1019	DECL_INITIAL (decl) = error_mark_node;
1020      else
1021	DECL_EXTERNAL (decl) = 0;
1022      assemble_alias (decl, id);
1023    }
1024  else
1025    {
1026      warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
1027      *no_add_attrs = true;
1028    }
1029
1030  return NULL_TREE;
1031}
1032
1033/* Handle a "no_instrument_function" attribute; arguments as in
1034   struct attribute_spec.handler.  */
1035
1036static tree
1037handle_no_instrument_function_attribute (node, name, args, flags, no_add_attrs)
1038     tree *node;
1039     tree name;
1040     tree args ATTRIBUTE_UNUSED;
1041     int flags ATTRIBUTE_UNUSED;
1042     bool *no_add_attrs;
1043{
1044  tree decl = *node;
1045
1046  if (TREE_CODE (decl) != FUNCTION_DECL)
1047    {
1048      error_with_decl (decl,
1049		       "`%s' attribute applies only to functions",
1050		       IDENTIFIER_POINTER (name));
1051      *no_add_attrs = true;
1052    }
1053  else if (DECL_INITIAL (decl))
1054    {
1055      error_with_decl (decl,
1056		       "can't set `%s' attribute after definition",
1057		       IDENTIFIER_POINTER (name));
1058      *no_add_attrs = true;
1059    }
1060  else
1061    DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
1062
1063  return NULL_TREE;
1064}
1065
1066/* Handle a "malloc" attribute; arguments as in
1067   struct attribute_spec.handler.  */
1068
1069static tree
1070handle_malloc_attribute (node, name, args, flags, no_add_attrs)
1071     tree *node;
1072     tree name;
1073     tree args ATTRIBUTE_UNUSED;
1074     int flags ATTRIBUTE_UNUSED;
1075     bool *no_add_attrs;
1076{
1077  if (TREE_CODE (*node) == FUNCTION_DECL)
1078    DECL_IS_MALLOC (*node) = 1;
1079  /* ??? TODO: Support types.  */
1080  else
1081    {
1082      warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
1083      *no_add_attrs = true;
1084    }
1085
1086  return NULL_TREE;
1087}
1088
1089/* Handle a "no_limit_stack" attribute; arguments as in
1090   struct attribute_spec.handler.  */
1091
1092static tree
1093handle_no_limit_stack_attribute (node, name, args, flags, no_add_attrs)
1094     tree *node;
1095     tree name;
1096     tree args ATTRIBUTE_UNUSED;
1097     int flags ATTRIBUTE_UNUSED;
1098     bool *no_add_attrs;
1099{
1100  tree decl = *node;
1101
1102  if (TREE_CODE (decl) != FUNCTION_DECL)
1103    {
1104      error_with_decl (decl,
1105		       "`%s' attribute applies only to functions",
1106		       IDENTIFIER_POINTER (name));
1107      *no_add_attrs = true;
1108    }
1109  else if (DECL_INITIAL (decl))
1110    {
1111      error_with_decl (decl,
1112		       "can't set `%s' attribute after definition",
1113		       IDENTIFIER_POINTER (name));
1114      *no_add_attrs = true;
1115    }
1116  else
1117    DECL_NO_LIMIT_STACK (decl) = 1;
1118
1119  return NULL_TREE;
1120}
1121
1122/* Handle a "pure" attribute; arguments as in
1123   struct attribute_spec.handler.  */
1124
1125static tree
1126handle_pure_attribute (node, name, args, flags, no_add_attrs)
1127     tree *node;
1128     tree name;
1129     tree args ATTRIBUTE_UNUSED;
1130     int flags ATTRIBUTE_UNUSED;
1131     bool *no_add_attrs;
1132{
1133  if (TREE_CODE (*node) == FUNCTION_DECL)
1134    DECL_IS_PURE (*node) = 1;
1135  /* ??? TODO: Support types.  */
1136  else
1137    {
1138      warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
1139      *no_add_attrs = true;
1140    }
1141
1142  return NULL_TREE;
1143}
1144
1145/* Handle a "deprecated" attribute; arguments as in
1146   struct attribute_spec.handler.  */
1147
1148static tree
1149handle_deprecated_attribute (node, name, args, flags, no_add_attrs)
1150     tree *node;
1151     tree name;
1152     tree args ATTRIBUTE_UNUSED;
1153     int flags;
1154     bool *no_add_attrs;
1155{
1156  tree type = NULL_TREE;
1157  int warn = 0;
1158  const char *what = NULL;
1159
1160  if (DECL_P (*node))
1161    {
1162      tree decl = *node;
1163      type = TREE_TYPE (decl);
1164
1165      if (TREE_CODE (decl) == TYPE_DECL
1166	  || TREE_CODE (decl) == PARM_DECL
1167	  || TREE_CODE (decl) == VAR_DECL
1168	  || TREE_CODE (decl) == FUNCTION_DECL
1169	  || TREE_CODE (decl) == FIELD_DECL)
1170	TREE_DEPRECATED (decl) = 1;
1171      else
1172	warn = 1;
1173    }
1174  else if (TYPE_P (*node))
1175    {
1176      if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
1177	*node = build_type_copy (*node);
1178      TREE_DEPRECATED (*node) = 1;
1179      type = *node;
1180    }
1181  else
1182    warn = 1;
1183
1184  if (warn)
1185    {
1186      *no_add_attrs = true;
1187      if (type && TYPE_NAME (type))
1188	{
1189	  if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
1190	    what = IDENTIFIER_POINTER (TYPE_NAME (*node));
1191	  else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
1192		   && DECL_NAME (TYPE_NAME (type)))
1193	    what = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
1194	}
1195      if (what)
1196	warning ("`%s' attribute ignored for `%s'",
1197		  IDENTIFIER_POINTER (name), what);
1198      else
1199	warning ("`%s' attribute ignored",
1200		      IDENTIFIER_POINTER (name));
1201    }
1202
1203  return NULL_TREE;
1204}
1205
1206/* Handle a "vector_size" attribute; arguments as in
1207   struct attribute_spec.handler.  */
1208
1209static tree
1210handle_vector_size_attribute (node, name, args, flags, no_add_attrs)
1211     tree *node;
1212     tree name;
1213     tree args;
1214     int flags ATTRIBUTE_UNUSED;
1215     bool *no_add_attrs;
1216{
1217  unsigned HOST_WIDE_INT vecsize, nunits;
1218  enum machine_mode mode, orig_mode, new_mode;
1219  tree type = *node, new_type;
1220
1221  *no_add_attrs = true;
1222
1223  if (! host_integerp (TREE_VALUE (args), 1))
1224    {
1225      warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
1226      return NULL_TREE;
1227    }
1228
1229  /* Get the vector size (in bytes).  */
1230  vecsize = tree_low_cst (TREE_VALUE (args), 1);
1231
1232  /* We need to provide for vector pointers, vector arrays, and
1233     functions returning vectors.  For example:
1234
1235       __attribute__((vector_size(16))) short *foo;
1236
1237     In this case, the mode is SI, but the type being modified is
1238     HI, so we need to look further.  */
1239
1240  while (POINTER_TYPE_P (type)
1241	 || TREE_CODE (type) == FUNCTION_TYPE
1242	 || TREE_CODE (type) == ARRAY_TYPE)
1243    type = TREE_TYPE (type);
1244
1245  /* Get the mode of the type being modified.  */
1246  orig_mode = TYPE_MODE (type);
1247
1248  if (TREE_CODE (type) == RECORD_TYPE
1249      || (GET_MODE_CLASS (orig_mode) != MODE_FLOAT
1250	  && GET_MODE_CLASS (orig_mode) != MODE_INT)
1251      || ! host_integerp (TYPE_SIZE_UNIT (type), 1))
1252    {
1253      error ("invalid vector type for attribute `%s'",
1254	     IDENTIFIER_POINTER (name));
1255      return NULL_TREE;
1256    }
1257
1258  /* Calculate how many units fit in the vector.  */
1259  nunits = vecsize / tree_low_cst (TYPE_SIZE_UNIT (type), 1);
1260
1261  /* Find a suitably sized vector.  */
1262  new_mode = VOIDmode;
1263  for (mode = GET_CLASS_NARROWEST_MODE (GET_MODE_CLASS (orig_mode) == MODE_INT
1264					? MODE_VECTOR_INT
1265					: MODE_VECTOR_FLOAT);
1266       mode != VOIDmode;
1267       mode = GET_MODE_WIDER_MODE (mode))
1268    if (vecsize == GET_MODE_SIZE (mode)
1269	&& nunits == (unsigned HOST_WIDE_INT) GET_MODE_NUNITS (mode))
1270      {
1271	new_mode = mode;
1272	break;
1273      }
1274
1275  if (new_mode == VOIDmode)
1276    error ("no vector mode with the size and type specified could be found");
1277  else
1278    {
1279      new_type = type_for_mode (new_mode, TREE_UNSIGNED (type));
1280      if (!new_type)
1281	error ("no vector mode with the size and type specified could be found");
1282      else
1283	/* Build back pointers if needed.  */
1284	*node = vector_size_helper (*node, new_type);
1285    }
1286
1287  return NULL_TREE;
1288}
1289
1290/* HACK.  GROSS.  This is absolutely disgusting.  I wish there was a
1291   better way.
1292
1293   If we requested a pointer to a vector, build up the pointers that
1294   we stripped off while looking for the inner type.  Similarly for
1295   return values from functions.
1296
1297   The argument "type" is the top of the chain, and "bottom" is the
1298   new type which we will point to.  */
1299
1300static tree
1301vector_size_helper (type, bottom)
1302     tree type, bottom;
1303{
1304  tree inner, outer;
1305
1306  if (POINTER_TYPE_P (type))
1307    {
1308      inner = vector_size_helper (TREE_TYPE (type), bottom);
1309      outer = build_pointer_type (inner);
1310    }
1311  else if (TREE_CODE (type) == ARRAY_TYPE)
1312    {
1313      inner = vector_size_helper (TREE_TYPE (type), bottom);
1314      outer = build_array_type (inner, TYPE_VALUES (type));
1315    }
1316  else if (TREE_CODE (type) == FUNCTION_TYPE)
1317    {
1318      inner = vector_size_helper (TREE_TYPE (type), bottom);
1319      outer = build_function_type (inner, TYPE_VALUES (type));
1320    }
1321  else
1322    return bottom;
1323
1324  TREE_READONLY (outer) = TREE_READONLY (type);
1325  TREE_THIS_VOLATILE (outer) = TREE_THIS_VOLATILE (type);
1326
1327  return outer;
1328}
1329
1330/* Split SPECS_ATTRS, a list of declspecs and prefix attributes, into two
1331   lists.  SPECS_ATTRS may also be just a typespec (eg: RECORD_TYPE).
1332
1333   The head of the declspec list is stored in DECLSPECS.
1334   The head of the attribute list is stored in PREFIX_ATTRIBUTES.
1335
1336   Note that attributes in SPECS_ATTRS are stored in the TREE_PURPOSE of
1337   the list elements.  We drop the containing TREE_LIST nodes and link the
1338   resulting attributes together the way decl_attributes expects them.  */
1339
1340void
1341split_specs_attrs (specs_attrs, declspecs, prefix_attributes)
1342     tree specs_attrs;
1343     tree *declspecs, *prefix_attributes;
1344{
1345  tree t, s, a, next, specs, attrs;
1346
1347  /* This can happen after an __extension__ in pedantic mode.  */
1348  if (specs_attrs != NULL_TREE
1349      && TREE_CODE (specs_attrs) == INTEGER_CST)
1350    {
1351      *declspecs = NULL_TREE;
1352      *prefix_attributes = NULL_TREE;
1353      return;
1354    }
1355
1356  /* This can happen in c++ (eg: decl: typespec initdecls ';').  */
1357  if (specs_attrs != NULL_TREE
1358      && TREE_CODE (specs_attrs) != TREE_LIST)
1359    {
1360      *declspecs = specs_attrs;
1361      *prefix_attributes = NULL_TREE;
1362      return;
1363    }
1364
1365  /* Remember to keep the lists in the same order, element-wise.  */
1366
1367  specs = s = NULL_TREE;
1368  attrs = a = NULL_TREE;
1369  for (t = specs_attrs; t; t = next)
1370    {
1371      next = TREE_CHAIN (t);
1372      /* Declspecs have a non-NULL TREE_VALUE.  */
1373      if (TREE_VALUE (t) != NULL_TREE)
1374	{
1375	  if (specs == NULL_TREE)
1376	    specs = s = t;
1377	  else
1378	    {
1379	      TREE_CHAIN (s) = t;
1380	      s = t;
1381	    }
1382	}
1383      /* The TREE_PURPOSE may also be empty in the case of
1384	 __attribute__(()).  */
1385      else if (TREE_PURPOSE (t) != NULL_TREE)
1386	{
1387	  if (attrs == NULL_TREE)
1388	    attrs = a = TREE_PURPOSE (t);
1389	  else
1390	    {
1391	      TREE_CHAIN (a) = TREE_PURPOSE (t);
1392	      a = TREE_PURPOSE (t);
1393	    }
1394	  /* More attrs can be linked here, move A to the end.  */
1395	  while (TREE_CHAIN (a) != NULL_TREE)
1396	    a = TREE_CHAIN (a);
1397	}
1398    }
1399
1400  /* Terminate the lists.  */
1401  if (s != NULL_TREE)
1402    TREE_CHAIN (s) = NULL_TREE;
1403  if (a != NULL_TREE)
1404    TREE_CHAIN (a) = NULL_TREE;
1405
1406  /* All done.  */
1407  *declspecs = specs;
1408  *prefix_attributes = attrs;
1409}
1410
1411/* Strip attributes from SPECS_ATTRS, a list of declspecs and attributes.
1412   This function is used by the parser when a rule will accept attributes
1413   in a particular position, but we don't want to support that just yet.
1414
1415   A warning is issued for every ignored attribute.  */
1416
1417tree
1418strip_attrs (specs_attrs)
1419     tree specs_attrs;
1420{
1421  tree specs, attrs;
1422
1423  split_specs_attrs (specs_attrs, &specs, &attrs);
1424
1425  while (attrs)
1426    {
1427      warning ("`%s' attribute ignored",
1428	       IDENTIFIER_POINTER (TREE_PURPOSE (attrs)));
1429      attrs = TREE_CHAIN (attrs);
1430    }
1431
1432  return specs;
1433}
1434