OSDN Git Service

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