OSDN Git Service

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