attribs.c revision 96489
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      assemble_alias (decl, id);
1054    }
1055  else
1056    {
1057      warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
1058      *no_add_attrs = true;
1059    }
1060
1061  return NULL_TREE;
1062}
1063
1064/* Handle a "no_instrument_function" attribute; arguments as in
1065   struct attribute_spec.handler.  */
1066
1067static tree
1068handle_no_instrument_function_attribute (node, name, args, flags, no_add_attrs)
1069     tree *node;
1070     tree name;
1071     tree args ATTRIBUTE_UNUSED;
1072     int flags ATTRIBUTE_UNUSED;
1073     bool *no_add_attrs;
1074{
1075  tree decl = *node;
1076
1077  if (TREE_CODE (decl) != FUNCTION_DECL)
1078    {
1079      error_with_decl (decl,
1080		       "`%s' attribute applies only to functions",
1081		       IDENTIFIER_POINTER (name));
1082      *no_add_attrs = true;
1083    }
1084  else if (DECL_INITIAL (decl))
1085    {
1086      error_with_decl (decl,
1087		       "can't set `%s' attribute after definition",
1088		       IDENTIFIER_POINTER (name));
1089      *no_add_attrs = true;
1090    }
1091  else
1092    DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
1093
1094  return NULL_TREE;
1095}
1096
1097/* Handle a "malloc" attribute; arguments as in
1098   struct attribute_spec.handler.  */
1099
1100static tree
1101handle_malloc_attribute (node, name, args, flags, no_add_attrs)
1102     tree *node;
1103     tree name;
1104     tree args ATTRIBUTE_UNUSED;
1105     int flags ATTRIBUTE_UNUSED;
1106     bool *no_add_attrs;
1107{
1108  if (TREE_CODE (*node) == FUNCTION_DECL)
1109    DECL_IS_MALLOC (*node) = 1;
1110  /* ??? TODO: Support types.  */
1111  else
1112    {
1113      warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
1114      *no_add_attrs = true;
1115    }
1116
1117  return NULL_TREE;
1118}
1119
1120/* Handle a "no_limit_stack" attribute; arguments as in
1121   struct attribute_spec.handler.  */
1122
1123static tree
1124handle_no_limit_stack_attribute (node, name, args, flags, no_add_attrs)
1125     tree *node;
1126     tree name;
1127     tree args ATTRIBUTE_UNUSED;
1128     int flags ATTRIBUTE_UNUSED;
1129     bool *no_add_attrs;
1130{
1131  tree decl = *node;
1132
1133  if (TREE_CODE (decl) != FUNCTION_DECL)
1134    {
1135      error_with_decl (decl,
1136		       "`%s' attribute applies only to functions",
1137		       IDENTIFIER_POINTER (name));
1138      *no_add_attrs = true;
1139    }
1140  else if (DECL_INITIAL (decl))
1141    {
1142      error_with_decl (decl,
1143		       "can't set `%s' attribute after definition",
1144		       IDENTIFIER_POINTER (name));
1145      *no_add_attrs = true;
1146    }
1147  else
1148    DECL_NO_LIMIT_STACK (decl) = 1;
1149
1150  return NULL_TREE;
1151}
1152
1153/* Handle a "pure" attribute; arguments as in
1154   struct attribute_spec.handler.  */
1155
1156static tree
1157handle_pure_attribute (node, name, args, flags, no_add_attrs)
1158     tree *node;
1159     tree name;
1160     tree args ATTRIBUTE_UNUSED;
1161     int flags ATTRIBUTE_UNUSED;
1162     bool *no_add_attrs;
1163{
1164  if (TREE_CODE (*node) == FUNCTION_DECL)
1165    DECL_IS_PURE (*node) = 1;
1166  /* ??? TODO: Support types.  */
1167  else
1168    {
1169      warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
1170      *no_add_attrs = true;
1171    }
1172
1173  return NULL_TREE;
1174}
1175
1176/* Handle a "deprecated" attribute; arguments as in
1177   struct attribute_spec.handler.  */
1178
1179static tree
1180handle_deprecated_attribute (node, name, args, flags, no_add_attrs)
1181     tree *node;
1182     tree name;
1183     tree args ATTRIBUTE_UNUSED;
1184     int flags;
1185     bool *no_add_attrs;
1186{
1187  tree type = NULL_TREE;
1188  int warn = 0;
1189  const char *what = NULL;
1190
1191  if (DECL_P (*node))
1192    {
1193      tree decl = *node;
1194      type = TREE_TYPE (decl);
1195
1196      if (TREE_CODE (decl) == TYPE_DECL
1197	  || TREE_CODE (decl) == PARM_DECL
1198	  || TREE_CODE (decl) == VAR_DECL
1199	  || TREE_CODE (decl) == FUNCTION_DECL
1200	  || TREE_CODE (decl) == FIELD_DECL)
1201	TREE_DEPRECATED (decl) = 1;
1202      else
1203	warn = 1;
1204    }
1205  else if (TYPE_P (*node))
1206    {
1207      if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
1208	*node = build_type_copy (*node);
1209      TREE_DEPRECATED (*node) = 1;
1210      type = *node;
1211    }
1212  else
1213    warn = 1;
1214
1215  if (warn)
1216    {
1217      *no_add_attrs = true;
1218      if (type && TYPE_NAME (type))
1219	{
1220	  if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
1221	    what = IDENTIFIER_POINTER (TYPE_NAME (*node));
1222	  else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
1223		   && DECL_NAME (TYPE_NAME (type)))
1224	    what = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
1225	}
1226      if (what)
1227	warning ("`%s' attribute ignored for `%s'",
1228		  IDENTIFIER_POINTER (name), what);
1229      else
1230	warning ("`%s' attribute ignored",
1231		      IDENTIFIER_POINTER (name));
1232    }
1233
1234  return NULL_TREE;
1235}
1236
1237/* Handle a "vector_size" attribute; arguments as in
1238   struct attribute_spec.handler.  */
1239
1240static tree
1241handle_vector_size_attribute (node, name, args, flags, no_add_attrs)
1242     tree *node;
1243     tree name;
1244     tree args;
1245     int flags ATTRIBUTE_UNUSED;
1246     bool *no_add_attrs;
1247{
1248  unsigned HOST_WIDE_INT vecsize, nunits;
1249  enum machine_mode mode, orig_mode, new_mode;
1250  tree type = *node, new_type;
1251
1252  *no_add_attrs = true;
1253
1254  if (! host_integerp (TREE_VALUE (args), 1))
1255    {
1256      warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
1257      return NULL_TREE;
1258    }
1259
1260  /* Get the vector size (in bytes).  */
1261  vecsize = tree_low_cst (TREE_VALUE (args), 1);
1262
1263  /* We need to provide for vector pointers, vector arrays, and
1264     functions returning vectors.  For example:
1265
1266       __attribute__((vector_size(16))) short *foo;
1267
1268     In this case, the mode is SI, but the type being modified is
1269     HI, so we need to look further.  */
1270
1271  while (POINTER_TYPE_P (type)
1272	 || TREE_CODE (type) == FUNCTION_TYPE
1273	 || TREE_CODE (type) == ARRAY_TYPE)
1274    type = TREE_TYPE (type);
1275
1276  /* Get the mode of the type being modified.  */
1277  orig_mode = TYPE_MODE (type);
1278
1279  if (TREE_CODE (type) == RECORD_TYPE
1280      || (GET_MODE_CLASS (orig_mode) != MODE_FLOAT
1281	  && GET_MODE_CLASS (orig_mode) != MODE_INT)
1282      || ! host_integerp (TYPE_SIZE_UNIT (type), 1))
1283    {
1284      error ("invalid vector type for attribute `%s'",
1285	     IDENTIFIER_POINTER (name));
1286      return NULL_TREE;
1287    }
1288
1289  /* Calculate how many units fit in the vector.  */
1290  nunits = vecsize / tree_low_cst (TYPE_SIZE_UNIT (type), 1);
1291
1292  /* Find a suitably sized vector.  */
1293  new_mode = VOIDmode;
1294  for (mode = GET_CLASS_NARROWEST_MODE (GET_MODE_CLASS (orig_mode) == MODE_INT
1295					? MODE_VECTOR_INT
1296					: MODE_VECTOR_FLOAT);
1297       mode != VOIDmode;
1298       mode = GET_MODE_WIDER_MODE (mode))
1299    if (vecsize == GET_MODE_SIZE (mode)
1300	&& nunits == (unsigned HOST_WIDE_INT) GET_MODE_NUNITS (mode))
1301      {
1302	new_mode = mode;
1303	break;
1304      }
1305
1306  if (new_mode == VOIDmode)
1307    error ("no vector mode with the size and type specified could be found");
1308  else
1309    {
1310      new_type = type_for_mode (new_mode, TREE_UNSIGNED (type));
1311      if (!new_type)
1312	error ("no vector mode with the size and type specified could be found");
1313      else
1314	/* Build back pointers if needed.  */
1315	*node = vector_size_helper (*node, new_type);
1316    }
1317
1318  return NULL_TREE;
1319}
1320
1321/* HACK.  GROSS.  This is absolutely disgusting.  I wish there was a
1322   better way.
1323
1324   If we requested a pointer to a vector, build up the pointers that
1325   we stripped off while looking for the inner type.  Similarly for
1326   return values from functions.
1327
1328   The argument "type" is the top of the chain, and "bottom" is the
1329   new type which we will point to.  */
1330
1331static tree
1332vector_size_helper (type, bottom)
1333     tree type, bottom;
1334{
1335  tree inner, outer;
1336
1337  if (POINTER_TYPE_P (type))
1338    {
1339      inner = vector_size_helper (TREE_TYPE (type), bottom);
1340      outer = build_pointer_type (inner);
1341    }
1342  else if (TREE_CODE (type) == ARRAY_TYPE)
1343    {
1344      inner = vector_size_helper (TREE_TYPE (type), bottom);
1345      outer = build_array_type (inner, TYPE_VALUES (type));
1346    }
1347  else if (TREE_CODE (type) == FUNCTION_TYPE)
1348    {
1349      inner = vector_size_helper (TREE_TYPE (type), bottom);
1350      outer = build_function_type (inner, TYPE_VALUES (type));
1351    }
1352  else
1353    return bottom;
1354
1355  TREE_READONLY (outer) = TREE_READONLY (type);
1356  TREE_THIS_VOLATILE (outer) = TREE_THIS_VOLATILE (type);
1357
1358  return outer;
1359}
1360
1361/* Split SPECS_ATTRS, a list of declspecs and prefix attributes, into two
1362   lists.  SPECS_ATTRS may also be just a typespec (eg: RECORD_TYPE).
1363
1364   The head of the declspec list is stored in DECLSPECS.
1365   The head of the attribute list is stored in PREFIX_ATTRIBUTES.
1366
1367   Note that attributes in SPECS_ATTRS are stored in the TREE_PURPOSE of
1368   the list elements.  We drop the containing TREE_LIST nodes and link the
1369   resulting attributes together the way decl_attributes expects them.  */
1370
1371void
1372split_specs_attrs (specs_attrs, declspecs, prefix_attributes)
1373     tree specs_attrs;
1374     tree *declspecs, *prefix_attributes;
1375{
1376  tree t, s, a, next, specs, attrs;
1377
1378  /* This can happen after an __extension__ in pedantic mode.  */
1379  if (specs_attrs != NULL_TREE
1380      && TREE_CODE (specs_attrs) == INTEGER_CST)
1381    {
1382      *declspecs = NULL_TREE;
1383      *prefix_attributes = NULL_TREE;
1384      return;
1385    }
1386
1387  /* This can happen in c++ (eg: decl: typespec initdecls ';').  */
1388  if (specs_attrs != NULL_TREE
1389      && TREE_CODE (specs_attrs) != TREE_LIST)
1390    {
1391      *declspecs = specs_attrs;
1392      *prefix_attributes = NULL_TREE;
1393      return;
1394    }
1395
1396  /* Remember to keep the lists in the same order, element-wise.  */
1397
1398  specs = s = NULL_TREE;
1399  attrs = a = NULL_TREE;
1400  for (t = specs_attrs; t; t = next)
1401    {
1402      next = TREE_CHAIN (t);
1403      /* Declspecs have a non-NULL TREE_VALUE.  */
1404      if (TREE_VALUE (t) != NULL_TREE)
1405	{
1406	  if (specs == NULL_TREE)
1407	    specs = s = t;
1408	  else
1409	    {
1410	      TREE_CHAIN (s) = t;
1411	      s = t;
1412	    }
1413	}
1414      /* The TREE_PURPOSE may also be empty in the case of
1415	 __attribute__(()).  */
1416      else if (TREE_PURPOSE (t) != NULL_TREE)
1417	{
1418	  if (attrs == NULL_TREE)
1419	    attrs = a = TREE_PURPOSE (t);
1420	  else
1421	    {
1422	      TREE_CHAIN (a) = TREE_PURPOSE (t);
1423	      a = TREE_PURPOSE (t);
1424	    }
1425	  /* More attrs can be linked here, move A to the end.  */
1426	  while (TREE_CHAIN (a) != NULL_TREE)
1427	    a = TREE_CHAIN (a);
1428	}
1429    }
1430
1431  /* Terminate the lists.  */
1432  if (s != NULL_TREE)
1433    TREE_CHAIN (s) = NULL_TREE;
1434  if (a != NULL_TREE)
1435    TREE_CHAIN (a) = NULL_TREE;
1436
1437  /* All done.  */
1438  *declspecs = specs;
1439  *prefix_attributes = attrs;
1440}
1441
1442/* Strip attributes from SPECS_ATTRS, a list of declspecs and attributes.
1443   This function is used by the parser when a rule will accept attributes
1444   in a particular position, but we don't want to support that just yet.
1445
1446   A warning is issued for every ignored attribute.  */
1447
1448tree
1449strip_attrs (specs_attrs)
1450     tree specs_attrs;
1451{
1452  tree specs, attrs;
1453
1454  split_specs_attrs (specs_attrs, &specs, &attrs);
1455
1456  while (attrs)
1457    {
1458      warning ("`%s' attribute ignored",
1459	       IDENTIFIER_POINTER (TREE_PURPOSE (attrs)));
1460      attrs = TREE_CHAIN (attrs);
1461    }
1462
1463  return specs;
1464}
1465
1466