]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/gcc/cp/tree.c
Import of unmodified (but trimmed) gcc-2.7.2. The bigger parts of the
[FreeBSD/FreeBSD.git] / contrib / gcc / cp / tree.c
1 /* Language-dependent node constructors for parse phase of GNU compiler.
2    Copyright (C) 1987, 88, 92, 93, 94, 1995 Free Software Foundation, Inc.
3    Hacked by Michael Tiemann (tiemann@cygnus.com)
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22 #include "config.h"
23 #include <stdio.h>
24 #include "obstack.h"
25 #include "tree.h"
26 #include "cp-tree.h"
27 #include "flags.h"
28 #include "rtl.h"
29
30 #define CEIL(x,y) (((x) + (y) - 1) / (y))
31
32 /* Return nonzero if REF is an lvalue valid for this language.
33    Lvalues can be assigned, unless they have TREE_READONLY.
34    Lvalues can have their address taken, unless they have DECL_REGISTER.  */
35
36 int
37 real_lvalue_p (ref)
38      tree ref;
39 {
40   if (! language_lvalue_valid (ref))
41     return 0;
42   
43   if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE)
44     return 1;
45
46   if (ref == current_class_decl && flag_this_is_variable <= 0)
47     return 0;
48
49   switch (TREE_CODE (ref))
50     {
51       /* preincrements and predecrements are valid lvals, provided
52          what they refer to are valid lvals. */
53     case PREINCREMENT_EXPR:
54     case PREDECREMENT_EXPR:
55     case COMPONENT_REF:
56     case SAVE_EXPR:
57       return real_lvalue_p (TREE_OPERAND (ref, 0));
58
59     case STRING_CST:
60       return 1;
61
62     case VAR_DECL:
63       if (TREE_READONLY (ref) && ! TREE_STATIC (ref)
64           && DECL_LANG_SPECIFIC (ref)
65           && DECL_IN_AGGR_P (ref))
66         return 0;
67     case INDIRECT_REF:
68     case ARRAY_REF:
69     case PARM_DECL:
70     case RESULT_DECL:
71     case ERROR_MARK:
72       if (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE
73           && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE)
74         return 1;
75       break;
76
77     case WITH_CLEANUP_EXPR:
78       return real_lvalue_p (TREE_OPERAND (ref, 0));
79
80       /* A currently unresolved scope ref.  */
81     case SCOPE_REF:
82       my_friendly_abort (103);
83     case OFFSET_REF:
84       if (TREE_CODE (TREE_OPERAND (ref, 1)) == FUNCTION_DECL)
85         return 1;
86       return real_lvalue_p (TREE_OPERAND (ref, 0))
87         && real_lvalue_p (TREE_OPERAND (ref, 1));
88       break;
89
90     case COND_EXPR:
91       return (real_lvalue_p (TREE_OPERAND (ref, 1))
92               && real_lvalue_p (TREE_OPERAND (ref, 2)));
93
94     case MODIFY_EXPR:
95       return 1;
96
97     case COMPOUND_EXPR:
98       return real_lvalue_p (TREE_OPERAND (ref, 1));
99
100     case MAX_EXPR:
101     case MIN_EXPR:
102       return (real_lvalue_p (TREE_OPERAND (ref, 0))
103               && real_lvalue_p (TREE_OPERAND (ref, 1)));
104     }
105
106   return 0;
107 }
108
109 int
110 lvalue_p (ref)
111      tree ref;
112 {
113   if (! language_lvalue_valid (ref))
114     return 0;
115   
116   if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE)
117     return 1;
118
119   if (ref == current_class_decl && flag_this_is_variable <= 0)
120     return 0;
121
122   switch (TREE_CODE (ref))
123     {
124       /* preincrements and predecrements are valid lvals, provided
125          what they refer to are valid lvals. */
126     case PREINCREMENT_EXPR:
127     case PREDECREMENT_EXPR:
128     case COMPONENT_REF:
129     case SAVE_EXPR:
130       return lvalue_p (TREE_OPERAND (ref, 0));
131
132     case STRING_CST:
133       return 1;
134
135     case VAR_DECL:
136       if (TREE_READONLY (ref) && ! TREE_STATIC (ref)
137           && DECL_LANG_SPECIFIC (ref)
138           && DECL_IN_AGGR_P (ref))
139         return 0;
140     case INDIRECT_REF:
141     case ARRAY_REF:
142     case PARM_DECL:
143     case RESULT_DECL:
144     case ERROR_MARK:
145       if (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE
146           && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE)
147         return 1;
148       break;
149
150     case WITH_CLEANUP_EXPR:
151       return lvalue_p (TREE_OPERAND (ref, 0));
152
153     case TARGET_EXPR:
154       return 1;
155
156     case CALL_EXPR:
157       if (IS_AGGR_TYPE (TREE_TYPE (ref)))
158         return 1;
159       break;
160
161       /* A currently unresolved scope ref.  */
162     case SCOPE_REF:
163       my_friendly_abort (103);
164     case OFFSET_REF:
165       if (TREE_CODE (TREE_OPERAND (ref, 1)) == FUNCTION_DECL)
166         return 1;
167       return lvalue_p (TREE_OPERAND (ref, 0))
168         && lvalue_p (TREE_OPERAND (ref, 1));
169       break;
170
171     case COND_EXPR:
172       return (lvalue_p (TREE_OPERAND (ref, 1))
173               && lvalue_p (TREE_OPERAND (ref, 2)));
174
175     case MODIFY_EXPR:
176       return 1;
177
178     case COMPOUND_EXPR:
179       return lvalue_p (TREE_OPERAND (ref, 1));
180
181     case MAX_EXPR:
182     case MIN_EXPR:
183       return (lvalue_p (TREE_OPERAND (ref, 0))
184               && lvalue_p (TREE_OPERAND (ref, 1)));
185     }
186
187   return 0;
188 }
189
190 /* Return nonzero if REF is an lvalue valid for this language;
191    otherwise, print an error message and return zero.  */
192
193 int
194 lvalue_or_else (ref, string)
195      tree ref;
196      char *string;
197 {
198   int win = lvalue_p (ref);
199   if (! win)
200     error ("non-lvalue in %s", string);
201   return win;
202 }
203
204 /* INIT is a CALL_EXPR which needs info about its target.
205    TYPE is the type that this initialization should appear to have.
206
207    Build an encapsulation of the initialization to perform
208    and return it so that it can be processed by language-independent
209    and language-specific expression expanders.
210
211    If WITH_CLEANUP_P is nonzero, we build a cleanup for this expression.
212    Otherwise, cleanups are not built here.  For example, when building
213    an initialization for a stack slot, since the called function handles
214    the cleanup, we would not want to do it here.  */
215 tree
216 build_cplus_new (type, init, with_cleanup_p)
217      tree type;
218      tree init;
219      int with_cleanup_p;
220 {
221   tree slot;
222   tree rval;
223
224   slot = build (VAR_DECL, type);
225   layout_decl (slot, 0);
226   rval = build (NEW_EXPR, type,
227                 TREE_OPERAND (init, 0), TREE_OPERAND (init, 1), slot);
228   TREE_SIDE_EFFECTS (rval) = 1;
229   TREE_ADDRESSABLE (rval) = 1;
230   rval = build (TARGET_EXPR, type, slot, rval, 0);
231   TREE_SIDE_EFFECTS (rval) = 1;
232   TREE_ADDRESSABLE (rval) = 1;
233
234 #if 0
235   if (with_cleanup_p && TYPE_NEEDS_DESTRUCTOR (type))
236     {
237       TREE_OPERAND (rval, 2) = error_mark_node;
238       rval = build (WITH_CLEANUP_EXPR, type, rval, 0,
239                     build_delete (build_pointer_type (type),
240                                   build_unary_op (ADDR_EXPR, slot, 0),
241                                   integer_two_node,
242                                   LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0));
243       TREE_SIDE_EFFECTS (rval) = 1;
244       TREE_ADDRESSABLE (rval) = 1;
245     }
246 #endif
247   return rval;
248 }
249
250 /* Recursively search EXP for CALL_EXPRs that need cleanups and replace
251    these CALL_EXPRs with tree nodes that will perform the cleanups.  */
252
253 tree
254 break_out_cleanups (exp)
255      tree exp;
256 {
257   tree tmp = exp;
258
259   if (TREE_CODE (tmp) == CALL_EXPR
260       && TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (tmp)))
261     return build_cplus_new (TREE_TYPE (tmp), tmp, 1);
262
263   while (TREE_CODE (tmp) == NOP_EXPR
264          || TREE_CODE (tmp) == CONVERT_EXPR
265          || TREE_CODE (tmp) == NON_LVALUE_EXPR)
266     {
267       if (TREE_CODE (TREE_OPERAND (tmp, 0)) == CALL_EXPR
268           && TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (TREE_OPERAND (tmp, 0))))
269         {
270           TREE_OPERAND (tmp, 0)
271             = build_cplus_new (TREE_TYPE (TREE_OPERAND (tmp, 0)),
272                                TREE_OPERAND (tmp, 0), 1);
273           break;
274         }
275       else
276         tmp = TREE_OPERAND (tmp, 0);
277     }
278   return exp;
279 }
280
281 /* Recursively perform a preorder search EXP for CALL_EXPRs, making
282    copies where they are found.  Returns a deep copy all nodes transitively
283    containing CALL_EXPRs.  */
284
285 tree
286 break_out_calls (exp)
287      tree exp;
288 {
289   register tree t1, t2;
290   register enum tree_code code;
291   register int changed = 0;
292   register int i;
293
294   if (exp == NULL_TREE)
295     return exp;
296
297   code = TREE_CODE (exp);
298
299   if (code == CALL_EXPR)
300     return copy_node (exp);
301
302   /* Don't try and defeat a save_expr, as it should only be done once. */
303     if (code == SAVE_EXPR)
304        return exp;
305
306   switch (TREE_CODE_CLASS (code))
307     {
308     default:
309       abort ();
310
311     case 'c':  /* a constant */
312     case 't':  /* a type node */
313     case 'x':  /* something random, like an identifier or an ERROR_MARK.  */
314       return exp;
315
316     case 'd':  /* A decl node */
317 #if 0                               /* This is bogus.  jason 9/21/94 */
318
319       t1 = break_out_calls (DECL_INITIAL (exp));
320       if (t1 != DECL_INITIAL (exp))
321         {
322           exp = copy_node (exp);
323           DECL_INITIAL (exp) = t1;
324         }
325 #endif
326       return exp;
327
328     case 'b':  /* A block node */
329       {
330         /* Don't know how to handle these correctly yet.   Must do a
331            break_out_calls on all DECL_INITIAL values for local variables,
332            and also break_out_calls on all sub-blocks and sub-statements.  */
333         abort ();
334       }
335       return exp;
336
337     case 'e':  /* an expression */
338     case 'r':  /* a reference */
339     case 's':  /* an expression with side effects */
340       for (i = tree_code_length[(int) code] - 1; i >= 0; i--)
341         {
342           t1 = break_out_calls (TREE_OPERAND (exp, i));
343           if (t1 != TREE_OPERAND (exp, i))
344             {
345               exp = copy_node (exp);
346               TREE_OPERAND (exp, i) = t1;
347             }
348         }
349       return exp;
350
351     case '<':  /* a comparison expression */
352     case '2':  /* a binary arithmetic expression */
353       t2 = break_out_calls (TREE_OPERAND (exp, 1));
354       if (t2 != TREE_OPERAND (exp, 1))
355         changed = 1;
356     case '1':  /* a unary arithmetic expression */
357       t1 = break_out_calls (TREE_OPERAND (exp, 0));
358       if (t1 != TREE_OPERAND (exp, 0))
359         changed = 1;
360       if (changed)
361         {
362           if (tree_code_length[(int) code] == 1)
363             return build1 (code, TREE_TYPE (exp), t1);
364           else
365             return build (code, TREE_TYPE (exp), t1, t2);
366         }
367       return exp;
368     }
369
370 }
371 \f
372 extern struct obstack *current_obstack;
373 extern struct obstack permanent_obstack, class_obstack;
374 extern struct obstack *saveable_obstack;
375
376 /* Here is how primitive or already-canonicalized types' hash
377    codes are made.  MUST BE CONSISTENT WITH tree.c !!! */
378 #define TYPE_HASH(TYPE) ((HOST_WIDE_INT) (TYPE) & 0777777)
379
380 /* Construct, lay out and return the type of methods belonging to class
381    BASETYPE and whose arguments are described by ARGTYPES and whose values
382    are described by RETTYPE.  If each type exists already, reuse it.  */
383 tree
384 build_cplus_method_type (basetype, rettype, argtypes)
385      tree basetype, rettype, argtypes;
386 {
387   register tree t;
388   tree ptype;
389   int hashcode;
390
391   /* Make a node of the sort we want.  */
392   t = make_node (METHOD_TYPE);
393
394   TYPE_METHOD_BASETYPE (t) = TYPE_MAIN_VARIANT (basetype);
395   TREE_TYPE (t) = rettype;
396   if (IS_SIGNATURE (basetype))
397     ptype = build_signature_pointer_type (TYPE_MAIN_VARIANT (basetype),
398                                           TYPE_READONLY (basetype),
399                                           TYPE_VOLATILE (basetype));
400   else
401     ptype = build_pointer_type (basetype);
402
403   /* The actual arglist for this function includes a "hidden" argument
404      which is "this".  Put it into the list of argument types.  */
405
406   argtypes = tree_cons (NULL_TREE, ptype, argtypes);
407   TYPE_ARG_TYPES (t) = argtypes;
408   TREE_SIDE_EFFECTS (argtypes) = 1;  /* Mark first argtype as "artificial".  */
409
410   /* If we already have such a type, use the old one and free this one.
411      Note that it also frees up the above cons cell if found.  */
412   hashcode = TYPE_HASH (basetype) + TYPE_HASH (rettype) + type_hash_list (argtypes);
413   t = type_hash_canon (hashcode, t);
414
415   if (TYPE_SIZE (t) == 0)
416     layout_type (t);
417
418   return t;
419 }
420
421 tree
422 build_cplus_staticfn_type (basetype, rettype, argtypes)
423      tree basetype, rettype, argtypes;
424 {
425   register tree t;
426   int hashcode;
427
428   /* Make a node of the sort we want.  */
429   t = make_node (FUNCTION_TYPE);
430
431   TYPE_METHOD_BASETYPE (t) = TYPE_MAIN_VARIANT (basetype);
432   TREE_TYPE (t) = rettype;
433
434   TYPE_ARG_TYPES (t) = argtypes;
435
436   /* If we already have such a type, use the old one and free this one.
437      Note that it also frees up the above cons cell if found.  */
438   hashcode = TYPE_HASH (basetype) + TYPE_HASH (rettype) + type_hash_list (argtypes);
439   t = type_hash_canon (hashcode, t);
440
441   if (TYPE_SIZE (t) == 0)
442     layout_type (t);
443
444   return t;
445 }
446
447 tree
448 build_cplus_array_type (elt_type, index_type)
449      tree elt_type;
450      tree index_type;
451 {
452   register struct obstack *ambient_obstack = current_obstack;
453   register struct obstack *ambient_saveable_obstack = saveable_obstack;
454   tree t;
455
456   /* We need a new one.  If both ELT_TYPE and INDEX_TYPE are permanent,
457      make this permanent too.  */
458   if (TREE_PERMANENT (elt_type)
459       && (index_type == 0 || TREE_PERMANENT (index_type)))
460     {
461       current_obstack = &permanent_obstack;
462       saveable_obstack = &permanent_obstack;
463     }
464
465   t = build_array_type (elt_type, index_type);
466
467   /* Push these needs up so that initialization takes place
468      more easily.  */
469   TYPE_NEEDS_CONSTRUCTING (t) = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (elt_type));
470   TYPE_NEEDS_DESTRUCTOR (t) = TYPE_NEEDS_DESTRUCTOR (TYPE_MAIN_VARIANT (elt_type));
471   current_obstack = ambient_obstack;
472   saveable_obstack = ambient_saveable_obstack;
473   return t;
474 }
475 \f
476 /* Make a variant type in the proper way for C/C++, propagating qualifiers
477    down to the element type of an array.  */
478
479 tree
480 cp_build_type_variant (type, constp, volatilep)
481      tree type;
482      int constp, volatilep;
483 {
484   if (TREE_CODE (type) == ARRAY_TYPE)
485     {
486       tree real_main_variant = TYPE_MAIN_VARIANT (type);
487
488       push_obstacks (TYPE_OBSTACK (real_main_variant),
489                      TYPE_OBSTACK (real_main_variant));
490       type = build_cplus_array_type (cp_build_type_variant (TREE_TYPE (type),
491                                                             constp, volatilep),
492                                      TYPE_DOMAIN (type));
493
494       /* TYPE must be on same obstack as REAL_MAIN_VARIANT.  If not,
495          make a copy.  (TYPE might have come from the hash table and
496          REAL_MAIN_VARIANT might be in some function's obstack.)  */
497
498       if (TYPE_OBSTACK (type) != TYPE_OBSTACK (real_main_variant))
499         {
500           type = copy_node (type);
501           TYPE_POINTER_TO (type) = TYPE_REFERENCE_TO (type) = 0;
502         }
503
504       TYPE_MAIN_VARIANT (type) = real_main_variant;
505       pop_obstacks ();
506     }
507   return build_type_variant (type, constp, volatilep);
508 }
509 \f
510 /* Add OFFSET to all base types of T.
511
512    OFFSET, which is a type offset, is number of bytes.
513
514    Note that we don't have to worry about having two paths to the
515    same base type, since this type owns its association list.  */
516 void
517 propagate_binfo_offsets (binfo, offset)
518      tree binfo;
519      tree offset;
520 {
521   tree binfos = BINFO_BASETYPES (binfo);
522   int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
523
524   for (i = 0; i < n_baselinks; /* note increment is done in the loop.  */)
525     {
526       tree base_binfo = TREE_VEC_ELT (binfos, i);
527
528       if (TREE_VIA_VIRTUAL (base_binfo))
529         i += 1;
530       else
531         {
532           int j;
533           tree base_binfos = BINFO_BASETYPES (base_binfo);
534           tree delta;
535
536           for (j = i+1; j < n_baselinks; j++)
537             if (! TREE_VIA_VIRTUAL (TREE_VEC_ELT (binfos, j)))
538               {
539                 /* The next basetype offset must take into account the space
540                    between the classes, not just the size of each class.  */
541                 delta = size_binop (MINUS_EXPR,
542                                     BINFO_OFFSET (TREE_VEC_ELT (binfos, j)),
543                                     BINFO_OFFSET (base_binfo));
544                 break;
545               }
546
547 #if 0
548           if (BINFO_OFFSET_ZEROP (base_binfo))
549             BINFO_OFFSET (base_binfo) = offset;
550           else
551             BINFO_OFFSET (base_binfo)
552               = size_binop (PLUS_EXPR, BINFO_OFFSET (base_binfo), offset);
553 #else
554           BINFO_OFFSET (base_binfo) = offset;
555 #endif
556           if (base_binfos)
557             {
558               int k;
559               tree chain = NULL_TREE;
560
561               /* Now unshare the structure beneath BASE_BINFO.  */
562               for (k = TREE_VEC_LENGTH (base_binfos)-1;
563                    k >= 0; k--)
564                 {
565                   tree base_base_binfo = TREE_VEC_ELT (base_binfos, k);
566                   if (! TREE_VIA_VIRTUAL (base_base_binfo))
567                     TREE_VEC_ELT (base_binfos, k)
568                       = make_binfo (BINFO_OFFSET (base_base_binfo),
569                                     base_base_binfo,
570                                     BINFO_VTABLE (base_base_binfo),
571                                     BINFO_VIRTUALS (base_base_binfo),
572                                     chain);
573                   chain = TREE_VEC_ELT (base_binfos, k);
574                   TREE_VIA_PUBLIC (chain) = TREE_VIA_PUBLIC (base_base_binfo);
575                   TREE_VIA_PROTECTED (chain) = TREE_VIA_PROTECTED (base_base_binfo);
576                   BINFO_INHERITANCE_CHAIN (chain) = base_binfo;
577                 }
578               /* Now propagate the offset to the base types.  */
579               propagate_binfo_offsets (base_binfo, offset);
580             }
581
582           /* Go to our next class that counts for offset propagation.  */
583           i = j;
584           if (i < n_baselinks)
585             offset = size_binop (PLUS_EXPR, offset, delta);
586         }
587     }
588 }
589
590 /* Compute the actual offsets that our virtual base classes
591    will have *for this type*.  This must be performed after
592    the fields are laid out, since virtual baseclasses must
593    lay down at the end of the record.
594
595    Returns the maximum number of virtual functions any of the virtual
596    baseclasses provide.  */
597 int
598 layout_vbasetypes (rec, max)
599      tree rec;
600      int max;
601 {
602   /* Get all the virtual base types that this type uses.
603      The TREE_VALUE slot holds the virtual baseclass type.  */
604   tree vbase_types = get_vbase_types (rec);
605
606 #ifdef STRUCTURE_SIZE_BOUNDARY
607   unsigned record_align = MAX (STRUCTURE_SIZE_BOUNDARY, TYPE_ALIGN (rec));
608 #else
609   unsigned record_align = MAX (BITS_PER_UNIT, TYPE_ALIGN (rec));
610 #endif
611   int desired_align;
612
613   /* Record size so far is CONST_SIZE + VAR_SIZE bits,
614      where CONST_SIZE is an integer
615      and VAR_SIZE is a tree expression.
616      If VAR_SIZE is null, the size is just CONST_SIZE.
617      Naturally we try to avoid using VAR_SIZE.  */
618   register unsigned const_size = 0;
619   register tree var_size = 0;
620   int nonvirtual_const_size;
621   tree nonvirtual_var_size;
622
623   CLASSTYPE_VBASECLASSES (rec) = vbase_types;
624
625   if (TREE_CODE (TYPE_SIZE (rec)) == INTEGER_CST)
626     const_size = TREE_INT_CST_LOW (TYPE_SIZE (rec));
627   else
628     var_size = TYPE_SIZE (rec);
629
630   nonvirtual_const_size = const_size;
631   nonvirtual_var_size = var_size;
632
633   while (vbase_types)
634     {
635       tree basetype = BINFO_TYPE (vbase_types);
636       tree offset;
637
638       desired_align = TYPE_ALIGN (basetype);
639       record_align = MAX (record_align, desired_align);
640
641       if (const_size == 0)
642         offset = integer_zero_node;
643       else
644         {
645           /* Give each virtual base type the alignment it wants.  */
646           const_size = CEIL (const_size, TYPE_ALIGN (basetype))
647             * TYPE_ALIGN (basetype);
648           offset = size_int (CEIL (const_size, BITS_PER_UNIT));
649         }
650
651       if (CLASSTYPE_VSIZE (basetype) > max)
652         max = CLASSTYPE_VSIZE (basetype);
653       BINFO_OFFSET (vbase_types) = offset;
654
655       if (TREE_CODE (TYPE_SIZE (basetype)) == INTEGER_CST)
656         {
657           /* Every virtual baseclass takes a least a UNIT, so that we can
658              take it's address and get something different for each base.  */
659           const_size += MAX (BITS_PER_UNIT,
660                              TREE_INT_CST_LOW (TYPE_SIZE (basetype))
661                              - TREE_INT_CST_LOW (CLASSTYPE_VBASE_SIZE (basetype)));
662         }
663       else if (var_size == 0)
664         var_size = TYPE_SIZE (basetype);
665       else
666         var_size = size_binop (PLUS_EXPR, var_size, TYPE_SIZE (basetype));
667
668       vbase_types = TREE_CHAIN (vbase_types);
669     }
670
671   if (const_size)
672     {
673       /* Because a virtual base might take a single byte above,
674          we have to re-adjust the total size to make sure it it
675          a multiple of the alignment.  */
676       /* Give the whole object the alignment it wants.  */
677       const_size = CEIL (const_size, record_align) * record_align;
678     }
679
680   /* Set the alignment in the complete type.  We don't set CLASSTYPE_ALIGN
681    here, as that is for this class, without any virtual base classes.  */
682   TYPE_ALIGN (rec) = record_align;
683   if (const_size != nonvirtual_const_size)
684     {
685       CLASSTYPE_VBASE_SIZE (rec)
686         = size_int (const_size - nonvirtual_const_size);
687       TYPE_SIZE (rec) = size_int (const_size);
688     }
689
690   /* Now propagate offset information throughout the lattice
691      under the vbase type.  */
692   for (vbase_types = CLASSTYPE_VBASECLASSES (rec); vbase_types;
693        vbase_types = TREE_CHAIN (vbase_types))
694     {
695       tree base_binfos = BINFO_BASETYPES (vbase_types);
696
697       BINFO_INHERITANCE_CHAIN (vbase_types) = TYPE_BINFO (rec);
698
699       if (base_binfos)
700         {
701           tree chain = NULL_TREE;
702           int j;
703           /* Now unshare the structure beneath BASE_BINFO.  */
704
705           for (j = TREE_VEC_LENGTH (base_binfos)-1;
706                j >= 0; j--)
707             {
708               tree base_base_binfo = TREE_VEC_ELT (base_binfos, j);
709               if (! TREE_VIA_VIRTUAL (base_base_binfo))
710                 TREE_VEC_ELT (base_binfos, j)
711                   = make_binfo (BINFO_OFFSET (base_base_binfo),
712                                 base_base_binfo,
713                                 BINFO_VTABLE (base_base_binfo),
714                                 BINFO_VIRTUALS (base_base_binfo),
715                                 chain);
716               chain = TREE_VEC_ELT (base_binfos, j);
717               TREE_VIA_PUBLIC (chain) = TREE_VIA_PUBLIC (base_base_binfo);
718               TREE_VIA_PROTECTED (chain) = TREE_VIA_PROTECTED (base_base_binfo);
719               BINFO_INHERITANCE_CHAIN (chain) = vbase_types;
720             }
721
722           propagate_binfo_offsets (vbase_types, BINFO_OFFSET (vbase_types));
723         }
724     }
725
726   return max;
727 }
728
729 /* Lay out the base types of a record type, REC.
730    Tentatively set the size and alignment of REC
731    according to the base types alone.
732
733    Offsets for immediate nonvirtual baseclasses are also computed here.
734
735    TYPE_BINFO (REC) should be NULL_TREE on entry, and this routine
736    creates a list of base_binfos in TYPE_BINFO (REC) from BINFOS.
737
738    Returns list of virtual base classes in a FIELD_DECL chain.  */
739 tree
740 layout_basetypes (rec, binfos)
741      tree rec, binfos;
742 {
743   /* Chain to hold all the new FIELD_DECLs which point at virtual
744      base classes.  */
745   tree vbase_decls = NULL_TREE;
746
747 #ifdef STRUCTURE_SIZE_BOUNDARY
748   unsigned record_align = MAX (STRUCTURE_SIZE_BOUNDARY, TYPE_ALIGN (rec));
749 #else
750   unsigned record_align = MAX (BITS_PER_UNIT, TYPE_ALIGN (rec));
751 #endif
752
753   /* Record size so far is CONST_SIZE + VAR_SIZE bits, where CONST_SIZE is
754      an integer and VAR_SIZE is a tree expression.  If VAR_SIZE is null,
755      the size is just CONST_SIZE.  Naturally we try to avoid using
756      VAR_SIZE.  And so far, we've been successful. */
757 #if 0
758   register tree var_size = 0;
759 #endif
760
761   register unsigned const_size = 0;
762   int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
763
764   /* Handle basetypes almost like fields, but record their
765      offsets differently.  */
766
767   for (i = 0; i < n_baseclasses; i++)
768     {
769       int inc, desired_align, int_vbase_size;
770       register tree base_binfo = TREE_VEC_ELT (binfos, i);
771       register tree basetype = BINFO_TYPE (base_binfo);
772       tree decl, offset;
773
774       if (TYPE_SIZE (basetype) == 0)
775         {
776 #if 0
777           /* This error is now reported in xref_tag, thus giving better
778              location information.  */
779           error_with_aggr_type (base_binfo,
780                                 "base class `%s' has incomplete type");
781
782           TREE_VIA_PUBLIC (base_binfo) = 1;
783           TREE_VIA_PROTECTED (base_binfo) = 0;
784           TREE_VIA_VIRTUAL (base_binfo) = 0;
785
786           /* Should handle this better so that
787
788              class A;
789              class B: private A { virtual void F(); };
790
791              does not dump core when compiled. */
792           my_friendly_abort (121);
793 #endif
794           continue;
795         }
796
797       /* All basetypes are recorded in the association list of the
798          derived type.  */
799
800       if (TREE_VIA_VIRTUAL (base_binfo))
801         {
802           int j;
803           char *name = (char *)alloca (TYPE_NAME_LENGTH (basetype)
804                                        + sizeof (VBASE_NAME) + 1);
805
806           /* The offset for a virtual base class is only used in computing
807              virtual function tables and for initializing virtual base
808              pointers.  It is built once `get_vbase_types' is called.  */
809
810           /* If this basetype can come from another vbase pointer
811              without an additional indirection, we will share
812              that pointer.  If an indirection is involved, we
813              make our own pointer.  */
814           for (j = 0; j < n_baseclasses; j++)
815             {
816               tree other_base_binfo = TREE_VEC_ELT (binfos, j);
817               if (! TREE_VIA_VIRTUAL (other_base_binfo)
818                   && binfo_member (basetype,
819                                    CLASSTYPE_VBASECLASSES (BINFO_TYPE (other_base_binfo))))
820                 goto got_it;
821             }
822           sprintf (name, VBASE_NAME_FORMAT, TYPE_NAME_STRING (basetype));
823           decl = build_lang_decl (FIELD_DECL, get_identifier (name),
824                                   build_pointer_type (basetype));
825           /* If you change any of the below, take a look at all the
826              other VFIELD_BASEs and VTABLE_BASEs in the code, and change
827              them too. */
828           DECL_ASSEMBLER_NAME (decl) = get_identifier (VTABLE_BASE);
829           DECL_VIRTUAL_P (decl) = 1;
830           DECL_FIELD_CONTEXT (decl) = rec;
831           DECL_CLASS_CONTEXT (decl) = rec;
832           DECL_FCONTEXT (decl) = basetype;
833           DECL_SAVED_INSNS (decl) = NULL_RTX;
834           DECL_FIELD_SIZE (decl) = 0;
835           DECL_ALIGN (decl) = TYPE_ALIGN (ptr_type_node);
836           TREE_CHAIN (decl) = vbase_decls;
837           BINFO_VPTR_FIELD (base_binfo) = decl;
838           vbase_decls = decl;
839
840           if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (basetype)
841               && DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0)) == NULL_TREE)
842             {
843               warning_with_decl (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0),
844                                  "destructor `%s' non-virtual");
845               warning ("in inheritance relationship `%s: virtual %s'",
846                        TYPE_NAME_STRING (rec),
847                        TYPE_NAME_STRING (basetype));
848             }
849         got_it:
850           /* The space this decl occupies has already been accounted for.  */
851           continue;
852         }
853
854       if (const_size == 0)
855         offset = integer_zero_node;
856       else
857         {
858           /* Give each base type the alignment it wants.  */
859           const_size = CEIL (const_size, TYPE_ALIGN (basetype))
860             * TYPE_ALIGN (basetype);
861           offset = size_int ((const_size + BITS_PER_UNIT - 1) / BITS_PER_UNIT);
862
863 #if 0
864           /* bpk: Disabled this check until someone is willing to
865              claim it as theirs and explain exactly what circumstances
866              warrant the warning.  */ 
867           if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (basetype)
868               && DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0)) == NULL_TREE)
869             {
870               warning_with_decl (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0),
871                                  "destructor `%s' non-virtual");
872               warning ("in inheritance relationship `%s:%s %s'",
873                        TYPE_NAME_STRING (rec),
874                        TREE_VIA_VIRTUAL (base_binfo) ? " virtual" : "",
875                        TYPE_NAME_STRING (basetype));
876             }
877 #endif
878         }
879       BINFO_OFFSET (base_binfo) = offset;
880       if (CLASSTYPE_VSIZE (basetype))
881         {
882           BINFO_VTABLE (base_binfo) = TYPE_BINFO_VTABLE (basetype);
883           BINFO_VIRTUALS (base_binfo) = TYPE_BINFO_VIRTUALS (basetype);
884         }
885       TREE_CHAIN (base_binfo) = TYPE_BINFO (rec);
886       TYPE_BINFO (rec) = base_binfo;
887
888       /* Add only the amount of storage not present in
889          the virtual baseclasses.  */
890
891       int_vbase_size = TREE_INT_CST_LOW (CLASSTYPE_VBASE_SIZE (basetype));
892       if (TREE_INT_CST_LOW (TYPE_SIZE (basetype)) > int_vbase_size)
893         {
894           inc = MAX (record_align,
895                      (TREE_INT_CST_LOW (TYPE_SIZE (basetype))
896                       - int_vbase_size));
897
898           /* Record must have at least as much alignment as any field.  */
899           desired_align = TYPE_ALIGN (basetype);
900           record_align = MAX (record_align, desired_align);
901
902           const_size += inc;
903         }
904     }
905
906   if (const_size)
907     CLASSTYPE_SIZE (rec) = size_int (const_size);
908   else
909     CLASSTYPE_SIZE (rec) = integer_zero_node;
910   CLASSTYPE_ALIGN (rec) = record_align;
911
912   return vbase_decls;
913 }
914 \f
915 /* Hashing of lists so that we don't make duplicates.
916    The entry point is `list_hash_canon'.  */
917
918 /* Each hash table slot is a bucket containing a chain
919    of these structures.  */
920
921 struct list_hash
922 {
923   struct list_hash *next;       /* Next structure in the bucket.  */
924   int hashcode;                 /* Hash code of this list.  */
925   tree list;                    /* The list recorded here.  */
926 };
927
928 /* Now here is the hash table.  When recording a list, it is added
929    to the slot whose index is the hash code mod the table size.
930    Note that the hash table is used for several kinds of lists.
931    While all these live in the same table, they are completely independent,
932    and the hash code is computed differently for each of these.  */
933
934 #define TYPE_HASH_SIZE 59
935 struct list_hash *list_hash_table[TYPE_HASH_SIZE];
936
937 /* Compute a hash code for a list (chain of TREE_LIST nodes
938    with goodies in the TREE_PURPOSE, TREE_VALUE, and bits of the
939    TREE_COMMON slots), by adding the hash codes of the individual entries.  */
940
941 int
942 list_hash (list)
943      tree list;
944 {
945   register int hashcode = 0;
946
947   if (TREE_CHAIN (list))
948     hashcode += TYPE_HASH (TREE_CHAIN (list));
949
950   if (TREE_VALUE (list))
951     hashcode += TYPE_HASH (TREE_VALUE (list));
952   else
953     hashcode += 1007;
954   if (TREE_PURPOSE (list))
955     hashcode += TYPE_HASH (TREE_PURPOSE (list));
956   else
957     hashcode += 1009;
958   return hashcode;
959 }
960
961 /* Look in the type hash table for a type isomorphic to TYPE.
962    If one is found, return it.  Otherwise return 0.  */
963
964 tree
965 list_hash_lookup (hashcode, list)
966      int hashcode;
967      tree list;
968 {
969   register struct list_hash *h;
970   for (h = list_hash_table[hashcode % TYPE_HASH_SIZE]; h; h = h->next)
971     if (h->hashcode == hashcode
972         && TREE_VIA_VIRTUAL (h->list) == TREE_VIA_VIRTUAL (list)
973         && TREE_VIA_PUBLIC (h->list) == TREE_VIA_PUBLIC (list)
974         && TREE_VIA_PROTECTED (h->list) == TREE_VIA_PROTECTED (list)
975         && TREE_PURPOSE (h->list) == TREE_PURPOSE (list)
976         && TREE_VALUE (h->list) == TREE_VALUE (list)
977         && TREE_CHAIN (h->list) == TREE_CHAIN (list))
978       {
979         my_friendly_assert (TREE_TYPE (h->list) == TREE_TYPE (list), 299);
980         return h->list;
981       }
982   return 0;
983 }
984
985 /* Add an entry to the list-hash-table
986    for a list TYPE whose hash code is HASHCODE.  */
987
988 void
989 list_hash_add (hashcode, list)
990      int hashcode;
991      tree list;
992 {
993   register struct list_hash *h;
994
995   h = (struct list_hash *) obstack_alloc (&class_obstack, sizeof (struct list_hash));
996   h->hashcode = hashcode;
997   h->list = list;
998   h->next = list_hash_table[hashcode % TYPE_HASH_SIZE];
999   list_hash_table[hashcode % TYPE_HASH_SIZE] = h;
1000 }
1001
1002 /* Given TYPE, and HASHCODE its hash code, return the canonical
1003    object for an identical list if one already exists.
1004    Otherwise, return TYPE, and record it as the canonical object
1005    if it is a permanent object.
1006
1007    To use this function, first create a list of the sort you want.
1008    Then compute its hash code from the fields of the list that
1009    make it different from other similar lists.
1010    Then call this function and use the value.
1011    This function frees the list you pass in if it is a duplicate.  */
1012
1013 /* Set to 1 to debug without canonicalization.  Never set by program.  */
1014 static int debug_no_list_hash = 0;
1015
1016 tree
1017 list_hash_canon (hashcode, list)
1018      int hashcode;
1019      tree list;
1020 {
1021   tree t1;
1022
1023   if (debug_no_list_hash)
1024     return list;
1025
1026   t1 = list_hash_lookup (hashcode, list);
1027   if (t1 != 0)
1028     {
1029       obstack_free (&class_obstack, list);
1030       return t1;
1031     }
1032
1033   /* If this is a new list, record it for later reuse.  */
1034   list_hash_add (hashcode, list);
1035
1036   return list;
1037 }
1038
1039 tree
1040 hash_tree_cons (via_public, via_virtual, via_protected, purpose, value, chain)
1041      int via_public, via_virtual, via_protected;
1042      tree purpose, value, chain;
1043 {
1044   struct obstack *ambient_obstack = current_obstack;
1045   tree t;
1046   int hashcode;
1047
1048   current_obstack = &class_obstack;
1049   t = tree_cons (purpose, value, chain);
1050   TREE_VIA_PUBLIC (t) = via_public;
1051   TREE_VIA_PROTECTED (t) = via_protected;
1052   TREE_VIA_VIRTUAL (t) = via_virtual;
1053   hashcode = list_hash (t);
1054   t = list_hash_canon (hashcode, t);
1055   current_obstack = ambient_obstack;
1056   return t;
1057 }
1058
1059 /* Constructor for hashed lists.  */
1060 tree
1061 hash_tree_chain (value, chain)
1062      tree value, chain;
1063 {
1064   struct obstack *ambient_obstack = current_obstack;
1065   tree t;
1066   int hashcode;
1067
1068   current_obstack = &class_obstack;
1069   t = tree_cons (NULL_TREE, value, chain);
1070   hashcode = list_hash (t);
1071   t = list_hash_canon (hashcode, t);
1072   current_obstack = ambient_obstack;
1073   return t;
1074 }
1075
1076 /* Similar, but used for concatenating two lists.  */
1077 tree
1078 hash_chainon (list1, list2)
1079      tree list1, list2;
1080 {
1081   if (list2 == 0)
1082     return list1;
1083   if (list1 == 0)
1084     return list2;
1085   if (TREE_CHAIN (list1) == NULL_TREE)
1086     return hash_tree_chain (TREE_VALUE (list1), list2);
1087   return hash_tree_chain (TREE_VALUE (list1),
1088                           hash_chainon (TREE_CHAIN (list1), list2));
1089 }
1090
1091 static tree
1092 get_identifier_list (value)
1093      tree value;
1094 {
1095   tree list = IDENTIFIER_AS_LIST (value);
1096   if (list != NULL_TREE
1097       && (TREE_CODE (list) != TREE_LIST
1098           || TREE_VALUE (list) != value))
1099     list = NULL_TREE;
1100   else if (IDENTIFIER_HAS_TYPE_VALUE (value)
1101            && TREE_CODE (IDENTIFIER_TYPE_VALUE (value)) == RECORD_TYPE
1102            && IDENTIFIER_TYPE_VALUE (value)
1103               == TYPE_MAIN_VARIANT (IDENTIFIER_TYPE_VALUE (value)))
1104     {
1105       tree type = IDENTIFIER_TYPE_VALUE (value);
1106
1107       if (TYPE_PTRMEMFUNC_P (type))
1108         list = NULL_TREE;
1109       else if (type == current_class_type)
1110         /* Don't mess up the constructor name.  */
1111         list = tree_cons (NULL_TREE, value, NULL_TREE);
1112       else
1113         {
1114           register tree id;
1115           /* This will return the correct thing for regular types,
1116              nested types, and templates.  Yay! */
1117           if (TYPE_NESTED_NAME (type))
1118             id = TYPE_NESTED_NAME (type);
1119           else
1120             id = TYPE_IDENTIFIER (type);
1121
1122           if (CLASSTYPE_ID_AS_LIST (type) == NULL_TREE)
1123             CLASSTYPE_ID_AS_LIST (type)
1124               = perm_tree_cons (NULL_TREE, id, NULL_TREE);
1125           list = CLASSTYPE_ID_AS_LIST (type);
1126         }
1127     }
1128   return list;
1129 }
1130
1131 tree
1132 get_decl_list (value)
1133      tree value;
1134 {
1135   tree list = NULL_TREE;
1136
1137   if (TREE_CODE (value) == IDENTIFIER_NODE)
1138     list = get_identifier_list (value);
1139   else if (TREE_CODE (value) == RECORD_TYPE
1140            && TYPE_LANG_SPECIFIC (value))
1141     list = CLASSTYPE_AS_LIST (value);
1142
1143   if (list != NULL_TREE)
1144     {
1145       my_friendly_assert (TREE_CHAIN (list) == NULL_TREE, 301);
1146       return list;
1147     }
1148
1149   return build_decl_list (NULL_TREE, value);
1150 }
1151
1152 /* Look in the type hash table for a type isomorphic to
1153    `build_tree_list (NULL_TREE, VALUE)'.
1154    If one is found, return it.  Otherwise return 0.  */
1155
1156 tree
1157 list_hash_lookup_or_cons (value)
1158      tree value;
1159 {
1160   register int hashcode = TYPE_HASH (value);
1161   register struct list_hash *h;
1162   struct obstack *ambient_obstack;
1163   tree list = NULL_TREE;
1164
1165   if (TREE_CODE (value) == IDENTIFIER_NODE)
1166     list = get_identifier_list (value);
1167   else if (TREE_CODE (value) == TYPE_DECL
1168            && TREE_CODE (TREE_TYPE (value)) == RECORD_TYPE
1169            && TYPE_LANG_SPECIFIC (TREE_TYPE (value)))
1170     list = CLASSTYPE_ID_AS_LIST (TREE_TYPE (value));
1171   else if (TREE_CODE (value) == RECORD_TYPE
1172            && TYPE_LANG_SPECIFIC (value))
1173     list = CLASSTYPE_AS_LIST (value);
1174
1175   if (list != NULL_TREE)
1176     {
1177       my_friendly_assert (TREE_CHAIN (list) == NULL_TREE, 302);
1178       return list;
1179     }
1180
1181   if (debug_no_list_hash)
1182     return hash_tree_chain (value, NULL_TREE);
1183
1184   for (h = list_hash_table[hashcode % TYPE_HASH_SIZE]; h; h = h->next)
1185     if (h->hashcode == hashcode
1186         && TREE_VIA_VIRTUAL (h->list) == 0
1187         && TREE_VIA_PUBLIC (h->list) == 0
1188         && TREE_VIA_PROTECTED (h->list) == 0
1189         && TREE_PURPOSE (h->list) == 0
1190         && TREE_VALUE (h->list) == value)
1191       {
1192         my_friendly_assert (TREE_TYPE (h->list) == 0, 303);
1193         my_friendly_assert (TREE_CHAIN (h->list) == 0, 304);
1194         return h->list;
1195       }
1196
1197   ambient_obstack = current_obstack;
1198   current_obstack = &class_obstack;
1199   list = build_tree_list (NULL_TREE, value);
1200   list_hash_add (hashcode, list);
1201   current_obstack = ambient_obstack;
1202   return list;
1203 }
1204 \f
1205 /* Build an association between TYPE and some parameters:
1206
1207    OFFSET is the offset added to `this' to convert it to a pointer
1208    of type `TYPE *'
1209
1210    BINFO is the base binfo to use, if we are deriving from one.  This
1211    is necessary, as we want specialized parent binfos from base
1212    classes, so that the VTABLE_NAMEs of bases are for the most derived
1213    type, instead of of the simple type.
1214
1215    VTABLE is the virtual function table with which to initialize
1216    sub-objects of type TYPE.
1217
1218    VIRTUALS are the virtual functions sitting in VTABLE.
1219
1220    CHAIN are more associations we must retain.  */
1221
1222 tree
1223 make_binfo (offset, binfo, vtable, virtuals, chain)
1224      tree offset, binfo;
1225      tree vtable, virtuals;
1226      tree chain;
1227 {
1228   tree new_binfo = make_tree_vec (6);
1229   tree type;
1230
1231   if (TREE_CODE (binfo) == TREE_VEC)
1232     type = BINFO_TYPE (binfo);
1233   else
1234     {
1235       type = binfo;
1236       binfo = TYPE_BINFO (binfo);
1237     }
1238
1239   TREE_CHAIN (new_binfo) = chain;
1240   if (chain)
1241     TREE_USED (new_binfo) = TREE_USED (chain);
1242
1243   TREE_TYPE (new_binfo) = TYPE_MAIN_VARIANT (type);
1244   BINFO_OFFSET (new_binfo) = offset;
1245   BINFO_VTABLE (new_binfo) = vtable;
1246   BINFO_VIRTUALS (new_binfo) = virtuals;
1247   BINFO_VPTR_FIELD (new_binfo) = NULL_TREE;
1248
1249   if (binfo && BINFO_BASETYPES (binfo) != NULL_TREE)
1250     BINFO_BASETYPES (new_binfo) = copy_node (BINFO_BASETYPES (binfo));      
1251   return new_binfo;
1252 }
1253
1254 /* Return the binfo value for ELEM in TYPE.  */
1255
1256 tree
1257 binfo_value (elem, type)
1258      tree elem;
1259      tree type;
1260 {
1261   if (get_base_distance (elem, type, 0, (tree *)0) == -2)
1262     compiler_error ("base class `%s' ambiguous in binfo_value",
1263                     TYPE_NAME_STRING (elem));
1264   if (elem == type)
1265     return TYPE_BINFO (type);
1266   if (TREE_CODE (elem) == RECORD_TYPE && TYPE_BINFO (elem) == type)
1267     return type;
1268   return get_binfo (elem, type, 0);
1269 }
1270
1271 tree
1272 reverse_path (path)
1273      tree path;
1274 {
1275   register tree prev = 0, tmp, next;
1276   for (tmp = path; tmp; tmp = next)
1277     {
1278       next = BINFO_INHERITANCE_CHAIN (tmp);
1279       BINFO_INHERITANCE_CHAIN (tmp) = prev;
1280       prev = tmp;
1281     }
1282   return prev;
1283 }
1284
1285 tree
1286 virtual_member (elem, list)
1287      tree elem;
1288      tree list;
1289 {
1290   tree t;
1291   tree rval, nval;
1292
1293   for (t = list; t; t = TREE_CHAIN (t))
1294     if (elem == BINFO_TYPE (t))
1295       return t;
1296   rval = 0;
1297   for (t = list; t; t = TREE_CHAIN (t))
1298     {
1299       tree binfos = BINFO_BASETYPES (t);
1300       int i;
1301
1302       if (binfos != NULL_TREE)
1303         for (i = TREE_VEC_LENGTH (binfos)-1; i >= 0; i--)
1304           {
1305             nval = binfo_value (elem, BINFO_TYPE (TREE_VEC_ELT (binfos, i)));
1306             if (nval)
1307               {
1308                 if (rval && BINFO_OFFSET (nval) != BINFO_OFFSET (rval))
1309                   my_friendly_abort (104);
1310                 rval = nval;
1311               }
1312           }
1313     }
1314   return rval;
1315 }
1316
1317 void
1318 debug_binfo (elem)
1319      tree elem;
1320 {
1321   unsigned HOST_WIDE_INT n;
1322   tree virtuals;
1323
1324   fprintf (stderr, "type \"%s\"; offset = %d\n",
1325            TYPE_NAME_STRING (BINFO_TYPE (elem)),
1326            TREE_INT_CST_LOW (BINFO_OFFSET (elem)));
1327   fprintf (stderr, "vtable type:\n");
1328   debug_tree (BINFO_TYPE (elem));
1329   if (BINFO_VTABLE (elem))
1330     fprintf (stderr, "vtable decl \"%s\"\n", IDENTIFIER_POINTER (DECL_NAME (BINFO_VTABLE (elem))));
1331   else
1332     fprintf (stderr, "no vtable decl yet\n");
1333   fprintf (stderr, "virtuals:\n");
1334   virtuals = BINFO_VIRTUALS (elem);
1335
1336   n = skip_rtti_stuff (&virtuals);
1337
1338   while (virtuals)
1339     {
1340       tree fndecl = TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals)), 0);
1341       fprintf (stderr, "%s [%d =? %d]\n",
1342                IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)),
1343                n, TREE_INT_CST_LOW (DECL_VINDEX (fndecl)));
1344       ++n;
1345       virtuals = TREE_CHAIN (virtuals);
1346     }
1347 }
1348
1349 /* Return the length of a chain of nodes chained through DECL_CHAIN.
1350    We expect a null pointer to mark the end of the chain.
1351    This is the Lisp primitive `length'.  */
1352
1353 int
1354 decl_list_length (t)
1355      tree t;
1356 {
1357   register tree tail;
1358   register int len = 0;
1359
1360   my_friendly_assert (TREE_CODE (t) == FUNCTION_DECL
1361                       || TREE_CODE (t) == TEMPLATE_DECL, 300);
1362   for (tail = t; tail; tail = DECL_CHAIN (tail))
1363     len++;
1364
1365   return len;
1366 }
1367
1368 int
1369 count_functions (t)
1370      tree t;
1371 {
1372   if (TREE_CODE (t) == FUNCTION_DECL)
1373     return 1;
1374   else if (TREE_CODE (t) == TREE_LIST)
1375     return decl_list_length (TREE_VALUE (t));
1376
1377   my_friendly_abort (359);
1378   return 0;
1379 }
1380
1381 /* Like value_member, but for DECL_CHAINs.  */
1382 tree
1383 decl_value_member (elem, list)
1384      tree elem, list;
1385 {
1386   while (list)
1387     {
1388       if (elem == list)
1389         return list;
1390       list = DECL_CHAIN (list);
1391     }
1392   return NULL_TREE;
1393 }
1394
1395 int
1396 is_overloaded_fn (x)
1397      tree x;
1398 {
1399   if (TREE_CODE (x) == FUNCTION_DECL)
1400     return 1;
1401
1402   if (TREE_CODE (x) == TREE_LIST
1403       && (TREE_CODE (TREE_VALUE (x)) == FUNCTION_DECL
1404           || TREE_CODE (TREE_VALUE (x)) == TEMPLATE_DECL))
1405     return 1;
1406
1407   return 0;
1408 }
1409
1410 int
1411 really_overloaded_fn (x)
1412      tree x;
1413 {     
1414   if (TREE_CODE (x) == TREE_LIST
1415       && (TREE_CODE (TREE_VALUE (x)) == FUNCTION_DECL
1416           || TREE_CODE (TREE_VALUE (x)) == TEMPLATE_DECL))
1417     return 1;
1418
1419   return 0;
1420 }
1421
1422 tree
1423 get_first_fn (from)
1424      tree from;
1425 {
1426   if (TREE_CODE (from) == FUNCTION_DECL)
1427     return from;
1428
1429   my_friendly_assert (TREE_CODE (from) == TREE_LIST, 9);
1430   
1431   return TREE_VALUE (from);
1432 }
1433
1434 tree
1435 fnaddr_from_vtable_entry (entry)
1436      tree entry;
1437 {
1438   if (flag_vtable_thunks)
1439     {
1440       tree func = entry;
1441       if (TREE_CODE (func) == ADDR_EXPR)
1442         func = TREE_OPERAND (func, 0);
1443       if (TREE_CODE (func) == THUNK_DECL)
1444         return DECL_INITIAL (func);
1445       else
1446         return entry;
1447     }
1448   else
1449     return TREE_VALUE (TREE_CHAIN (TREE_CHAIN (CONSTRUCTOR_ELTS (entry))));
1450 }
1451
1452 void
1453 set_fnaddr_from_vtable_entry (entry, value)
1454      tree entry, value;
1455 {
1456   if (flag_vtable_thunks)
1457     abort ();
1458   else
1459   TREE_VALUE (TREE_CHAIN (TREE_CHAIN (CONSTRUCTOR_ELTS (entry)))) = value;
1460 }
1461
1462 tree
1463 function_arg_chain (t)
1464      tree t;
1465 {
1466   return TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (t)));
1467 }
1468
1469 int
1470 promotes_to_aggr_type (t, code)
1471      tree t;
1472      enum tree_code code;
1473 {
1474   if (TREE_CODE (t) == code)
1475     t = TREE_TYPE (t);
1476   return IS_AGGR_TYPE (t);
1477 }
1478
1479 int
1480 is_aggr_type_2 (t1, t2)
1481      tree t1, t2;
1482 {
1483   if (TREE_CODE (t1) != TREE_CODE (t2))
1484     return 0;
1485   return IS_AGGR_TYPE (t1) && IS_AGGR_TYPE (t2);
1486 }
1487
1488 /* Give message using types TYPE1 and TYPE2 as arguments.
1489    PFN is the function which will print the message;
1490    S is the format string for PFN to use.  */
1491 void
1492 message_2_types (pfn, s, type1, type2)
1493      void (*pfn) ();
1494      char *s;
1495      tree type1, type2;
1496 {
1497   tree name1 = TYPE_NAME (type1);
1498   tree name2 = TYPE_NAME (type2);
1499   if (TREE_CODE (name1) == TYPE_DECL)
1500     name1 = DECL_NAME (name1);
1501   if (TREE_CODE (name2) == TYPE_DECL)
1502     name2 = DECL_NAME (name2);
1503   (*pfn) (s, IDENTIFIER_POINTER (name1), IDENTIFIER_POINTER (name2));
1504 }
1505 \f
1506 #define PRINT_RING_SIZE 4
1507
1508 char *
1509 lang_printable_name (decl)
1510      tree decl;
1511 {
1512   static tree decl_ring[PRINT_RING_SIZE];
1513   static char *print_ring[PRINT_RING_SIZE];
1514   static int ring_counter;
1515   int i;
1516
1517   /* Only cache functions.  */
1518   if (TREE_CODE (decl) != FUNCTION_DECL
1519       || DECL_LANG_SPECIFIC (decl) == 0)
1520     return decl_as_string (decl, 1);
1521
1522   /* See if this print name is lying around.  */
1523   for (i = 0; i < PRINT_RING_SIZE; i++)
1524     if (decl_ring[i] == decl)
1525       /* yes, so return it.  */
1526       return print_ring[i];
1527
1528   if (++ring_counter == PRINT_RING_SIZE)
1529     ring_counter = 0;
1530
1531   if (current_function_decl != NULL_TREE)
1532     {
1533       if (decl_ring[ring_counter] == current_function_decl)
1534         ring_counter += 1;
1535       if (ring_counter == PRINT_RING_SIZE)
1536         ring_counter = 0;
1537       if (decl_ring[ring_counter] == current_function_decl)
1538         my_friendly_abort (106);
1539     }
1540
1541   if (print_ring[ring_counter])
1542     free (print_ring[ring_counter]);
1543
1544   {
1545     int print_ret_type_p
1546       = (!DECL_CONSTRUCTOR_P (decl)
1547          && !DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl)));
1548
1549     char *name = (char *)decl_as_string (decl, print_ret_type_p);
1550     print_ring[ring_counter] = (char *)malloc (strlen (name) + 1);
1551     strcpy (print_ring[ring_counter], name);
1552     decl_ring[ring_counter] = decl;
1553   }
1554   return print_ring[ring_counter];
1555 }
1556 \f
1557 /* Comparison function for sorting identifiers in RAISES lists.
1558    Note that because IDENTIFIER_NODEs are unique, we can sort
1559    them by address, saving an indirection.  */
1560 static int
1561 id_cmp (p1, p2)
1562      tree *p1, *p2;
1563 {
1564   return (HOST_WIDE_INT)TREE_VALUE (*p1) - (HOST_WIDE_INT)TREE_VALUE (*p2);
1565 }
1566
1567 /* Build the FUNCTION_TYPE or METHOD_TYPE which may throw exceptions
1568    listed in RAISES.  */
1569 tree
1570 build_exception_variant (type, raises)
1571      tree type;
1572      tree raises;
1573 {
1574   int i;
1575   tree v = TYPE_MAIN_VARIANT (type);
1576   tree t, t2, cname;
1577   tree *a = (tree *)alloca ((list_length (raises)+1) * sizeof (tree));
1578   int constp = TYPE_READONLY (type);
1579   int volatilep = TYPE_VOLATILE (type);
1580
1581   for (v = TYPE_NEXT_VARIANT (v); v; v = TYPE_NEXT_VARIANT (v))
1582     {
1583       if (TYPE_READONLY (v) != constp
1584           || TYPE_VOLATILE (v) != volatilep)
1585         continue;
1586
1587       /* @@ This should do set equality, not exact match. */
1588       if (simple_cst_list_equal (TYPE_RAISES_EXCEPTIONS (v), raises))
1589         /* List of exceptions raised matches previously found list.
1590
1591            @@ Nice to free up storage used in consing up the
1592            @@ list of exceptions raised.  */
1593         return v;
1594     }
1595
1596   /* Need to build a new variant.  */
1597   v = copy_node (type);
1598   TYPE_NEXT_VARIANT (v) = TYPE_NEXT_VARIANT (type);
1599   TYPE_NEXT_VARIANT (type) = v;
1600   if (raises && ! TREE_PERMANENT (raises))
1601     {
1602       push_obstacks_nochange ();
1603       end_temporary_allocation ();
1604       raises = copy_list (raises);
1605       pop_obstacks ();
1606     }
1607   TYPE_RAISES_EXCEPTIONS (v) = raises;
1608   return v;
1609 }
1610
1611 /* Subroutine of copy_to_permanent
1612
1613    Assuming T is a node build bottom-up, make it all exist on
1614    permanent obstack, if it is not permanent already.  */
1615
1616 tree
1617 mapcar (t, func)
1618      tree t;
1619      tree (*func)();
1620 {
1621   enum tree_code code;
1622   tree tmp;
1623
1624   if (t == NULL_TREE)
1625     return t;
1626
1627   if (tmp = func (t), tmp != NULL_TREE)
1628     return tmp;
1629
1630   switch (code = TREE_CODE (t))
1631     {
1632     case ERROR_MARK:
1633       return error_mark_node;
1634
1635     case VAR_DECL:
1636     case FUNCTION_DECL:
1637     case CONST_DECL:
1638       break;
1639
1640     case PARM_DECL:
1641       {
1642         tree chain = TREE_CHAIN (t);
1643         t = copy_node (t);
1644         TREE_CHAIN (t) = mapcar (chain, func);
1645         TREE_TYPE (t) = mapcar (TREE_TYPE (t), func);
1646         DECL_INITIAL (t) = mapcar (DECL_INITIAL (t), func);
1647         DECL_SIZE (t) = mapcar (DECL_SIZE (t), func);
1648         return t;
1649       }
1650
1651     case TREE_LIST:
1652       {
1653         tree chain = TREE_CHAIN (t);
1654         t = copy_node (t);
1655         TREE_PURPOSE (t) = mapcar (TREE_PURPOSE (t), func);
1656         TREE_VALUE (t) = mapcar (TREE_VALUE (t), func);
1657         TREE_CHAIN (t) = mapcar (chain, func);
1658         return t;
1659       }
1660
1661     case TREE_VEC:
1662       {
1663         int len = TREE_VEC_LENGTH (t);
1664
1665         t = copy_node (t);
1666         while (len--)
1667           TREE_VEC_ELT (t, len) = mapcar (TREE_VEC_ELT (t, len), func);
1668         return t;
1669       }
1670
1671     case INTEGER_CST:
1672     case REAL_CST:
1673     case STRING_CST:
1674       return copy_node (t);
1675
1676     case COND_EXPR:
1677     case TARGET_EXPR:
1678     case NEW_EXPR:
1679       t = copy_node (t);
1680       TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
1681       TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func);
1682       TREE_OPERAND (t, 2) = mapcar (TREE_OPERAND (t, 2), func);
1683       return t;
1684
1685     case SAVE_EXPR:
1686       t = copy_node (t);
1687       TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
1688       return t;
1689
1690     case MODIFY_EXPR:
1691     case PLUS_EXPR:
1692     case MINUS_EXPR:
1693     case MULT_EXPR:
1694     case TRUNC_DIV_EXPR:
1695     case TRUNC_MOD_EXPR:
1696     case MIN_EXPR:
1697     case MAX_EXPR:
1698     case LSHIFT_EXPR:
1699     case RSHIFT_EXPR:
1700     case BIT_IOR_EXPR:
1701     case BIT_XOR_EXPR:
1702     case BIT_AND_EXPR:
1703     case BIT_ANDTC_EXPR:
1704     case TRUTH_ANDIF_EXPR:
1705     case TRUTH_ORIF_EXPR:
1706     case LT_EXPR:
1707     case LE_EXPR:
1708     case GT_EXPR:
1709     case GE_EXPR:
1710     case EQ_EXPR:
1711     case NE_EXPR:
1712     case CEIL_DIV_EXPR:
1713     case FLOOR_DIV_EXPR:
1714     case ROUND_DIV_EXPR:
1715     case CEIL_MOD_EXPR:
1716     case FLOOR_MOD_EXPR:
1717     case ROUND_MOD_EXPR:
1718     case COMPOUND_EXPR:
1719     case PREDECREMENT_EXPR:
1720     case PREINCREMENT_EXPR:
1721     case POSTDECREMENT_EXPR:
1722     case POSTINCREMENT_EXPR:
1723     case CALL_EXPR:
1724       t = copy_node (t);
1725       TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
1726       TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func);
1727       return t;
1728
1729     case CONVERT_EXPR:
1730     case ADDR_EXPR:
1731     case INDIRECT_REF:
1732     case NEGATE_EXPR:
1733     case BIT_NOT_EXPR:
1734     case TRUTH_NOT_EXPR:
1735     case NOP_EXPR:
1736     case COMPONENT_REF:
1737       t = copy_node (t);
1738       TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
1739       return t;
1740
1741     case POINTER_TYPE:
1742       return build_pointer_type (mapcar (TREE_TYPE (t), func));
1743     case REFERENCE_TYPE:
1744       return build_reference_type (mapcar (TREE_TYPE (t), func));
1745     case FUNCTION_TYPE:
1746       return build_function_type (mapcar (TREE_TYPE (t), func),
1747                                   mapcar (TYPE_ARG_TYPES (t), func));
1748     case ARRAY_TYPE:
1749       return build_array_type (mapcar (TREE_TYPE (t), func),
1750                                mapcar (TYPE_DOMAIN (t), func));
1751     case INTEGER_TYPE:
1752       return build_index_type (mapcar (TYPE_MAX_VALUE (t), func));
1753
1754     case OFFSET_TYPE:
1755       return build_offset_type (mapcar (TYPE_OFFSET_BASETYPE (t), func),
1756                                 mapcar (TREE_TYPE (t), func));
1757     case METHOD_TYPE:
1758       return build_method_type
1759         (mapcar (TYPE_METHOD_BASETYPE (t), func),
1760          build_function_type
1761          (mapcar (TREE_TYPE (t), func),
1762           mapcar (TREE_CHAIN (TYPE_ARG_TYPES (t)), func)));
1763
1764     case RECORD_TYPE:
1765       if (TYPE_PTRMEMFUNC_P (t))
1766         return build_ptrmemfunc_type
1767           (mapcar (TYPE_PTRMEMFUNC_FN_TYPE (t), func));
1768       /* else fall through */
1769       
1770       /*  This list is incomplete, but should suffice for now.
1771           It is very important that `sorry' does not call
1772           `report_error_function'.  That could cause an infinite loop.  */
1773     default:
1774       sorry ("initializer contains unrecognized tree code");
1775       return error_mark_node;
1776
1777     }
1778   my_friendly_abort (107);
1779   /* NOTREACHED */
1780   return NULL_TREE;
1781 }
1782
1783 static tree
1784 perm_manip (t)
1785      tree t;
1786 {
1787   if (TREE_PERMANENT (t))
1788     return t;
1789   return NULL_TREE;
1790 }
1791
1792 /* Assuming T is a node built bottom-up, make it all exist on
1793    permanent obstack, if it is not permanent already.  */
1794 tree
1795 copy_to_permanent (t)
1796      tree t;
1797 {
1798   register struct obstack *ambient_obstack = current_obstack;
1799   register struct obstack *ambient_saveable_obstack = saveable_obstack;
1800   int resume;
1801
1802   if (t == NULL_TREE || TREE_PERMANENT (t))
1803     return t;
1804
1805   saveable_obstack = &permanent_obstack;
1806   current_obstack = saveable_obstack;
1807   resume = suspend_momentary ();
1808
1809   t = mapcar (t, perm_manip);
1810
1811   resume_momentary (resume);
1812   current_obstack = ambient_obstack;
1813   saveable_obstack = ambient_saveable_obstack;
1814
1815   return t;
1816 }
1817
1818 void
1819 print_lang_statistics ()
1820 {
1821   extern struct obstack maybepermanent_obstack;
1822   print_obstack_statistics ("class_obstack", &class_obstack);
1823   print_obstack_statistics ("permanent_obstack", &permanent_obstack);
1824   print_obstack_statistics ("maybepermanent_obstack", &maybepermanent_obstack);
1825   print_search_statistics ();
1826   print_class_statistics ();
1827 }
1828
1829 /* This is used by the `assert' macro.  It is provided in libgcc.a,
1830    which `cc' doesn't know how to link.  Note that the C++ front-end
1831    no longer actually uses the `assert' macro (instead, it calls
1832    my_friendly_assert).  But all of the back-end files still need this.  */
1833 void
1834 __eprintf (string, expression, line, filename)
1835 #ifdef __STDC__
1836      const char *string;
1837      const char *expression;
1838      unsigned line;
1839      const char *filename;
1840 #else
1841      char *string;
1842      char *expression;
1843      unsigned line;
1844      char *filename;
1845 #endif
1846 {
1847   fprintf (stderr, string, expression, line, filename);
1848   fflush (stderr);
1849   abort ();
1850 }
1851
1852 /* Return, as an INTEGER_CST node, the number of elements for
1853    TYPE (which is an ARRAY_TYPE).  This counts only elements of the top array. */
1854
1855 tree
1856 array_type_nelts_top (type)
1857      tree type;
1858 {
1859   return fold (build (PLUS_EXPR, sizetype,
1860                       array_type_nelts (type),
1861                       integer_one_node));
1862 }
1863
1864 /* Return, as an INTEGER_CST node, the number of elements for
1865    TYPE (which is an ARRAY_TYPE).  This one is a recursive count of all
1866    ARRAY_TYPEs that are clumped together. */
1867
1868 tree
1869 array_type_nelts_total (type)
1870      tree type;
1871 {
1872   tree sz = array_type_nelts_top (type);
1873   type = TREE_TYPE (type);
1874   while (TREE_CODE (type) == ARRAY_TYPE)
1875     {
1876       tree n = array_type_nelts_top (type);
1877       sz = fold (build (MULT_EXPR, sizetype, sz, n));
1878       type = TREE_TYPE (type);
1879     }
1880   return sz;
1881 }
1882
1883 static
1884 tree
1885 bot_manip (t)
1886      tree t;
1887 {
1888   if (TREE_CODE (t) != TREE_LIST && ! TREE_SIDE_EFFECTS (t))
1889     return t;
1890   else if (TREE_CODE (t) == TARGET_EXPR)
1891     return build_cplus_new (TREE_TYPE (t),
1892                             break_out_target_exprs (TREE_OPERAND (t, 1)), 0);
1893   return NULL_TREE;
1894 }
1895   
1896 /* Actually, we'll just clean out the target exprs for the moment.  */
1897 tree
1898 break_out_target_exprs (t)
1899      tree t;
1900 {
1901   return mapcar (t, bot_manip);
1902 }
1903
1904 tree
1905 unsave_expr (expr)
1906      tree expr;
1907 {
1908   tree t;
1909
1910   t = build1 (UNSAVE_EXPR, TREE_TYPE (expr), expr);
1911   TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (expr);
1912   return t;
1913 }
1914
1915 /* Modify a tree in place so that all the evaluate only once things
1916    are cleared out.  Return the EXPR given.  */
1917 tree
1918 unsave_expr_now (expr)
1919      tree expr;
1920 {
1921   enum tree_code code;
1922   register int i;
1923
1924   if (expr == NULL_TREE)
1925     return expr;
1926
1927   code = TREE_CODE (expr);
1928   switch (code)
1929     {
1930     case SAVE_EXPR:
1931       SAVE_EXPR_RTL (expr) = NULL_RTX;
1932       break;
1933
1934     case TARGET_EXPR:
1935       sorry ("TARGET_EXPR reused inside UNSAVE_EXPR");
1936       break;
1937       
1938     case RTL_EXPR:
1939       warning ("RTL_EXPR reused inside UNSAVE_EXPR");
1940       RTL_EXPR_SEQUENCE (expr) = NULL_RTX;
1941       break;
1942
1943     case CALL_EXPR:
1944       CALL_EXPR_RTL (expr) = NULL_RTX;
1945       if (TREE_OPERAND (expr, 1)
1946           && TREE_CODE (TREE_OPERAND (expr, 1)) == TREE_LIST)
1947         {
1948           tree exp = TREE_OPERAND (expr, 1);
1949           while (exp)
1950             {
1951               unsave_expr_now (TREE_VALUE (exp));
1952               exp = TREE_CHAIN (exp);
1953             }
1954         }
1955       break;
1956       
1957     case WITH_CLEANUP_EXPR:
1958       warning ("WITH_CLEANUP_EXPR reused inside UNSAVE_EXPR");
1959       RTL_EXPR_RTL (expr) = NULL_RTX;
1960       break;
1961     }
1962
1963   switch (TREE_CODE_CLASS (code))
1964     {
1965     case 'c':  /* a constant */
1966     case 't':  /* a type node */
1967     case 'x':  /* something random, like an identifier or an ERROR_MARK.  */
1968     case 'd':  /* A decl node */
1969     case 'b':  /* A block node */
1970       return expr;
1971
1972     case 'e':  /* an expression */
1973     case 'r':  /* a reference */
1974     case 's':  /* an expression with side effects */
1975     case '<':  /* a comparison expression */
1976     case '2':  /* a binary arithmetic expression */
1977     case '1':  /* a unary arithmetic expression */
1978       for (i = tree_code_length[(int) code] - 1; i >= 0; i--)
1979         unsave_expr_now (TREE_OPERAND (expr, i));
1980       return expr;
1981
1982     default:
1983       my_friendly_abort (999);
1984     }
1985 }
1986
1987 /* Since cleanup may have SAVE_EXPRs in it, we protect it with an
1988    UNSAVE_EXPR as the backend cannot yet handle SAVE_EXPRs in cleanups
1989    by itself.  */
1990 int
1991 cp_expand_decl_cleanup (decl, cleanup)
1992      tree decl, cleanup;
1993 {
1994   return expand_decl_cleanup (decl, unsave_expr (cleanup));
1995 }