OSDN Git Service

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