OSDN Git Service

d046a6242ba47578a6ad011f7698fd332090dd88
[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_always_inline_attribute PARAMS ((tree *, tree, tree, int,
55                                                     bool *));
56 static tree handle_used_attribute       PARAMS ((tree *, tree, tree, int,
57                                                  bool *));
58 static tree handle_unused_attribute     PARAMS ((tree *, tree, tree, int,
59                                                  bool *));
60 static tree handle_const_attribute      PARAMS ((tree *, tree, tree, int,
61                                                  bool *));
62 static tree handle_transparent_union_attribute PARAMS ((tree *, tree, tree,
63                                                         int, bool *));
64 static tree handle_constructor_attribute PARAMS ((tree *, tree, tree, int,
65                                                   bool *));
66 static tree handle_destructor_attribute PARAMS ((tree *, tree, tree, int,
67                                                  bool *));
68 static tree handle_mode_attribute       PARAMS ((tree *, tree, tree, int,
69                                                  bool *));
70 static tree handle_section_attribute    PARAMS ((tree *, tree, tree, int,
71                                                  bool *));
72 static tree handle_aligned_attribute    PARAMS ((tree *, tree, tree, int,
73                                                  bool *));
74 static tree handle_weak_attribute       PARAMS ((tree *, tree, tree, int,
75                                                  bool *));
76 static tree handle_alias_attribute      PARAMS ((tree *, tree, tree, int,
77                                                  bool *));
78 static tree handle_no_instrument_function_attribute PARAMS ((tree *, tree,
79                                                              tree, int,
80                                                              bool *));
81 static tree handle_malloc_attribute     PARAMS ((tree *, tree, tree, int,
82                                                  bool *));
83 static tree handle_no_limit_stack_attribute PARAMS ((tree *, tree, tree, int,
84                                                      bool *));
85 static tree handle_pure_attribute       PARAMS ((tree *, tree, tree, int,
86                                                  bool *));
87 static tree handle_deprecated_attribute PARAMS ((tree *, tree, tree, int,
88                                                  bool *));
89 static tree handle_vector_size_attribute PARAMS ((tree *, tree, tree, int,
90                                                   bool *));
91 static tree vector_size_helper PARAMS ((tree, tree));
92
93 /* Table of machine-independent attributes common to all C-like languages.  */
94 static 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.  */
155 static 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.  */
161 const struct attribute_spec *format_attribute_table = empty_attribute_table;
162
163 /* Table of machine-independent attributes for a particular language.  */
164 const struct attribute_spec *lang_attribute_table = empty_attribute_table;
165
166 /* Flag saying whether common language attributes are to be supported.  */
167 int lang_attribute_common = 1;
168
169 /* Initialize attribute tables, and make some sanity checks
170    if --enable-checking.  */
171
172 static void
173 init_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 \f
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
267 tree
268 decl_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
439 static tree
440 handle_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
478 static tree
479 handle_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
500 static tree
501 handle_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
522 static tree
523 handle_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
553 static tree
554 handle_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
575 static tree
576 handle_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
600 static tree
601 handle_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
623 static tree
624 handle_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
660 static tree
661 handle_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
691 static tree
692 handle_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
738 static tree
739 handle_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
768 static tree
769 handle_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
798 static tree
799 handle_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
859 static tree
860 handle_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
917 static tree
918 handle_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
1001 static tree
1002 handle_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
1017 static tree
1018 handle_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
1067 static tree
1068 handle_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
1100 static tree
1101 handle_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
1123 static tree
1124 handle_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
1156 static tree
1157 handle_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    
1179 static tree
1180 handle_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
1240 static tree
1241 handle_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       tree index, array, rt;
1311
1312       new_type = type_for_mode (new_mode, TREE_UNSIGNED (type));
1313
1314       if (!new_type)
1315         {
1316           error ("no vector mode with the size and type specified could be found");
1317           return NULL_TREE;
1318         }
1319
1320       new_type = build_type_copy (new_type);
1321
1322       /* Set the debug information here, because this is the only
1323          place where we know the underlying type for a vector made
1324          with vector_size.  For debugging purposes we pretend a vector
1325          is an array within a structure.  */
1326       index = build_int_2 (TYPE_VECTOR_SUBPARTS (new_type) - 1, 0);
1327       array = build_array_type (type, build_index_type (index));
1328       rt = make_node (RECORD_TYPE);
1329
1330       TYPE_FIELDS (rt) = build_decl (FIELD_DECL, get_identifier ("f"), array);
1331       DECL_CONTEXT (TYPE_FIELDS (rt)) = rt;
1332       layout_type (rt);
1333       TYPE_DEBUG_REPRESENTATION_TYPE (new_type) = rt;
1334
1335       /* Build back pointers if needed.  */
1336       *node = vector_size_helper (*node, new_type);
1337     }
1338     
1339   return NULL_TREE;
1340 }
1341
1342 /* HACK.  GROSS.  This is absolutely disgusting.  I wish there was a
1343    better way.
1344
1345    If we requested a pointer to a vector, build up the pointers that
1346    we stripped off while looking for the inner type.  Similarly for
1347    return values from functions.
1348
1349    The argument "type" is the top of the chain, and "bottom" is the
1350    new type which we will point to.  */
1351
1352 static tree
1353 vector_size_helper (type, bottom)
1354      tree type, bottom;
1355 {
1356   tree inner, outer;
1357
1358   if (POINTER_TYPE_P (type))
1359     {
1360       inner = vector_size_helper (TREE_TYPE (type), bottom);
1361       outer = build_pointer_type (inner);
1362     }
1363   else if (TREE_CODE (type) == ARRAY_TYPE)
1364     {
1365       inner = vector_size_helper (TREE_TYPE (type), bottom);
1366       outer = build_array_type (inner, TYPE_VALUES (type));
1367     }
1368   else if (TREE_CODE (type) == FUNCTION_TYPE)
1369     {
1370       inner = vector_size_helper (TREE_TYPE (type), bottom);
1371       outer = build_function_type (inner, TYPE_VALUES (type));
1372     }
1373   else
1374     return bottom;
1375   
1376   TREE_READONLY (outer) = TREE_READONLY (type);
1377   TREE_THIS_VOLATILE (outer) = TREE_THIS_VOLATILE (type);
1378
1379   return outer;
1380 }
1381
1382 /* Split SPECS_ATTRS, a list of declspecs and prefix attributes, into two
1383    lists.  SPECS_ATTRS may also be just a typespec (eg: RECORD_TYPE).
1384
1385    The head of the declspec list is stored in DECLSPECS.
1386    The head of the attribute list is stored in PREFIX_ATTRIBUTES.
1387
1388    Note that attributes in SPECS_ATTRS are stored in the TREE_PURPOSE of
1389    the list elements.  We drop the containing TREE_LIST nodes and link the
1390    resulting attributes together the way decl_attributes expects them.  */
1391
1392 void
1393 split_specs_attrs (specs_attrs, declspecs, prefix_attributes)
1394      tree specs_attrs;
1395      tree *declspecs, *prefix_attributes;
1396 {
1397   tree t, s, a, next, specs, attrs;
1398
1399   /* This can happen after an __extension__ in pedantic mode.  */
1400   if (specs_attrs != NULL_TREE 
1401       && TREE_CODE (specs_attrs) == INTEGER_CST)
1402     {
1403       *declspecs = NULL_TREE;
1404       *prefix_attributes = NULL_TREE;
1405       return;
1406     }
1407
1408   /* This can happen in c++ (eg: decl: typespec initdecls ';').  */
1409   if (specs_attrs != NULL_TREE
1410       && TREE_CODE (specs_attrs) != TREE_LIST)
1411     {
1412       *declspecs = specs_attrs;
1413       *prefix_attributes = NULL_TREE;
1414       return;
1415     }
1416
1417   /* Remember to keep the lists in the same order, element-wise.  */
1418
1419   specs = s = NULL_TREE;
1420   attrs = a = NULL_TREE;
1421   for (t = specs_attrs; t; t = next)
1422     {
1423       next = TREE_CHAIN (t);
1424       /* Declspecs have a non-NULL TREE_VALUE.  */
1425       if (TREE_VALUE (t) != NULL_TREE)
1426         {
1427           if (specs == NULL_TREE)
1428             specs = s = t;
1429           else
1430             {
1431               TREE_CHAIN (s) = t;
1432               s = t;
1433             }
1434         }
1435       /* The TREE_PURPOSE may also be empty in the case of
1436          __attribute__(()).  */
1437       else if (TREE_PURPOSE (t) != NULL_TREE)
1438         {
1439           if (attrs == NULL_TREE)
1440             attrs = a = TREE_PURPOSE (t);
1441           else
1442             {
1443               TREE_CHAIN (a) = TREE_PURPOSE (t);
1444               a = TREE_PURPOSE (t);
1445             }
1446           /* More attrs can be linked here, move A to the end.  */
1447           while (TREE_CHAIN (a) != NULL_TREE)
1448             a = TREE_CHAIN (a);
1449         }
1450     }
1451
1452   /* Terminate the lists.  */
1453   if (s != NULL_TREE)
1454     TREE_CHAIN (s) = NULL_TREE;
1455   if (a != NULL_TREE)
1456     TREE_CHAIN (a) = NULL_TREE;
1457
1458   /* All done.  */
1459   *declspecs = specs;
1460   *prefix_attributes = attrs;
1461 }
1462
1463 /* Strip attributes from SPECS_ATTRS, a list of declspecs and attributes.
1464    This function is used by the parser when a rule will accept attributes
1465    in a particular position, but we don't want to support that just yet.
1466
1467    A warning is issued for every ignored attribute.  */
1468
1469 tree
1470 strip_attrs (specs_attrs)
1471      tree specs_attrs;
1472 {
1473   tree specs, attrs;
1474
1475   split_specs_attrs (specs_attrs, &specs, &attrs);
1476
1477   while (attrs)
1478     {
1479       warning ("`%s' attribute ignored",
1480                IDENTIFIER_POINTER (TREE_PURPOSE (attrs)));
1481       attrs = TREE_CHAIN (attrs);
1482     }
1483
1484   return specs;
1485 }
1486