Annotation of gcc/cp-tree.c, revision 1.1.1.6

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.