OSDN Git Service

* attribs.c (decl_attributes): Clear ATTR_FLAG_TYPE_IN_PLACE
[pf3gnuchains/gcc-fork.git] / gcc / attribs.c
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
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING.  If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-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
36 static void init_attributes             PARAMS ((void));
37
38 /* Table of the tables of attributes (common, format, language, machine)
39    searched.  */
40 static const struct attribute_spec *attribute_tables[4];
41
42 static bool attributes_initialized = false;
43
44 static tree handle_packed_attribute     PARAMS ((tree *, tree, tree, int,
45                                                  bool *));
46 static tree handle_nocommon_attribute   PARAMS ((tree *, tree, tree, int,
47                                                  bool *));
48 static tree handle_common_attribute     PARAMS ((tree *, tree, tree, int,
49                                                  bool *));
50 static tree handle_noreturn_attribute   PARAMS ((tree *, tree, tree, int,
51                                                  bool *));
52 static tree handle_noinline_attribute   PARAMS ((tree *, tree, tree, int,
53                                                  bool *));
54 static tree handle_used_attribute       PARAMS ((tree *, tree, tree, int,
55                                                  bool *));
56 static tree handle_unused_attribute     PARAMS ((tree *, tree, tree, int,
57                                                  bool *));
58 static tree handle_const_attribute      PARAMS ((tree *, tree, tree, int,
59                                                  bool *));
60 static tree handle_transparent_union_attribute PARAMS ((tree *, tree, tree,
61                                                         int, bool *));
62 static tree handle_constructor_attribute PARAMS ((tree *, tree, tree, int,
63                                                   bool *));
64 static tree handle_destructor_attribute PARAMS ((tree *, tree, tree, int,
65                                                  bool *));
66 static tree handle_mode_attribute       PARAMS ((tree *, tree, tree, int,
67                                                  bool *));
68 static tree handle_section_attribute    PARAMS ((tree *, tree, tree, int,
69                                                  bool *));
70 static tree handle_aligned_attribute    PARAMS ((tree *, tree, tree, int,
71                                                  bool *));
72 static tree handle_weak_attribute       PARAMS ((tree *, tree, tree, int,
73                                                  bool *));
74 static tree handle_alias_attribute      PARAMS ((tree *, tree, tree, int,
75                                                  bool *));
76 static tree handle_no_instrument_function_attribute PARAMS ((tree *, tree,
77                                                              tree, int,
78                                                              bool *));
79 static tree handle_malloc_attribute     PARAMS ((tree *, tree, tree, int,
80                                                  bool *));
81 static tree handle_no_limit_stack_attribute PARAMS ((tree *, tree, tree, int,
82                                                      bool *));
83 static tree handle_pure_attribute       PARAMS ((tree *, tree, tree, int,
84                                                  bool *));
85 static tree handle_deprecated_attribute PARAMS ((tree *, tree, tree, int,
86                                                  bool *));
87 static tree handle_vector_size_attribute PARAMS ((tree *, tree, tree, int,
88                                                   bool *));
89 static tree vector_size_helper PARAMS ((tree, tree));
90
91 /* Table of machine-independent attributes common to all C-like languages.  */
92 static 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.  */
151 static 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.  */
157 const struct attribute_spec *format_attribute_table = empty_attribute_table;
158
159 /* Table of machine-independent attributes for a particular language.  */
160 const struct attribute_spec *lang_attribute_table = empty_attribute_table;
161
162 /* Flag saying whether common language attributes are to be supported.  */
163 int lang_attribute_common = 1;
164
165 /* Initialize attribute tables, and make some sanity checks
166    if --enable-checking.  */
167
168 static void
169 init_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 \f
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
263 tree
264 decl_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
433 static tree
434 handle_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
472 static tree
473 handle_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
494 static tree
495 handle_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
516 static tree
517 handle_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
547 static tree
548 handle_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
569 static tree
570 handle_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
592 static tree
593 handle_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
629 static tree
630 handle_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
660 static tree
661 handle_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
707 static tree
708 handle_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
737 static tree
738 handle_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
767 static tree
768 handle_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
828 static tree
829 handle_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
886 static tree
887 handle_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
970 static tree
971 handle_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
986 static tree
987 handle_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
1036 static tree
1037 handle_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
1069 static tree
1070 handle_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
1092 static tree
1093 handle_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
1125 static tree
1126 handle_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    
1148 static tree
1149 handle_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
1209 static tree
1210 handle_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
1300 static tree
1301 vector_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
1340 void
1341 split_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
1417 tree
1418 strip_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 }