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

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

unix.superglobalmegacorp.com

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