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