Annotation of gcc/cp/class.c, revision 1.1

1.1     ! root        1: /* Functions related to building classes and their related objects.
        !             2:    Copyright (C) 1987, 1992, 1993, 1994 Free Software Foundation, Inc.
        !             3:    Contributed 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: 
        !            22: /* High-level class interface. */
        !            23: 
        !            24: #include "config.h"
        !            25: #include "tree.h"
        !            26: #include <stdio.h>
        !            27: #include "cp-tree.h"
        !            28: #include "flags.h"
        !            29: 
        !            30: #include "obstack.h"
        !            31: #define obstack_chunk_alloc xmalloc
        !            32: #define obstack_chunk_free free
        !            33: 
        !            34: extern struct obstack permanent_obstack;
        !            35: 
        !            36: /* This is how we tell when two virtual member functions are really the
        !            37:    same. */
        !            38: #define SAME_FN(FN1DECL, FN2DECL) (DECL_ASSEMBLER_NAME (FN1DECL) == DECL_ASSEMBLER_NAME (FN2DECL))
        !            39: 
        !            40: extern void set_class_shadows PROTO ((tree));
        !            41: 
        !            42: /* Way of stacking class types.  */
        !            43: static tree *current_class_base, *current_class_stack;
        !            44: static int current_class_stacksize;
        !            45: int current_class_depth;
        !            46: 
        !            47: struct class_level
        !            48: {
        !            49:   /* The previous class level.  */
        !            50:   struct class_level *level_chain;
        !            51: 
        !            52:   /* The class instance variable, as a PARM_DECL.  */
        !            53:   tree decl;
        !            54:   /* The class instance variable, as an object.  */
        !            55:   tree object;
        !            56:   /* The virtual function table pointer
        !            57:      for the class instance variable.  */
        !            58:   tree vtable_decl;
        !            59: 
        !            60:   /* Name of the current class.  */
        !            61:   tree name;
        !            62:   /* Type of the current class.  */
        !            63:   tree type;
        !            64: 
        !            65:   /* Flags for this class level.  */
        !            66:   int this_is_variable;
        !            67:   int memoized_lookups;
        !            68:   int save_memoized;
        !            69:   int unused;
        !            70: };
        !            71: 
        !            72: tree current_class_decl, C_C_D;        /* PARM_DECL: the class instance variable */
        !            73: tree current_vtable_decl;
        !            74: 
        !            75: /* The following two can be derived from the previous one */
        !            76: tree current_class_name;       /* IDENTIFIER_NODE: name of current class */
        !            77: tree current_class_type;       /* _TYPE: the type of the current class */
        !            78: tree previous_class_type;      /* _TYPE: the previous type that was a class */
        !            79: tree previous_class_values;            /* TREE_LIST: copy of the class_shadowed list
        !            80:                                   when leaving an outermost class scope.  */
        !            81: static tree get_vfield_name PROTO((tree));
        !            82: tree the_null_vtable_entry;
        !            83: 
        !            84: /* Way of stacking language names.  */
        !            85: tree *current_lang_base, *current_lang_stack;
        !            86: int current_lang_stacksize;
        !            87: 
        !            88: /* Names of languages we recognize.  */
        !            89: tree lang_name_c, lang_name_cplusplus;
        !            90: tree current_lang_name;
        !            91: 
        !            92: /* When layout out an aggregate type, the size of the
        !            93:    basetypes (virtual and non-virtual) is passed to layout_record
        !            94:    via this node.  */
        !            95: static tree base_layout_decl;
        !            96: 
        !            97: /* Variables shared between class.c and call.c.  */
        !            98: 
        !            99: int n_vtables = 0;
        !           100: int n_vtable_entries = 0;
        !           101: int n_vtable_searches = 0;
        !           102: int n_vtable_elems = 0;
        !           103: int n_convert_harshness = 0;
        !           104: int n_compute_conversion_costs = 0;
        !           105: int n_build_method_call = 0;
        !           106: int n_inner_fields_searched = 0;
        !           107: 
        !           108: /* Virtual baseclass things.  */
        !           109: tree
        !           110: build_vbase_pointer (exp, type)
        !           111:      tree exp, type;
        !           112: {
        !           113:   char *name;
        !           114: 
        !           115:   name = (char *) alloca (TYPE_NAME_LENGTH (type) + sizeof (VBASE_NAME) + 1);
        !           116:   sprintf (name, VBASE_NAME_FORMAT, TYPE_NAME_STRING (type));
        !           117:   return build_component_ref (exp, get_identifier (name), 0, 0);
        !           118: }
        !           119: 
        !           120: /* Is the type of the EXPR, the complete type of the object?
        !           121:    If we are going to be wrong, we must be conservative, and return 0. */
        !           122: int
        !           123: complete_type_p (expr)
        !           124:      tree expr;
        !           125: {
        !           126:   tree type = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
        !           127:   while (1)
        !           128:     {
        !           129:       switch (TREE_CODE (expr))
        !           130:        {
        !           131:        case SAVE_EXPR:
        !           132:        case INDIRECT_REF:
        !           133:        case ADDR_EXPR:
        !           134:        case NOP_EXPR:
        !           135:        case CONVERT_EXPR:
        !           136:          expr = TREE_OPERAND (expr, 0);
        !           137:          continue;
        !           138: 
        !           139:        case CALL_EXPR: 
        !           140:          if (! TREE_HAS_CONSTRUCTOR (expr))
        !           141:            break;
        !           142:          /* fall through... */
        !           143:        case VAR_DECL:
        !           144:        case FIELD_DECL:
        !           145:          if (TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE
        !           146:              && IS_AGGR_TYPE (TREE_TYPE (TREE_TYPE (expr)))
        !           147:              && TYPE_MAIN_VARIANT (TREE_TYPE (expr)) == type)
        !           148:            return 1;
        !           149:          /* fall through... */
        !           150:        case TARGET_EXPR:
        !           151:        case PARM_DECL:
        !           152:          if (IS_AGGR_TYPE (TREE_TYPE (expr))
        !           153:              && TYPE_MAIN_VARIANT (TREE_TYPE (expr)) == type)
        !           154:            return 1;
        !           155:          /* fall through... */
        !           156:        case PLUS_EXPR:
        !           157:        default:
        !           158:          break;
        !           159:        }
        !           160:       break;
        !           161:     }
        !           162:   return 0;
        !           163: }
        !           164: 
        !           165: /* Build multi-level access to EXPR using hierarchy path PATH.
        !           166:    CODE is PLUS_EXPR if we are going with the grain,
        !           167:    and MINUS_EXPR if we are not (in which case, we cannot traverse
        !           168:    virtual baseclass links).
        !           169: 
        !           170:    TYPE is the type we want this path to have on exit.
        !           171: 
        !           172:    ALIAS_THIS is non-zero if EXPR in an expression involving `this'.  */
        !           173: tree
        !           174: build_vbase_path (code, type, expr, path, alias_this)
        !           175:      enum tree_code code;
        !           176:      tree type, expr, path;
        !           177:      int alias_this;
        !           178: {
        !           179:   register int changed = 0;
        !           180:   tree last = NULL_TREE, last_virtual = NULL_TREE;
        !           181:   int nonnull = 0;
        !           182:   int fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull);
        !           183:   tree null_expr = 0, nonnull_expr;
        !           184:   tree basetype;
        !           185:   tree offset = integer_zero_node;
        !           186: 
        !           187:   /* We need additional logic to convert back to the unconverted type
        !           188:      (the static type of the complete object), and then convert back
        !           189:      to the type we want.  Until that is done, or until we can
        !           190:      recognize when that is, we cannot do the short cut logic. (mrs) */
        !           191:   /* Do this, until we can undo any previous convertions.  See net35.C
        !           192:      for a testcase. */
        !           193:   fixed_type_p = complete_type_p (expr);
        !           194: 
        !           195:   if (!fixed_type_p && TREE_SIDE_EFFECTS (expr))
        !           196:     expr = save_expr (expr);
        !           197:   nonnull_expr = expr;
        !           198: 
        !           199:   if (BINFO_INHERITANCE_CHAIN (path))
        !           200:     {
        !           201:       tree reverse_path = NULL_TREE;
        !           202: 
        !           203:       while (path)
        !           204:        {
        !           205:          tree r = copy_node (path);
        !           206:          BINFO_INHERITANCE_CHAIN (r) = reverse_path;
        !           207:          reverse_path = r;
        !           208:          path = BINFO_INHERITANCE_CHAIN (path);
        !           209:        }
        !           210:       path = reverse_path;
        !           211:     }
        !           212: 
        !           213:   basetype = BINFO_TYPE (path);
        !           214: 
        !           215:   while (path)
        !           216:     {
        !           217:       if (TREE_VIA_VIRTUAL (path))
        !           218:        {
        !           219:          last_virtual = BINFO_TYPE (path);
        !           220:          if (code == PLUS_EXPR)
        !           221:            {
        !           222:              changed = ! fixed_type_p;
        !           223: 
        !           224:              if (changed)
        !           225:                {
        !           226:                  extern int flag_assume_nonnull_objects;
        !           227:                  tree ind;
        !           228: 
        !           229:                  /* We already check for ambiguous things in the caller, just
        !           230:                     find a path. */
        !           231:                  if (last)
        !           232:                    {
        !           233:                      tree binfo = get_binfo (last, TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (nonnull_expr))), 0);
        !           234:                      nonnull_expr = convert_pointer_to_real (binfo, nonnull_expr);
        !           235:                    }
        !           236:                  ind = build_indirect_ref (nonnull_expr, NULL_PTR);
        !           237:                  nonnull_expr = build_vbase_pointer (ind, last_virtual);
        !           238:                  if (nonnull == 0 && !flag_assume_nonnull_objects
        !           239:                      && null_expr == NULL_TREE)
        !           240:                    {
        !           241:                      null_expr = build1 (NOP_EXPR, TYPE_POINTER_TO (last_virtual), integer_zero_node);
        !           242:                      expr = build (COND_EXPR, TYPE_POINTER_TO (last_virtual),
        !           243:                                    build (EQ_EXPR, integer_type_node, expr,
        !           244:                                           integer_zero_node),
        !           245:                                    null_expr, nonnull_expr);
        !           246:                    }
        !           247:                }
        !           248:              /* else we'll figure out the offset below.  */
        !           249: 
        !           250:              /* Happens in the case of parse errors.  */
        !           251:              if (nonnull_expr == error_mark_node)
        !           252:                return error_mark_node;
        !           253:            }
        !           254:          else
        !           255:            {
        !           256:              cp_error ("cannot cast up from virtual baseclass `%T'",
        !           257:                          last_virtual);
        !           258:              return error_mark_node;
        !           259:            }
        !           260:        }
        !           261:       last = path;
        !           262:       path = BINFO_INHERITANCE_CHAIN (path);
        !           263:     }
        !           264:   /* LAST is now the last basetype assoc on the path.  */
        !           265: 
        !           266:   /* A pointer to a virtual base member of a non-null object
        !           267:      is non-null.  Therefore, we only need to test for zeroness once.
        !           268:      Make EXPR the canonical expression to deal with here.  */
        !           269:   if (null_expr)
        !           270:     {
        !           271:       TREE_OPERAND (expr, 2) = nonnull_expr;
        !           272:       TREE_TYPE (TREE_OPERAND (expr, 1)) = TREE_TYPE (nonnull_expr);
        !           273:     }
        !           274:   else
        !           275:     expr = nonnull_expr;
        !           276: 
        !           277:   /* If we go through any virtual base pointers, make sure that
        !           278:      casts to BASETYPE from the last virtual base class use
        !           279:      the right value for BASETYPE.  */
        !           280:   if (changed)
        !           281:     {
        !           282:       tree intype = TREE_TYPE (TREE_TYPE (expr));
        !           283:       if (TYPE_MAIN_VARIANT (intype) == BINFO_TYPE (last))
        !           284:        basetype = intype;
        !           285:       else
        !           286:        {
        !           287:          tree binfo = get_binfo (last, TYPE_MAIN_VARIANT (intype), 0);
        !           288:          basetype = last;
        !           289:          offset = BINFO_OFFSET (binfo);
        !           290:        }
        !           291:     }
        !           292:   else
        !           293:     {
        !           294:       if (last_virtual)
        !           295:        {
        !           296:          offset = BINFO_OFFSET (binfo_member (last_virtual,
        !           297:                                               CLASSTYPE_VBASECLASSES (basetype)));
        !           298:          offset = size_binop (PLUS_EXPR, offset, BINFO_OFFSET (last));
        !           299:        }
        !           300:       else
        !           301:        offset = BINFO_OFFSET (last);
        !           302:     }
        !           303: 
        !           304:   if (TREE_INT_CST_LOW (offset))
        !           305:     {
        !           306:       /* For multiple inheritance: if `this' can be set by any
        !           307:         function, then it could be 0 on entry to any function.
        !           308:         Preserve such zeroness here.  Otherwise, only in the
        !           309:         case of constructors need we worry, and in those cases,
        !           310:         it will be zero, or initialized to some legal value to
        !           311:         which we may add.  */
        !           312:       if (nonnull == 0 && (alias_this == 0 || flag_this_is_variable > 0))
        !           313:        {
        !           314:          if (null_expr)
        !           315:            TREE_TYPE (null_expr) = type;
        !           316:          else
        !           317:            null_expr = build1 (NOP_EXPR, type, integer_zero_node);
        !           318:          if (TREE_SIDE_EFFECTS (expr))
        !           319:            expr = save_expr (expr);
        !           320: 
        !           321:          return build (COND_EXPR, type,
        !           322:                        build (EQ_EXPR, integer_type_node, expr, integer_zero_node),
        !           323:                        null_expr,
        !           324:                        build (code, type, expr, offset));
        !           325:        }
        !           326:       else return build (code, type, expr, offset);
        !           327:     }
        !           328: 
        !           329:   /* Cannot change the TREE_TYPE of a NOP_EXPR here, since it may
        !           330:      be used multiple times in initialization of multiple inheritance.  */
        !           331:   if (null_expr)
        !           332:     {
        !           333:       TREE_TYPE (expr) = type;
        !           334:       return expr;
        !           335:     }
        !           336:   else
        !           337:     return build1 (NOP_EXPR, type, expr);
        !           338: }
        !           339: 
        !           340: /* Virtual function things.  */
        !           341: 
        !           342: /* Virtual functions to be dealt with after laying out our base
        !           343:    classes.  We do all overrides after we layout virtual base classes.
        !           344:    */
        !           345: static tree pending_hard_virtuals;
        !           346: static int doing_hard_virtuals;
        !           347: 
        !           348: /* Build an entry in the virtual function table.
        !           349:    DELTA is the offset for the `this' pointer.
        !           350:    PFN is an ADDR_EXPR containing a pointer to the virtual function.
        !           351:    Note that the index (DELTA2) in the virtual function table
        !           352:    is always 0.  */
        !           353: tree
        !           354: build_vtable_entry (delta, pfn)
        !           355:      tree delta, pfn;
        !           356: {
        !           357: 
        !           358:   if (flag_vtable_thunks)
        !           359:     {
        !           360:       HOST_WIDE_INT idelta = TREE_INT_CST_LOW (delta);
        !           361:       extern tree make_thunk ();
        !           362:       if (idelta)
        !           363:        {
        !           364:          pfn = build1 (ADDR_EXPR, vtable_entry_type,
        !           365:                        make_thunk (pfn, idelta));
        !           366:          TREE_READONLY (pfn) = 1;
        !           367:          TREE_CONSTANT (pfn) = 1;
        !           368:        }
        !           369: #ifdef GATHER_STATISTICS
        !           370:       n_vtable_entries += 1;
        !           371: #endif
        !           372:       return pfn;
        !           373:     }
        !           374:   else
        !           375:     {
        !           376:       extern int flag_huge_objects;
        !           377:       tree elems = tree_cons (NULL_TREE, delta,
        !           378:                              tree_cons (NULL_TREE, integer_zero_node,
        !           379:                                         build_tree_list (NULL_TREE, pfn)));
        !           380:       tree entry = build (CONSTRUCTOR, vtable_entry_type, NULL_TREE, elems);
        !           381: 
        !           382:       /* DELTA is constructed by `size_int', which means it may be an
        !           383:         unsigned quantity on some platforms.  Therefore, we cannot use
        !           384:         `int_fits_type_p', because when DELTA is really negative,
        !           385:         `force_fit_type' will make it look like a very large number.  */
        !           386: 
        !           387:       if ((TREE_INT_CST_LOW (TYPE_MAX_VALUE (delta_type_node))
        !           388:           < TREE_INT_CST_LOW (delta))
        !           389:          || (TREE_INT_CST_LOW (delta)
        !           390:              < TREE_INT_CST_LOW (TYPE_MIN_VALUE (delta_type_node))))
        !           391:        if (flag_huge_objects)
        !           392:          sorry ("object size exceeds built-in limit for virtual function table implementation");
        !           393:        else
        !           394:          sorry ("object size exceeds normal limit for virtual function table implementation, recompile all source and use -fhuge-objects");
        !           395: 
        !           396:       TREE_CONSTANT (entry) = 1;
        !           397:       TREE_STATIC (entry) = 1;
        !           398:       TREE_READONLY (entry) = 1;
        !           399: 
        !           400: #ifdef GATHER_STATISTICS
        !           401:       n_vtable_entries += 1;
        !           402: #endif
        !           403: 
        !           404:       return entry;
        !           405:     }
        !           406: }
        !           407: 
        !           408: /* Given an object INSTANCE, return an expression which yields the
        !           409:    virtual function corresponding to INDEX.  There are many special
        !           410:    cases for INSTANCE which we take care of here, mainly to avoid
        !           411:    creating extra tree nodes when we don't have to.  */
        !           412: tree
        !           413: build_vfn_ref (ptr_to_instptr, instance, idx)
        !           414:      tree *ptr_to_instptr, instance;
        !           415:      tree idx;
        !           416: {
        !           417:   extern int building_cleanup;
        !           418:   tree vtbl, aref;
        !           419:   tree basetype = TREE_TYPE (instance);
        !           420: 
        !           421:   if (TREE_CODE (basetype) == REFERENCE_TYPE)
        !           422:     basetype = TREE_TYPE (basetype);
        !           423: 
        !           424:   if (instance == C_C_D)
        !           425:     {
        !           426:       if (current_vtable_decl == NULL_TREE
        !           427:          || current_vtable_decl == error_mark_node
        !           428:          || !UNIQUELY_DERIVED_FROM_P (DECL_FCONTEXT (CLASSTYPE_VFIELD (current_class_type)), basetype))
        !           429:        vtbl = build_indirect_ref (build_vfield_ref (instance, basetype), NULL_PTR);
        !           430:       else
        !           431:        vtbl = current_vtable_decl;
        !           432:     }
        !           433:   else
        !           434:     {
        !           435:       if (optimize)
        !           436:        {
        !           437:          /* Try to figure out what a reference refers to, and
        !           438:             access its virtual function table directly.  */
        !           439:          tree ref = NULL_TREE;
        !           440: 
        !           441:          if (TREE_CODE (instance) == INDIRECT_REF
        !           442:              && TREE_CODE (TREE_TYPE (TREE_OPERAND (instance, 0))) == REFERENCE_TYPE)
        !           443:            ref = TREE_OPERAND (instance, 0);
        !           444:          else if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)
        !           445:            ref = instance;
        !           446: 
        !           447:          if (ref && TREE_CODE (ref) == VAR_DECL
        !           448:              && DECL_INITIAL (ref))
        !           449:            {
        !           450:              tree init = DECL_INITIAL (ref);
        !           451: 
        !           452:              while (TREE_CODE (init) == NOP_EXPR
        !           453:                     || TREE_CODE (init) == NON_LVALUE_EXPR)
        !           454:                init = TREE_OPERAND (init, 0);
        !           455:              if (TREE_CODE (init) == ADDR_EXPR)
        !           456:                {
        !           457:                  init = TREE_OPERAND (init, 0);
        !           458:                  if (IS_AGGR_TYPE (TREE_TYPE (init))
        !           459:                      && (TREE_CODE (init) == PARM_DECL
        !           460:                          || TREE_CODE (init) == VAR_DECL))
        !           461:                    instance = init;
        !           462:                }
        !           463:            }
        !           464:        }
        !           465: 
        !           466:       if (IS_AGGR_TYPE (TREE_TYPE (instance))
        !           467:          && !IS_SIGNATURE_POINTER (TREE_TYPE (instance))
        !           468:          && !IS_SIGNATURE_REFERENCE (TREE_TYPE (instance))
        !           469:          && (TREE_CODE (instance) == RESULT_DECL
        !           470:              || TREE_CODE (instance) == PARM_DECL
        !           471:              || TREE_CODE (instance) == VAR_DECL))
        !           472:        vtbl = TYPE_BINFO_VTABLE (basetype);
        !           473:       else
        !           474:        vtbl = build_indirect_ref (build_vfield_ref (instance, basetype),
        !           475:                                   NULL_PTR);
        !           476:     }
        !           477:   if (!flag_vtable_thunks)
        !           478:     assemble_external (vtbl);
        !           479:   aref = build_array_ref (vtbl, idx);
        !           480: 
        !           481:   /* Save the intermediate result in a SAVE_EXPR so we don't have to
        !           482:      compute each component of the virtual function pointer twice.  */ 
        !           483:   if (!building_cleanup && TREE_CODE (aref) == INDIRECT_REF)
        !           484:     TREE_OPERAND (aref, 0) = save_expr (TREE_OPERAND (aref, 0));
        !           485: 
        !           486:   if (flag_vtable_thunks)
        !           487:     return aref;
        !           488:   else
        !           489:     {
        !           490:       *ptr_to_instptr
        !           491:        = build (PLUS_EXPR, TREE_TYPE (*ptr_to_instptr),
        !           492:                 *ptr_to_instptr,
        !           493:                 convert (ptrdiff_type_node,
        !           494:                          build_component_ref (aref, delta_identifier, 0, 0)));
        !           495:       return build_component_ref (aref, pfn_identifier, 0, 0);
        !           496:     }
        !           497: }
        !           498: 
        !           499: /* Return the name of the virtual function table (as an IDENTIFIER_NODE)
        !           500:    for the given TYPE.  */
        !           501: static tree
        !           502: get_vtable_name (type)
        !           503:      tree type;
        !           504: {
        !           505:   tree type_id = build_typename_overload (type);
        !           506:   char *buf = (char *)alloca (strlen (VTABLE_NAME_FORMAT)
        !           507:                              + IDENTIFIER_LENGTH (type_id) + 2);
        !           508:   char *ptr = IDENTIFIER_POINTER (type_id);
        !           509:   int i;
        !           510:   for (i = 0; ptr[i] == OPERATOR_TYPENAME_FORMAT[i]; i++) ;
        !           511: #if 0
        !           512:   /* We don't take off the numbers; prepare_fresh_vtable uses the
        !           513:      DECL_ASSEMBLER_NAME for the type, which includes the number
        !           514:      in `3foo'.  If we were to pull them off here, we'd end up with
        !           515:      something like `_vt.foo.3bar', instead of a uniform definition.  */
        !           516:   while (ptr[i] >= '0' && ptr[i] <= '9')
        !           517:     i += 1;
        !           518: #endif
        !           519:   sprintf (buf, VTABLE_NAME_FORMAT, ptr+i);
        !           520:   return get_identifier (buf);
        !           521: }
        !           522: 
        !           523: /* Build a virtual function for type TYPE.
        !           524:    If BINFO is non-NULL, build the vtable starting with the initial
        !           525:    approximation that it is the same as the one which is the head of
        !           526:    the association list.  */
        !           527: static tree
        !           528: build_vtable (binfo, type)
        !           529:      tree binfo, type;
        !           530: {
        !           531:   tree name = get_vtable_name (type);
        !           532:   tree virtuals, decl;
        !           533: 
        !           534:   if (binfo)
        !           535:     {
        !           536:       virtuals = copy_list (BINFO_VIRTUALS (binfo));
        !           537:       decl = build_decl (VAR_DECL, name, TREE_TYPE (BINFO_VTABLE (binfo)));
        !           538:     }
        !           539:   else
        !           540:     {
        !           541:       virtuals = NULL_TREE;
        !           542:       decl = build_decl (VAR_DECL, name, void_type_node);
        !           543:     }
        !           544: 
        !           545: #ifdef GATHER_STATISTICS
        !           546:   n_vtables += 1;
        !           547:   n_vtable_elems += list_length (virtuals);
        !           548: #endif
        !           549: 
        !           550:   /* Set TREE_PUBLIC and TREE_EXTERN as appropriate.  */
        !           551:   if (! flag_vtable_thunks)
        !           552:     import_export_vtable (decl, type);
        !           553: 
        !           554:   IDENTIFIER_GLOBAL_VALUE (name) = decl = pushdecl_top_level (decl);
        !           555:   /* Initialize the association list for this type, based
        !           556:      on our first approximation.  */
        !           557:   TYPE_BINFO_VTABLE (type) = decl;
        !           558:   TYPE_BINFO_VIRTUALS (type) = virtuals;
        !           559: 
        !           560:   TREE_STATIC (decl) = 1;
        !           561: #ifndef WRITABLE_VTABLES
        !           562:   /* Make them READONLY by default. (mrs) */
        !           563:   TREE_READONLY (decl) = 1;
        !           564: #endif
        !           565:   /* At one time the vtable info was grabbed 2 words at a time.  This
        !           566:      fails on sparc unless you have 8-byte alignment.  (tiemann) */
        !           567:   DECL_ALIGN (decl) = MAX (TYPE_ALIGN (double_type_node),
        !           568:                           DECL_ALIGN (decl));
        !           569: 
        !           570:   /* Why is this conditional? (mrs) */
        !           571:   if (binfo && write_virtuals >= 0)
        !           572:     DECL_VIRTUAL_P (decl) = 1;
        !           573:   DECL_CONTEXT (decl) = type;
        !           574: 
        !           575:   binfo = TYPE_BINFO (type);
        !           576:   SET_BINFO_NEW_VTABLE_MARKED (binfo);
        !           577:   return decl;
        !           578: }
        !           579: 
        !           580: /* Given a base type PARENT, and a derived type TYPE, build
        !           581:    a name which distinguishes exactly the PARENT member of TYPE's type.
        !           582: 
        !           583:    FORMAT is a string which controls how sprintf formats the name
        !           584:    we have generated.
        !           585: 
        !           586:    For example, given
        !           587: 
        !           588:        class A; class B; class C : A, B;
        !           589: 
        !           590:    it is possible to distinguish "A" from "C's A".  And given
        !           591: 
        !           592:        class L;
        !           593:        class A : L; class B : L; class C : A, B;
        !           594: 
        !           595:    it is possible to distinguish "L" from "A's L", and also from
        !           596:    "C's L from A".
        !           597: 
        !           598:    Make sure to use the DECL_ASSEMBLER_NAME of the TYPE_NAME of the
        !           599:    type, as template have DECL_NAMEs like: X<int>, whereas the
        !           600:    DECL_ASSEMBLER_NAME is set to be something the assembler can handle.
        !           601:   */
        !           602: static tree
        !           603: build_type_pathname (format, parent, type)
        !           604:      char *format;
        !           605:      tree parent, type;
        !           606: {
        !           607:   extern struct obstack temporary_obstack;
        !           608:   char *first, *base, *name;
        !           609:   int i;
        !           610:   tree id;
        !           611: 
        !           612:   parent = TYPE_MAIN_VARIANT (parent);
        !           613: 
        !           614:   /* Remember where to cut the obstack to.  */
        !           615:   first = obstack_base (&temporary_obstack);
        !           616: 
        !           617:   /* Put on TYPE+PARENT.  */
        !           618:   obstack_grow (&temporary_obstack,
        !           619:                TYPE_ASSEMBLER_NAME_STRING (type),
        !           620:                TYPE_ASSEMBLER_NAME_LENGTH (type));
        !           621: #ifdef JOINER
        !           622:   obstack_1grow (&temporary_obstack, JOINER);
        !           623: #else
        !           624:   obstack_1grow (&temporary_obstack, '_');
        !           625: #endif
        !           626:   obstack_grow0 (&temporary_obstack,
        !           627:                 TYPE_ASSEMBLER_NAME_STRING (parent),
        !           628:                 TYPE_ASSEMBLER_NAME_LENGTH (parent));
        !           629:   i = obstack_object_size (&temporary_obstack);
        !           630:   base = obstack_base (&temporary_obstack);
        !           631:   obstack_finish (&temporary_obstack);
        !           632: 
        !           633:   /* Put on FORMAT+TYPE+PARENT.  */
        !           634:   obstack_blank (&temporary_obstack, strlen (format) + i + 1);
        !           635:   name = obstack_base (&temporary_obstack);
        !           636:   sprintf (name, format, base);
        !           637:   id = get_identifier (name);
        !           638:   obstack_free (&temporary_obstack, first);
        !           639: 
        !           640:   return id;
        !           641: }
        !           642: 
        !           643: /* Give TYPE a new virtual function table which is initialized
        !           644:    with a skeleton-copy of its original initialization.  The only
        !           645:    entry that changes is the `delta' entry, so we can really
        !           646:    share a lot of structure.
        !           647: 
        !           648:    FOR_TYPE is the derived type which caused this table to
        !           649:    be needed.
        !           650: 
        !           651:    BINFO is the type association which provided TYPE for FOR_TYPE.  */
        !           652: static void
        !           653: prepare_fresh_vtable (binfo, for_type)
        !           654:      tree binfo, for_type;
        !           655: {
        !           656:   tree basetype = BINFO_TYPE (binfo);
        !           657:   tree orig_decl = BINFO_VTABLE (binfo);
        !           658:   /* This name is too simplistic.  We can have multiple basetypes for
        !           659:      for_type, and we really want different names.  (mrs) */
        !           660:   tree name = build_type_pathname (VTABLE_NAME_FORMAT, basetype, for_type);
        !           661:   tree new_decl = build_decl (VAR_DECL, name, TREE_TYPE (orig_decl));
        !           662:   tree path;
        !           663:   int result;
        !           664: 
        !           665:   /* Remember which class this vtable is really for.  */
        !           666:   DECL_CONTEXT (new_decl) = for_type;
        !           667: 
        !           668:   TREE_STATIC (new_decl) = 1;
        !           669:   BINFO_VTABLE (binfo) = pushdecl_top_level (new_decl);
        !           670:   DECL_VIRTUAL_P (new_decl) = 1;
        !           671: #ifndef WRITABLE_VTABLES
        !           672:   /* Make them READONLY by default. (mrs) */
        !           673:   TREE_READONLY (new_decl) = 1;
        !           674: #endif
        !           675:   DECL_ALIGN (new_decl) = DECL_ALIGN (orig_decl);
        !           676: 
        !           677:   /* Make fresh virtual list, so we can smash it later.  */
        !           678:   BINFO_VIRTUALS (binfo) = copy_list (BINFO_VIRTUALS (binfo));
        !           679:   /* Install the value for `headof' if that's what we're doing.  */
        !           680:   if (flag_dossier)
        !           681:     TREE_VALUE (TREE_CHAIN (BINFO_VIRTUALS (binfo)))
        !           682:       = build_vtable_entry (size_binop (MINUS_EXPR, integer_zero_node, BINFO_OFFSET (binfo)),
        !           683:                            FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (TREE_CHAIN (BINFO_VIRTUALS (binfo)))));
        !           684: 
        !           685: #ifdef GATHER_STATISTICS
        !           686:   n_vtables += 1;
        !           687:   n_vtable_elems += list_length (BINFO_VIRTUALS (binfo));
        !           688: #endif
        !           689: 
        !           690:   /* Set TREE_PUBLIC and TREE_EXTERN as appropriate.  */
        !           691:   if (! flag_vtable_thunks)
        !           692:     import_export_vtable (new_decl, for_type);
        !           693: 
        !           694:   if (TREE_VIA_VIRTUAL (binfo))
        !           695:     my_friendly_assert (binfo == binfo_member (BINFO_TYPE (binfo),
        !           696:                                   CLASSTYPE_VBASECLASSES (current_class_type)),
        !           697:                        170);
        !           698:   SET_BINFO_NEW_VTABLE_MARKED (binfo);
        !           699: }
        !           700: 
        !           701: /* Access the virtual function table entry that logically
        !           702:    contains BASE_FNDECL.  VIRTUALS is the virtual function table's
        !           703:    initializer.  We can run off the end, when dealing with virtual
        !           704:    destructors in MI situations, return NULL_TREE in that case.  */
        !           705: static tree
        !           706: get_vtable_entry (virtuals, base_fndecl)
        !           707:      tree virtuals, base_fndecl;
        !           708: {
        !           709:   unsigned HOST_WIDE_INT i = (HOST_BITS_PER_WIDE_INT >= BITS_PER_WORD
        !           710:           ? (TREE_INT_CST_LOW (DECL_VINDEX (base_fndecl))
        !           711:              & (((unsigned HOST_WIDE_INT)1<<(BITS_PER_WORD-1))-1))
        !           712:           : TREE_INT_CST_LOW (DECL_VINDEX (base_fndecl)));
        !           713: 
        !           714: #ifdef GATHER_STATISTICS
        !           715:   n_vtable_searches += i;
        !           716: #endif
        !           717: 
        !           718:   while (i > 0 && virtuals)
        !           719:     {
        !           720:       virtuals = TREE_CHAIN (virtuals);
        !           721:       i -= 1;
        !           722:     }
        !           723:   return virtuals;
        !           724: }
        !           725: 
        !           726: /* Put new entry ENTRY into virtual function table initializer
        !           727:    VIRTUALS.
        !           728: 
        !           729:    Also update DECL_VINDEX (FNDECL).  */
        !           730: 
        !           731: static void
        !           732: modify_vtable_entry (old_entry_in_list, new_entry, fndecl)
        !           733:      tree old_entry_in_list, new_entry, fndecl;
        !           734: {
        !           735:   tree base_fndecl = TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (old_entry_in_list)), 0);
        !           736: 
        !           737: #ifdef NOTQUITE
        !           738:   cp_warning ("replaced %D with %D", DECL_ASSEMBLER_NAME (base_fndecl),
        !           739:              DECL_ASSEMBLER_NAME (fndecl));
        !           740: #endif
        !           741:   TREE_VALUE (old_entry_in_list) = new_entry;
        !           742: 
        !           743:   /* Now assign virtual dispatch information, if unset.  */
        !           744:   /* We can dispatch this, through any overridden base function. */
        !           745:   if (TREE_CODE (DECL_VINDEX (fndecl)) != INTEGER_CST)
        !           746:     {
        !           747:       DECL_VINDEX (fndecl) = DECL_VINDEX (base_fndecl);
        !           748:       DECL_CONTEXT (fndecl) = DECL_CONTEXT (base_fndecl);
        !           749:     }
        !           750: }
        !           751: 
        !           752: /* Access the virtual function table entry i.  VIRTUALS is the virtual
        !           753:    function table's initializer.  */
        !           754: static tree
        !           755: get_vtable_entry_n (virtuals, i)
        !           756:      tree virtuals;
        !           757:      unsigned HOST_WIDE_INT i;
        !           758: {
        !           759:   while (i > 0)
        !           760:     {
        !           761:       virtuals = TREE_CHAIN (virtuals);
        !           762:       i -= 1;
        !           763:     }
        !           764:   return virtuals;
        !           765: }
        !           766: 
        !           767: /* Add a virtual function to all the appropriate vtables for the class
        !           768:    T.  DECL_VINDEX(X) should be error_mark_node, if we want to
        !           769:    allocate a new slot in our table.  If it is error_mark_node, we
        !           770:    know that no other function from another vtable is overridden by X.
        !           771:    HAS_VIRTUAL keeps track of how many virtuals there are in our main
        !           772:    vtable for the type, and we build upon the PENDING_VIRTUALS list
        !           773:    and return it.  */
        !           774: static tree
        !           775: add_virtual_function (pending_virtuals, has_virtual, fndecl, t)
        !           776:      tree pending_virtuals;
        !           777:      int *has_virtual;
        !           778:      tree fndecl;
        !           779:      tree t; /* Structure type. */
        !           780: {
        !           781:   /* FUNCTION_TYPEs and OFFSET_TYPEs no longer freely
        !           782:      convert to void *.  Make such a conversion here.  */
        !           783:   tree vfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, fndecl);
        !           784:   TREE_CONSTANT (vfn) = 1;
        !           785: 
        !           786: #ifndef DUMB_USER
        !           787:   if (current_class_type == 0)
        !           788:     cp_warning ("internal problem, current_class_type is zero when adding `%D', please report",
        !           789:                fndecl);
        !           790:   if (current_class_type && t != current_class_type)
        !           791:     cp_warning ("internal problem, current_class_type differs when adding `%D', please report",
        !           792:                fndecl);
        !           793: #endif
        !           794: 
        !           795:   if (!flag_vtable_thunks)
        !           796:     TREE_ADDRESSABLE (fndecl) = CLASSTYPE_VTABLE_NEEDS_WRITING (t);
        !           797: 
        !           798:   /* If the virtual function is a redefinition of a prior one,
        !           799:      figure out in which base class the new definition goes,
        !           800:      and if necessary, make a fresh virtual function table
        !           801:      to hold that entry.  */
        !           802:   if (DECL_VINDEX (fndecl) == error_mark_node)
        !           803:     {
        !           804:       tree entry;
        !           805: 
        !           806:       if (flag_dossier && *has_virtual == 0)
        !           807:        {
        !           808:          /* CLASSTYPE_DOSSIER is only used as a Boolean (NULL or not). */
        !           809:          CLASSTYPE_DOSSIER (t) = integer_one_node;
        !           810:          *has_virtual = 1;
        !           811:         }
        !           812: 
        !           813:       /* Build a new INT_CST for this DECL_VINDEX.  */
        !           814:       {
        !           815:        static tree index_table[256];
        !           816:        tree index;
        !           817:        int i = ++(*has_virtual);
        !           818: 
        !           819:        if (i >= 256 || index_table[i] == 0)
        !           820:          {
        !           821:            index = build_int_2 (i, 0);
        !           822:            if (i < 256)
        !           823:              index_table[i] = index;
        !           824:          }
        !           825:        else
        !           826:          index = index_table[i];
        !           827: 
        !           828:        /* Now assign virtual dispatch information. */
        !           829:        DECL_VINDEX (fndecl) = index;
        !           830:        DECL_CONTEXT (fndecl) = t;
        !           831:       }
        !           832:       entry = build_vtable_entry (integer_zero_node, vfn);
        !           833:       pending_virtuals = tree_cons (DECL_VINDEX (fndecl), entry, pending_virtuals);
        !           834:     }
        !           835:   /* Might already be INTEGER_CST if declared twice in class.  We will
        !           836:      give error later or we've already given it.  */
        !           837:   else if (TREE_CODE (DECL_VINDEX (fndecl)) != INTEGER_CST)
        !           838:     {
        !           839:       /* Need an entry in some other virtual function table.
        !           840:          Deal with this after we have laid out our virtual base classes.  */
        !           841:       pending_hard_virtuals = temp_tree_cons (fndecl, vfn, pending_hard_virtuals);
        !           842:     }
        !           843:   return pending_virtuals;
        !           844: }
        !           845: 
        !           846: /* Obstack on which to build the vector of class methods.  */
        !           847: struct obstack class_obstack;
        !           848: extern struct obstack *current_obstack;
        !           849: 
        !           850: /* Add method METHOD to class TYPE.  This is used when a method
        !           851:    has been defined which did not initially appear in the class definition,
        !           852:    and helps cut down on spurious error messages.
        !           853: 
        !           854:    FIELDS is the entry in the METHOD_VEC vector entry of the class type where
        !           855:    the method should be added.  */
        !           856: void
        !           857: add_method (type, fields, method)
        !           858:      tree type, *fields, method;
        !           859: {
        !           860:   /* We must make a copy of METHOD here, since we must be sure that
        !           861:      we have exclusive title to this method's DECL_CHAIN.  */
        !           862:   tree decl;
        !           863: 
        !           864:   push_obstacks (&permanent_obstack, &permanent_obstack);
        !           865:   {
        !           866:     decl = copy_node (method);
        !           867:     if (DECL_RTL (decl) == 0
        !           868:         && (!processing_template_decl
        !           869:             || !uses_template_parms (decl)))
        !           870:       {
        !           871:        make_function_rtl (decl);
        !           872:        DECL_RTL (method) = DECL_RTL (decl);
        !           873:       }
        !           874:   }
        !           875: 
        !           876:   if (fields && *fields)
        !           877:     {
        !           878:       /* Take care not to hide destructor.  */
        !           879:       DECL_CHAIN (decl) = DECL_CHAIN (*fields);
        !           880:       DECL_CHAIN (*fields) = decl;
        !           881:     }
        !           882:   else if (CLASSTYPE_METHOD_VEC (type) == 0)
        !           883:     {
        !           884:       tree method_vec = make_node (TREE_VEC);
        !           885:       if (TYPE_IDENTIFIER (type) == DECL_NAME (decl))
        !           886:        {
        !           887:          TREE_VEC_ELT (method_vec, 0) = decl;
        !           888:          TREE_VEC_LENGTH (method_vec) = 1;
        !           889:        }
        !           890:       else
        !           891:        {
        !           892:          /* ??? Is it possible for there to have been enough room in the
        !           893:             current chunk for the tree_vec structure but not a tree_vec
        !           894:             plus a tree*?  Will this work in that case?  */
        !           895:          obstack_free (current_obstack, method_vec);
        !           896:          obstack_blank (current_obstack, sizeof (struct tree_vec) + sizeof (tree *));
        !           897:          TREE_VEC_ELT (method_vec, 1) = decl;
        !           898:          TREE_VEC_LENGTH (method_vec) = 2;
        !           899:          obstack_finish (current_obstack);
        !           900:        }
        !           901:       CLASSTYPE_METHOD_VEC (type) = method_vec;
        !           902:     }
        !           903:   else
        !           904:     {
        !           905:       tree method_vec = CLASSTYPE_METHOD_VEC (type);
        !           906:       int len = TREE_VEC_LENGTH (method_vec);
        !           907: 
        !           908:       /* Adding a new ctor or dtor.  This is easy because our
        !           909:          METHOD_VEC always has a slot for such entries.  */
        !           910:       if (TYPE_IDENTIFIER (type) == DECL_NAME (decl))
        !           911:        {
        !           912:          /* TREE_VEC_ELT (method_vec, 0) = decl; */
        !           913:          if (decl != TREE_VEC_ELT (method_vec, 0))
        !           914:            {
        !           915:              DECL_CHAIN (decl) = TREE_VEC_ELT (method_vec, 0);
        !           916:              TREE_VEC_ELT (method_vec, 0) = decl;
        !           917:            }
        !           918:        }
        !           919:       else
        !           920:        {
        !           921:          /* This is trickier.  We try to extend the TREE_VEC in-place,
        !           922:             but if that does not work, we copy all its data to a new
        !           923:             TREE_VEC that's large enough.  */
        !           924:          struct obstack *ob = &class_obstack;
        !           925:          tree *end = (tree *)obstack_next_free (ob);
        !           926: 
        !           927:          if (end != TREE_VEC_END (method_vec))
        !           928:            {
        !           929:              ob = current_obstack;
        !           930:              TREE_VEC_LENGTH (method_vec) += 1;
        !           931:              TREE_VEC_ELT (method_vec, len) = NULL_TREE;
        !           932:              method_vec = copy_node (method_vec);
        !           933:              TREE_VEC_LENGTH (method_vec) -= 1;
        !           934:            }
        !           935:          else
        !           936:            {
        !           937:              tree tmp_vec = (tree) obstack_base (ob);
        !           938:              if (obstack_room (ob) < sizeof (tree))
        !           939:                {
        !           940:                  obstack_blank (ob, sizeof (struct tree_common)
        !           941:                                 + tree_code_length[(int) TREE_VEC]
        !           942:                                   * sizeof (char *)
        !           943:                                 + len * sizeof (tree));
        !           944:                  tmp_vec = (tree) obstack_base (ob);
        !           945:                  bcopy ((char *) method_vec, (char *) tmp_vec,
        !           946:                         (sizeof (struct tree_common)
        !           947:                          + tree_code_length[(int) TREE_VEC] * sizeof (char *)
        !           948:                          + (len-1) * sizeof (tree)));
        !           949:                  method_vec = tmp_vec;
        !           950:                }
        !           951:              else
        !           952:                obstack_blank (ob, sizeof (tree));
        !           953:            }
        !           954: 
        !           955:          obstack_finish (ob);
        !           956:          TREE_VEC_ELT (method_vec, len) = decl;
        !           957:          TREE_VEC_LENGTH (method_vec) = len + 1;
        !           958:          CLASSTYPE_METHOD_VEC (type) = method_vec;
        !           959: 
        !           960:          if (TYPE_BINFO_BASETYPES (type) && CLASSTYPE_BASELINK_VEC (type))
        !           961:            {
        !           962:              /* ??? May be better to know whether these can be extended?  */
        !           963:              tree baselink_vec = CLASSTYPE_BASELINK_VEC (type);
        !           964: 
        !           965:              TREE_VEC_LENGTH (baselink_vec) += 1;
        !           966:              CLASSTYPE_BASELINK_VEC (type) = copy_node (baselink_vec);
        !           967:              TREE_VEC_LENGTH (baselink_vec) -= 1;
        !           968: 
        !           969:              TREE_VEC_ELT (CLASSTYPE_BASELINK_VEC (type), len) = 0;
        !           970:            }
        !           971:        }
        !           972:     }
        !           973:   DECL_CONTEXT (decl) = type;
        !           974:   DECL_CLASS_CONTEXT (decl) = type;
        !           975: 
        !           976:   pop_obstacks ();
        !           977: }
        !           978: 
        !           979: /* Subroutines of finish_struct.  */
        !           980: 
        !           981: /* Look through the list of fields for this struct, deleting
        !           982:    duplicates as we go.  This must be recursive to handle
        !           983:    anonymous unions.
        !           984: 
        !           985:    FIELD is the field which may not appear anywhere in FIELDS.
        !           986:    FIELD_PTR, if non-null, is the starting point at which
        !           987:    chained deletions may take place.
        !           988:    The value returned is the first acceptable entry found
        !           989:    in FIELDS.
        !           990: 
        !           991:    Note that anonymous fields which are not of UNION_TYPE are
        !           992:    not duplicates, they are just anonymous fields.  This happens
        !           993:    when we have unnamed bitfields, for example.  */
        !           994: static tree
        !           995: delete_duplicate_fields_1 (field, fields)
        !           996:      tree field, fields;
        !           997: {
        !           998:   tree x;
        !           999:   tree prev = 0;
        !          1000:   if (DECL_NAME (field) == 0)
        !          1001:     {
        !          1002:       if (TREE_CODE (TREE_TYPE (field)) != UNION_TYPE)
        !          1003:        return fields;
        !          1004: 
        !          1005:       for (x = TYPE_FIELDS (TREE_TYPE (field)); x; x = TREE_CHAIN (x))
        !          1006:        fields = delete_duplicate_fields_1 (x, fields);
        !          1007:       return fields;
        !          1008:     }
        !          1009:   else
        !          1010:     {
        !          1011:       for (x = fields; x; prev = x, x = TREE_CHAIN (x))
        !          1012:        {
        !          1013:          if (DECL_NAME (x) == 0)
        !          1014:            {
        !          1015:              if (TREE_CODE (TREE_TYPE (x)) != UNION_TYPE)
        !          1016:                continue;
        !          1017:              TYPE_FIELDS (TREE_TYPE (x))
        !          1018:                = delete_duplicate_fields_1 (field, TYPE_FIELDS (TREE_TYPE (x)));
        !          1019:              if (TYPE_FIELDS (TREE_TYPE (x)) == 0)
        !          1020:                {
        !          1021:                  if (prev == 0)
        !          1022:                    fields = TREE_CHAIN (fields);
        !          1023:                  else
        !          1024:                    TREE_CHAIN (prev) = TREE_CHAIN (x);
        !          1025:                }
        !          1026:            }
        !          1027:          else
        !          1028:            {
        !          1029:              if (DECL_NAME (field) == DECL_NAME (x))
        !          1030:                {
        !          1031:                  if (TREE_CODE (field) == CONST_DECL
        !          1032:                      && TREE_CODE (x) == CONST_DECL)
        !          1033:                    cp_error_at ("duplicate enum value `%D'", x);
        !          1034:                  else if (TREE_CODE (field) == CONST_DECL
        !          1035:                           || TREE_CODE (x) == CONST_DECL)
        !          1036:                    cp_error_at ("duplicate field `%D' (as enum and non-enum)",
        !          1037:                                x);
        !          1038:                  else if (TREE_CODE (field) == TYPE_DECL
        !          1039:                           && TREE_CODE (x) == TYPE_DECL)
        !          1040:                    cp_error_at ("duplicate nested type `%D'", x);
        !          1041:                  else if (TREE_CODE (field) == TYPE_DECL
        !          1042:                           || TREE_CODE (x) == TYPE_DECL)
        !          1043:                    cp_error_at ("duplicate field `%D' (as type and non-type)",
        !          1044:                                x);
        !          1045:                  else
        !          1046:                    cp_error_at ("duplicate member `%D'", x);
        !          1047:                  if (prev == 0)
        !          1048:                    fields = TREE_CHAIN (fields);
        !          1049:                  else
        !          1050:                    TREE_CHAIN (prev) = TREE_CHAIN (x);
        !          1051:                }
        !          1052:            }
        !          1053:        }
        !          1054:     }
        !          1055:   return fields;
        !          1056: }
        !          1057: 
        !          1058: static void
        !          1059: delete_duplicate_fields (fields)
        !          1060:      tree fields;
        !          1061: {
        !          1062:   tree x;
        !          1063:   for (x = fields; x && TREE_CHAIN (x); x = TREE_CHAIN (x))
        !          1064:     TREE_CHAIN (x) = delete_duplicate_fields_1 (x, TREE_CHAIN (x));
        !          1065: }
        !          1066: 
        !          1067: /* Change the access of FDECL to ACCESS in T.
        !          1068:    Return 1 if change was legit, otherwise return 0.  */
        !          1069: static int
        !          1070: alter_access (t, fdecl, access)
        !          1071:      tree t;
        !          1072:      tree fdecl;
        !          1073:      enum access_type access;
        !          1074: {
        !          1075:   tree elem = purpose_member (t, DECL_ACCESS (fdecl));
        !          1076:   if (elem && TREE_VALUE (elem) != (tree)access)
        !          1077:     {
        !          1078:       if (TREE_CODE (TREE_TYPE (fdecl)) == FUNCTION_DECL)
        !          1079:        {
        !          1080:          cp_error_at ("conflicting access specifications for method `%D', ignored", TREE_TYPE (fdecl));
        !          1081:        }
        !          1082:       else
        !          1083:        error ("conflicting access specifications for field `%s', ignored",
        !          1084:               IDENTIFIER_POINTER (DECL_NAME (fdecl)));
        !          1085:     }
        !          1086:   else if (TREE_PRIVATE (fdecl) && access != access_private)
        !          1087:     cp_error_at ("cannot make private `%D' non-private", fdecl);
        !          1088:   else if (TREE_PROTECTED (fdecl))
        !          1089:     {
        !          1090:       if (access == access_public)
        !          1091:        cp_error_at ("cannot make protected `%D' public", fdecl);
        !          1092:       goto alter;
        !          1093:     }
        !          1094:   /* ARM 11.3: an access declaration may not be used to restrict access
        !          1095:      to a member that is accessible in the base class.  */
        !          1096:   else if (TREE_PUBLIC (fdecl)
        !          1097:           && (access == access_private
        !          1098:               || access == access_protected))
        !          1099:     cp_error_at ("cannot reduce access of public member `%D'", fdecl);
        !          1100:   else if (elem == NULL_TREE)
        !          1101:     {
        !          1102:     alter:
        !          1103:       DECL_ACCESS (fdecl) = tree_cons (t, (tree)access,
        !          1104:                                           DECL_ACCESS (fdecl));
        !          1105:       return 1;
        !          1106:     }
        !          1107:   return 0;
        !          1108: }
        !          1109: 
        !          1110: /* Return the offset to the main vtable for a given base BINFO.  */
        !          1111: tree
        !          1112: get_vfield_offset (binfo)
        !          1113:      tree binfo;
        !          1114: {
        !          1115:   return size_binop (PLUS_EXPR,
        !          1116:                     size_binop (FLOOR_DIV_EXPR,
        !          1117:                                 DECL_FIELD_BITPOS (CLASSTYPE_VFIELD (BINFO_TYPE (binfo))),
        !          1118:                                 size_int (BITS_PER_UNIT)),
        !          1119:                     BINFO_OFFSET (binfo));
        !          1120: }
        !          1121: 
        !          1122: /* Get the offset to the start of the original binfo that we derived
        !          1123:    this binfo from.  If we find TYPE first, return the offset only
        !          1124:    that far.  The shortened search is useful because the this pointer
        !          1125:    on method calling is expected to point to a DECL_CONTEXT (fndecl)
        !          1126:    object, and not a baseclass of it.  */
        !          1127: static tree
        !          1128: get_derived_offset (binfo, type)
        !          1129:      tree binfo, type;
        !          1130: {
        !          1131:   tree offset1 = get_vfield_offset (TYPE_BINFO (BINFO_TYPE (binfo)));
        !          1132:   tree offset2;
        !          1133:   int i;
        !          1134:   while (BINFO_BASETYPES (binfo)
        !          1135:         && (i=CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo))) != -1)
        !          1136:     {
        !          1137:       tree binfos = BINFO_BASETYPES (binfo);
        !          1138:       if (BINFO_TYPE (binfo) == type)
        !          1139:        break;
        !          1140:       binfo = TREE_VEC_ELT (binfos, i);
        !          1141:     }
        !          1142:   offset2 = get_vfield_offset (TYPE_BINFO (BINFO_TYPE (binfo)));
        !          1143:   return size_binop (MINUS_EXPR, offset1, offset2);
        !          1144: }
        !          1145: 
        !          1146: /* If FOR_TYPE needs to reinitialize virtual function table pointers
        !          1147:    for TYPE's sub-objects, add such reinitializations to BASE_INIT_LIST.
        !          1148:    Returns BASE_INIT_LIST appropriately modified.  */
        !          1149: 
        !          1150: static tree
        !          1151: maybe_fixup_vptrs (for_type, binfo, base_init_list)
        !          1152:      tree for_type, binfo, base_init_list;
        !          1153: {
        !          1154:   /* Now reinitialize any slots that don't fall under our virtual
        !          1155:      function table pointer.  */
        !          1156:   tree vfields = CLASSTYPE_VFIELDS (BINFO_TYPE (binfo));
        !          1157:   while (vfields)
        !          1158:     {
        !          1159:       tree basetype = VF_NORMAL_VALUE (vfields)
        !          1160:        ? TYPE_MAIN_VARIANT (VF_NORMAL_VALUE (vfields))
        !          1161:          : VF_BASETYPE_VALUE (vfields);
        !          1162: 
        !          1163:       tree base_binfo = get_binfo (basetype, for_type, 0);
        !          1164:       /* Punt until this is implemented. */
        !          1165:       if (1 /* BINFO_MODIFIED (base_binfo) */)
        !          1166:        {
        !          1167:          tree base_offset = get_vfield_offset (base_binfo);
        !          1168:          if (! tree_int_cst_equal (base_offset, get_vfield_offset (TYPE_BINFO (for_type)))
        !          1169:              && ! tree_int_cst_equal (base_offset, get_vfield_offset (binfo)))
        !          1170:            base_init_list = tree_cons (error_mark_node, base_binfo,
        !          1171:                                        base_init_list);
        !          1172:        }
        !          1173:       vfields = TREE_CHAIN (vfields);
        !          1174:     }
        !          1175:   return base_init_list;
        !          1176: }
        !          1177: 
        !          1178: /* If TYPE does not have a constructor, then the compiler must
        !          1179:    manually deal with all of the initialization this type requires.
        !          1180: 
        !          1181:    If a base initializer exists only to fill in the virtual function
        !          1182:    table pointer, then we mark that fact with the TREE_VIRTUAL bit.
        !          1183:    This way, we avoid multiple initializations of the same field by
        !          1184:    each virtual function table up the class hierarchy.
        !          1185: 
        !          1186:    Virtual base class pointers are not initialized here.  They are
        !          1187:    initialized only at the "top level" of object creation.  If we
        !          1188:    initialized them here, we would have to skip a lot of work.  */
        !          1189: 
        !          1190: static void
        !          1191: build_class_init_list (type)
        !          1192:      tree type;
        !          1193: {
        !          1194:   tree base_init_list = NULL_TREE;
        !          1195:   tree member_init_list = NULL_TREE;
        !          1196: 
        !          1197:   /* Since we build member_init_list and base_init_list using
        !          1198:      tree_cons, backwards fields the all through work.  */
        !          1199:   tree x;
        !          1200:   tree binfos = BINFO_BASETYPES (TYPE_BINFO (type));
        !          1201:   int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
        !          1202: 
        !          1203:   for (x = TYPE_FIELDS (type); x; x = TREE_CHAIN (x))
        !          1204:     {
        !          1205:       if (TREE_CODE (x) != FIELD_DECL)
        !          1206:        continue;
        !          1207: 
        !          1208:       if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (x))
        !          1209:          || DECL_INITIAL (x) != NULL_TREE)
        !          1210:        member_init_list = tree_cons (x, type, member_init_list);
        !          1211:     }
        !          1212:   member_init_list = nreverse (member_init_list);
        !          1213: 
        !          1214:   /* We will end up doing this last.  Need special marker
        !          1215:      to avoid infinite regress.  */
        !          1216:   if (TYPE_VIRTUAL_P (type))
        !          1217:     {
        !          1218:       base_init_list = build_tree_list (error_mark_node, TYPE_BINFO (type));
        !          1219:       if (CLASSTYPE_NEEDS_VIRTUAL_REINIT (type) == 0)
        !          1220:        TREE_VALUE (base_init_list) = NULL_TREE;
        !          1221:       TREE_ADDRESSABLE (base_init_list) = 1;
        !          1222:     }
        !          1223: 
        !          1224:   /* Each base class which needs to have initialization
        !          1225:      of some kind gets to make such requests known here.  */
        !          1226:   for (i = n_baseclasses-1; i >= 0; i--)
        !          1227:     {
        !          1228:       tree base_binfo = TREE_VEC_ELT (binfos, i);
        !          1229:       tree blist;
        !          1230: 
        !          1231:       /* Don't initialize virtual baseclasses this way.  */
        !          1232:       if (TREE_VIA_VIRTUAL (base_binfo))
        !          1233:        continue;
        !          1234: 
        !          1235:       if (TYPE_HAS_CONSTRUCTOR (BINFO_TYPE (base_binfo)))
        !          1236:        {
        !          1237:          /* ...and the last shall come first...  */
        !          1238:          base_init_list = maybe_fixup_vptrs (type, base_binfo, base_init_list);
        !          1239:          base_init_list = tree_cons (NULL_TREE, base_binfo, base_init_list);
        !          1240:          continue;
        !          1241:        }
        !          1242: 
        !          1243:       if ((blist = CLASSTYPE_BASE_INIT_LIST (BINFO_TYPE (base_binfo))) == NULL_TREE)
        !          1244:        /* Nothing to initialize.  */
        !          1245:        continue;
        !          1246: 
        !          1247:       /* ...ditto...  */
        !          1248:       base_init_list = maybe_fixup_vptrs (type, base_binfo, base_init_list);
        !          1249: 
        !          1250:       /* This is normally true for single inheritance.
        !          1251:         The win is we can shrink the chain of initializations
        !          1252:         to be done by only converting to the actual type
        !          1253:         we are interested in.  */
        !          1254:       if (TREE_VALUE (blist)
        !          1255:          && TREE_CODE (TREE_VALUE (blist)) == TREE_VEC
        !          1256:          && tree_int_cst_equal (BINFO_OFFSET (base_binfo),
        !          1257:                                 BINFO_OFFSET (TREE_VALUE (blist))))
        !          1258:        {
        !          1259:          if (base_init_list)
        !          1260:            {
        !          1261:              /* Does it do more than just fill in a
        !          1262:                 virtual function table pointer?  */
        !          1263:              if (! TREE_ADDRESSABLE (blist))
        !          1264:                base_init_list = build_tree_list (blist, base_init_list);
        !          1265:              /* Can we get by just with the virtual function table
        !          1266:                 pointer that it fills in?  */
        !          1267:              else if (TREE_ADDRESSABLE (base_init_list)
        !          1268:                       && TREE_VALUE (base_init_list) == 0)
        !          1269:                base_init_list = blist;
        !          1270:              /* Maybe, but it is not obvious as the previous case.  */
        !          1271:              else if (! CLASSTYPE_NEEDS_VIRTUAL_REINIT (type))
        !          1272:                {
        !          1273:                  tree last = tree_last (base_init_list);
        !          1274:                  while (TREE_VALUE (last)
        !          1275:                         && TREE_CODE (TREE_VALUE (last)) == TREE_LIST)
        !          1276:                    last = tree_last (TREE_VALUE (last));
        !          1277:                  if (TREE_VALUE (last) == 0)
        !          1278:                    base_init_list = build_tree_list (blist, base_init_list);
        !          1279:                }
        !          1280:            }
        !          1281:          else
        !          1282:            base_init_list = blist;
        !          1283:        }
        !          1284:       else
        !          1285:        {
        !          1286:          /* The function expand_aggr_init knows how to do the
        !          1287:             initialization of `basetype' without getting
        !          1288:             an explicit `blist'.  */
        !          1289:          if (base_init_list)
        !          1290:            base_init_list = tree_cons (NULL_TREE, base_binfo, base_init_list);
        !          1291:          else
        !          1292:            base_init_list = CLASSTYPE_BINFO_AS_LIST (BINFO_TYPE (base_binfo));
        !          1293:        }
        !          1294:     }
        !          1295: 
        !          1296:   if (base_init_list)
        !          1297:     if (member_init_list)
        !          1298:       CLASSTYPE_BASE_INIT_LIST (type) = build_tree_list (base_init_list, member_init_list);
        !          1299:     else
        !          1300:       CLASSTYPE_BASE_INIT_LIST (type) = base_init_list;
        !          1301:   else if (member_init_list)
        !          1302:     CLASSTYPE_BASE_INIT_LIST (type) = member_init_list;
        !          1303: }
        !          1304: 
        !          1305: struct base_info
        !          1306: {
        !          1307:   int has_virtual;
        !          1308:   int max_has_virtual;
        !          1309:   int n_ancestors;
        !          1310:   tree vfield;
        !          1311:   tree vfields;
        !          1312:   char cant_have_default_ctor;
        !          1313:   char cant_have_const_ctor;
        !          1314:   char cant_synth_copy_ctor;
        !          1315:   char cant_synth_asn_ref;
        !          1316:   char no_const_asn_ref;
        !          1317:   char needs_virtual_dtor;
        !          1318: };
        !          1319: 
        !          1320: /* Record information about type T derived from its base classes.
        !          1321:    Store most of that information in T itself, and place the
        !          1322:    remaining information in the struct BASE_INFO.
        !          1323: 
        !          1324:    Propagate basetype offsets throughout the lattice.  Note that the
        !          1325:    lattice topped by T is really a pair: it's a DAG that gives the
        !          1326:    structure of the derivation hierarchy, and it's a list of the
        !          1327:    virtual baseclasses that appear anywhere in the DAG.  When a vbase
        !          1328:    type appears in the DAG, it's offset is 0, and it's children start
        !          1329:    their offsets from that point.  When a vbase type appears in the list,
        !          1330:    its offset is the offset it has in the hierarchy, and its children's
        !          1331:    offsets include that offset in theirs.
        !          1332: 
        !          1333:    Returns the index of the first base class to have virtual functions,
        !          1334:    or -1 if no such base class.
        !          1335: 
        !          1336:    Note that at this point TYPE_BINFO (t) != t_binfo.  */
        !          1337: 
        !          1338: static int
        !          1339: finish_base_struct (t, b, t_binfo)
        !          1340:      tree t;
        !          1341:      struct base_info *b;
        !          1342:      tree t_binfo;
        !          1343: {
        !          1344:   tree binfos = BINFO_BASETYPES (t_binfo);
        !          1345:   int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
        !          1346:   int first_vfn_base_index = -1;
        !          1347:   bzero ((char *) b, sizeof (struct base_info));
        !          1348: 
        !          1349:   for (i = 0; i < n_baseclasses; i++)
        !          1350:     {
        !          1351:       tree base_binfo = TREE_VEC_ELT (binfos, i);
        !          1352:       tree basetype = BINFO_TYPE (base_binfo);
        !          1353: 
        !          1354:       /* If the type of basetype is incomplete, then
        !          1355:         we already complained about that fact
        !          1356:         (and we should have fixed it up as well).  */
        !          1357:       if (TYPE_SIZE (basetype) == 0)
        !          1358:        {
        !          1359:          int j;
        !          1360:          /* The base type is of incomplete type.  It is
        !          1361:             probably best to pretend that it does not
        !          1362:             exist.  */
        !          1363:          if (i == n_baseclasses-1)
        !          1364:            TREE_VEC_ELT (binfos, i) = NULL_TREE;
        !          1365:          TREE_VEC_LENGTH (binfos) -= 1;
        !          1366:          n_baseclasses -= 1;
        !          1367:          for (j = i; j+1 < n_baseclasses; j++)
        !          1368:            TREE_VEC_ELT (binfos, j) = TREE_VEC_ELT (binfos, j+1);
        !          1369:        }
        !          1370: 
        !          1371:       if (TYPE_HAS_INIT_REF (basetype)
        !          1372:          && !TYPE_HAS_CONST_INIT_REF (basetype))
        !          1373:        b->cant_have_const_ctor = 1;
        !          1374:       if (! TYPE_HAS_INIT_REF (basetype)
        !          1375:          || (TYPE_HAS_NONPUBLIC_CTOR (basetype) == 2
        !          1376:              && ! is_friend_type (t, basetype)))
        !          1377:        b->cant_synth_copy_ctor = 1;
        !          1378: 
        !          1379:       if (TYPE_HAS_CONSTRUCTOR (basetype)
        !          1380:          && ! TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype))
        !          1381:        {
        !          1382:          b->cant_have_default_ctor = 1;
        !          1383:          if (! TYPE_HAS_CONSTRUCTOR (t))
        !          1384:            {
        !          1385:              cp_pedwarn ("base `%T' with only non-default constructor",
        !          1386:                          basetype);
        !          1387:              cp_pedwarn ("in class without a constructor");
        !          1388:            }
        !          1389:        }
        !          1390: 
        !          1391:       if (TYPE_HAS_ASSIGN_REF (basetype)
        !          1392:          && !TYPE_HAS_CONST_ASSIGN_REF (basetype))
        !          1393:        b->no_const_asn_ref = 1;
        !          1394:       if (! TYPE_HAS_ASSIGN_REF (basetype)
        !          1395:          || TYPE_HAS_ABSTRACT_ASSIGN_REF (basetype)
        !          1396:          || (TYPE_HAS_NONPUBLIC_ASSIGN_REF (basetype) == 2
        !          1397:              && ! is_friend_type (t, basetype)))
        !          1398:        b->cant_synth_asn_ref = 1;
        !          1399: 
        !          1400:       b->n_ancestors += CLASSTYPE_N_SUPERCLASSES (basetype);
        !          1401:       TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (basetype);
        !          1402:       TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_NEEDS_DESTRUCTOR (basetype);
        !          1403:       TYPE_HAS_COMPLEX_ASSIGN_REF (t) |= TYPE_HAS_COMPLEX_ASSIGN_REF (basetype);
        !          1404:       TYPE_HAS_COMPLEX_INIT_REF (t) |= (TYPE_HAS_COMPLEX_INIT_REF (basetype)
        !          1405:                                        || TYPE_NEEDS_CONSTRUCTING (basetype));
        !          1406: 
        !          1407:       TYPE_OVERLOADS_CALL_EXPR (t) |= TYPE_OVERLOADS_CALL_EXPR (basetype);
        !          1408:       TYPE_OVERLOADS_ARRAY_REF (t) |= TYPE_OVERLOADS_ARRAY_REF (basetype);
        !          1409:       TYPE_OVERLOADS_ARROW (t) |= TYPE_OVERLOADS_ARROW (basetype);
        !          1410: 
        !          1411:       if (! TREE_VIA_VIRTUAL (base_binfo)
        !          1412: #if 0
        !          1413:          /* This cannot be done, as prepare_fresh_vtable wants to modify
        !          1414:             binfos associated with vfields anywhere in the hierarchy, not
        !          1415:             just immediate base classes.  Due to unsharing, the compiler
        !          1416:             might consume 3% more memory on a real program.
        !          1417:             */
        !          1418:          && ! BINFO_OFFSET_ZEROP (base_binfo)
        !          1419: #endif
        !          1420:          && BINFO_BASETYPES (base_binfo))
        !          1421:        {
        !          1422:          tree base_binfos = BINFO_BASETYPES (base_binfo);
        !          1423:          tree chain = NULL_TREE;
        !          1424:          int j;
        !          1425: 
        !          1426:          /* Now unshare the structure beneath BASE_BINFO.  */
        !          1427:          for (j = TREE_VEC_LENGTH (base_binfos)-1;
        !          1428:               j >= 0; j--)
        !          1429:            {
        !          1430:              tree base_base_binfo = TREE_VEC_ELT (base_binfos, j);
        !          1431:              if (! TREE_VIA_VIRTUAL (base_base_binfo))
        !          1432:                TREE_VEC_ELT (base_binfos, j)
        !          1433:                  = make_binfo (BINFO_OFFSET (base_base_binfo),
        !          1434:                                base_base_binfo,
        !          1435:                                BINFO_VTABLE (base_base_binfo),
        !          1436:                                BINFO_VIRTUALS (base_base_binfo),
        !          1437:                                chain);
        !          1438:              chain = TREE_VEC_ELT (base_binfos, j);
        !          1439:              TREE_VIA_PUBLIC (chain) = TREE_VIA_PUBLIC (base_base_binfo);
        !          1440:              TREE_VIA_PROTECTED (chain) = TREE_VIA_PROTECTED (base_base_binfo);
        !          1441:            }
        !          1442: 
        !          1443:          /* Completely unshare potentially shared data, and
        !          1444:             update what is ours.  */
        !          1445:          propagate_binfo_offsets (base_binfo, BINFO_OFFSET (base_binfo));
        !          1446:        }
        !          1447: 
        !          1448:       if (! TREE_VIA_VIRTUAL (base_binfo))
        !          1449:        CLASSTYPE_N_SUPERCLASSES (t) += 1;
        !          1450: 
        !          1451:       if (TYPE_VIRTUAL_P (basetype))
        !          1452:        {
        !          1453:          /* If there's going to be a destructor needed, make
        !          1454:             sure it will be virtual.  */
        !          1455:          b->needs_virtual_dtor = 1;
        !          1456: 
        !          1457:          /* Don't borrow virtuals from virtual baseclasses.  */
        !          1458:          if (TREE_VIA_VIRTUAL (base_binfo))
        !          1459:            continue;
        !          1460: 
        !          1461:          if (first_vfn_base_index < 0)
        !          1462:            {
        !          1463:              tree vfields;
        !          1464:              first_vfn_base_index = i;
        !          1465: 
        !          1466:              /* Update these two, now that we know what vtable we are
        !          1467:                 going to extend.  This is so that we can add virtual
        !          1468:                 functions, and override them properly.  */
        !          1469:              BINFO_VTABLE (t_binfo) = TYPE_BINFO_VTABLE (basetype);
        !          1470:              BINFO_VIRTUALS (t_binfo) = TYPE_BINFO_VIRTUALS (basetype);
        !          1471:              b->has_virtual = CLASSTYPE_VSIZE (basetype);
        !          1472:              b->vfield = CLASSTYPE_VFIELD (basetype);
        !          1473:              b->vfields = copy_list (CLASSTYPE_VFIELDS (basetype));
        !          1474:              vfields = b->vfields;
        !          1475:              while (vfields)
        !          1476:                {
        !          1477:                  if (VF_BINFO_VALUE (vfields) == NULL_TREE
        !          1478:                      || ! TREE_VIA_VIRTUAL (VF_BINFO_VALUE (vfields)))
        !          1479:                    {
        !          1480:                      tree value = VF_BASETYPE_VALUE (vfields);
        !          1481:                      if (DECL_NAME (CLASSTYPE_VFIELD (value))
        !          1482:                          == DECL_NAME (CLASSTYPE_VFIELD (basetype)))
        !          1483:                        VF_NORMAL_VALUE (b->vfields) = basetype;
        !          1484:                      else
        !          1485:                        VF_NORMAL_VALUE (b->vfields) = VF_NORMAL_VALUE (vfields);
        !          1486:                    }
        !          1487:                  vfields = TREE_CHAIN (vfields);
        !          1488:                }
        !          1489:              CLASSTYPE_VFIELD (t) = b->vfield;
        !          1490:            }
        !          1491:          else
        !          1492:            {
        !          1493:              /* Only add unique vfields, and flatten them out as we go.  */
        !          1494:              tree vfields = CLASSTYPE_VFIELDS (basetype);
        !          1495:              while (vfields)
        !          1496:                {
        !          1497:                  if (VF_BINFO_VALUE (vfields) == NULL_TREE
        !          1498:                      || ! TREE_VIA_VIRTUAL (VF_BINFO_VALUE (vfields)))
        !          1499:                    {
        !          1500:                      tree value = VF_BASETYPE_VALUE (vfields);
        !          1501:                      b->vfields = tree_cons (base_binfo, value, b->vfields);
        !          1502:                      if (DECL_NAME (CLASSTYPE_VFIELD (value))
        !          1503:                          == DECL_NAME (CLASSTYPE_VFIELD (basetype)))
        !          1504:                        VF_NORMAL_VALUE (b->vfields) = basetype;
        !          1505:                      else
        !          1506:                        VF_NORMAL_VALUE (b->vfields) = VF_NORMAL_VALUE (vfields);
        !          1507:                    }
        !          1508:                  vfields = TREE_CHAIN (vfields);
        !          1509:                }
        !          1510: 
        !          1511:              if (b->has_virtual == 0)
        !          1512:                {
        !          1513:                  first_vfn_base_index = i;
        !          1514: 
        !          1515:                  /* Update these two, now that we know what vtable we are
        !          1516:                     going to extend.  This is so that we can add virtual
        !          1517:                     functions, and override them properly.  */
        !          1518:                  BINFO_VTABLE (t_binfo) = TYPE_BINFO_VTABLE (basetype);
        !          1519:                  BINFO_VIRTUALS (t_binfo) = TYPE_BINFO_VIRTUALS (basetype);
        !          1520:                  b->has_virtual = CLASSTYPE_VSIZE (basetype);
        !          1521:                  b->vfield = CLASSTYPE_VFIELD (basetype);
        !          1522:                  CLASSTYPE_VFIELD (t) = b->vfield;
        !          1523:                  /* When we install the first one, set the VF_NORMAL_VALUE
        !          1524:                     to be the current class, as this it is the most derived
        !          1525:                     class.  Hopefully, this is not set to something else
        !          1526:                     later.  (mrs) */
        !          1527:                  vfields = b->vfields;
        !          1528:                  while (vfields)
        !          1529:                    {
        !          1530:                      if (DECL_NAME (CLASSTYPE_VFIELD (t))
        !          1531:                          == DECL_NAME (CLASSTYPE_VFIELD (basetype)))
        !          1532:                        {
        !          1533:                          VF_NORMAL_VALUE (vfields) = t;
        !          1534:                          /* There should only be one of them!  And it should
        !          1535:                             always be found, if we get into here.  (mrs)  */
        !          1536:                          break;
        !          1537:                        }
        !          1538:                      vfields = TREE_CHAIN (vfields);
        !          1539:                    }
        !          1540:                }
        !          1541:            }
        !          1542:        }
        !          1543:     }
        !          1544: 
        !          1545:   /* Must come after offsets are fixed for all bases.  */
        !          1546:   for (i = 0; i < n_baseclasses; i++)
        !          1547:     {
        !          1548:       tree base_binfo = TREE_VEC_ELT (binfos, i);
        !          1549:       tree basetype = BINFO_TYPE (base_binfo);
        !          1550: 
        !          1551:       if (get_base_distance (basetype, t_binfo, 0, (tree*)0) == -2)
        !          1552:        {
        !          1553:          cp_warning ("direct base `%T' inaccessible in `%T' due to ambiguity",
        !          1554:                      basetype, t);
        !          1555:          b->cant_synth_asn_ref = 1;
        !          1556:          b->cant_synth_copy_ctor = 1;
        !          1557:        }
        !          1558:     }
        !          1559:   {
        !          1560:     tree v = get_vbase_types (t_binfo);
        !          1561: 
        !          1562:     for (; v; v = TREE_CHAIN (v))
        !          1563:       {
        !          1564:        tree basetype = BINFO_TYPE (v);
        !          1565:        if (get_base_distance (basetype, t_binfo, 0, (tree*)0) == -2)
        !          1566:          {
        !          1567:            if (extra_warnings)
        !          1568:              cp_warning ("virtual base `%T' inaccessible in `%T' due to ambiguity",
        !          1569:                          basetype, t);
        !          1570:            b->cant_synth_asn_ref = 1;
        !          1571:            b->cant_synth_copy_ctor = 1;
        !          1572:          }
        !          1573:       }
        !          1574:   }    
        !          1575: 
        !          1576:   {
        !          1577:     tree vfields;
        !          1578:     /* Find the base class with the largest number of virtual functions.  */
        !          1579:     for (vfields = b->vfields; vfields; vfields = TREE_CHAIN (vfields))
        !          1580:       {
        !          1581:        if (CLASSTYPE_VSIZE (VF_BASETYPE_VALUE (vfields)) > b->max_has_virtual)
        !          1582:          b->max_has_virtual = CLASSTYPE_VSIZE (VF_BASETYPE_VALUE (vfields));
        !          1583:        if (VF_DERIVED_VALUE (vfields)
        !          1584:            && CLASSTYPE_VSIZE (VF_DERIVED_VALUE (vfields)) > b->max_has_virtual)
        !          1585:          b->max_has_virtual = CLASSTYPE_VSIZE (VF_DERIVED_VALUE (vfields));
        !          1586:       }
        !          1587:   }
        !          1588: 
        !          1589:   if (b->vfield == 0)
        !          1590:     /* If all virtual functions come only from virtual baseclasses.  */
        !          1591:     return -1;
        !          1592:   return first_vfn_base_index;
        !          1593: }
        !          1594: 
        !          1595: static int
        !          1596: typecode_p (type, code)
        !          1597:      tree type;
        !          1598:      enum tree_code code;
        !          1599: {
        !          1600:   return (TREE_CODE (type) == code
        !          1601:          || (TREE_CODE (type) == REFERENCE_TYPE
        !          1602:              && TREE_CODE (TREE_TYPE (type)) == code));
        !          1603: }
        !          1604: 
        !          1605: /* Set memoizing fields and bits of T (and its variants) for later use.
        !          1606:    MAX_HAS_VIRTUAL is the largest size of any T's virtual function tables.  */
        !          1607: static void
        !          1608: finish_struct_bits (t, max_has_virtual)
        !          1609:      tree t;
        !          1610:      int max_has_virtual;
        !          1611: {
        !          1612:   int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
        !          1613:   tree method_vec = CLASSTYPE_METHOD_VEC (t);
        !          1614: 
        !          1615:   /* Fix up variants (if any).  */
        !          1616:   tree variants = TYPE_NEXT_VARIANT (t);
        !          1617:   while (variants)
        !          1618:     {
        !          1619:       /* These fields are in the _TYPE part of the node, not in
        !          1620:         the TYPE_LANG_SPECIFIC component, so they are not shared.  */
        !          1621:       TYPE_HAS_CONSTRUCTOR (variants) = TYPE_HAS_CONSTRUCTOR (t);
        !          1622:       TYPE_HAS_DESTRUCTOR (variants) = TYPE_HAS_DESTRUCTOR (t);
        !          1623:       TYPE_NEEDS_CONSTRUCTING (variants) = TYPE_NEEDS_CONSTRUCTING (t);
        !          1624:       TYPE_NEEDS_DESTRUCTOR (variants) = TYPE_NEEDS_DESTRUCTOR (t);
        !          1625: 
        !          1626:       TYPE_USES_COMPLEX_INHERITANCE (variants) = TYPE_USES_COMPLEX_INHERITANCE (t);
        !          1627:       TYPE_VIRTUAL_P (variants) = TYPE_VIRTUAL_P (t);
        !          1628:       TYPE_USES_VIRTUAL_BASECLASSES (variants) = TYPE_USES_VIRTUAL_BASECLASSES (t);
        !          1629:       /* Copy whatever these are holding today.  */
        !          1630:       TYPE_MIN_VALUE (variants) = TYPE_MIN_VALUE (t);
        !          1631:       TYPE_MAX_VALUE (variants) = TYPE_MAX_VALUE (t);
        !          1632:       variants = TYPE_NEXT_VARIANT (variants);
        !          1633:     }
        !          1634: 
        !          1635:   if (n_baseclasses && max_has_virtual)
        !          1636:     {
        !          1637:       /* Done by `finish_struct' for classes without baseclasses.  */
        !          1638:       int might_have_abstract_virtuals = CLASSTYPE_ABSTRACT_VIRTUALS (t) != 0;
        !          1639:       tree binfos = TYPE_BINFO_BASETYPES (t);
        !          1640:       for (i = n_baseclasses-1; i >= 0; i--)
        !          1641:        {
        !          1642:          might_have_abstract_virtuals
        !          1643:            |= (CLASSTYPE_ABSTRACT_VIRTUALS (BINFO_TYPE (TREE_VEC_ELT (binfos, i))) != 0);
        !          1644:          if (might_have_abstract_virtuals)
        !          1645:            break;
        !          1646:        }
        !          1647:       if (might_have_abstract_virtuals)
        !          1648:        {
        !          1649:          /* We use error_mark_node from override_one_vtable to signal
        !          1650:             an artificial abstract. */
        !          1651:          if (CLASSTYPE_ABSTRACT_VIRTUALS (t) == error_mark_node)
        !          1652:            CLASSTYPE_ABSTRACT_VIRTUALS (t) = NULL_TREE;
        !          1653:          CLASSTYPE_ABSTRACT_VIRTUALS (t) = get_abstract_virtuals (t);
        !          1654:        }
        !          1655:     }
        !          1656: 
        !          1657:   if (n_baseclasses)
        !          1658:     {
        !          1659:       /* Notice whether this class has type conversion functions defined.  */
        !          1660:       tree binfo = TYPE_BINFO (t);
        !          1661:       tree binfos = BINFO_BASETYPES (binfo);
        !          1662:       tree basetype;
        !          1663: 
        !          1664:       for (i = n_baseclasses-1; i >= 0; i--)
        !          1665:        {
        !          1666:          basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, i));
        !          1667: 
        !          1668:          if (TYPE_HAS_CONVERSION (basetype))
        !          1669:            {
        !          1670:              TYPE_HAS_CONVERSION (t) = 1;
        !          1671:              TYPE_HAS_INT_CONVERSION (t) |= TYPE_HAS_INT_CONVERSION (basetype);
        !          1672:              TYPE_HAS_REAL_CONVERSION (t) |= TYPE_HAS_REAL_CONVERSION (basetype);
        !          1673:            }
        !          1674:          if (CLASSTYPE_MAX_DEPTH (basetype) >= CLASSTYPE_MAX_DEPTH (t))
        !          1675:            CLASSTYPE_MAX_DEPTH (t) = CLASSTYPE_MAX_DEPTH (basetype) + 1;
        !          1676:        }
        !          1677:     }
        !          1678: 
        !          1679:   /* Need to test METHOD_VEC here in case all methods
        !          1680:      (conversions and otherwise) are inherited.  */
        !          1681:   if (TYPE_HAS_CONVERSION (t) && method_vec != NULL_TREE)
        !          1682:     {
        !          1683:       tree first_conversions[last_conversion_type];
        !          1684:       tree last_conversions[last_conversion_type];
        !          1685:       enum conversion_type conv_index;
        !          1686:       tree *tmp;
        !          1687:       int i;
        !          1688: 
        !          1689:       bzero ((char *) first_conversions, sizeof (first_conversions));
        !          1690:       bzero ((char *) last_conversions, sizeof (last_conversions));
        !          1691:       for (tmp = &TREE_VEC_ELT (method_vec, 1);
        !          1692:           tmp != TREE_VEC_END (method_vec); tmp += 1)
        !          1693:        {
        !          1694:          /* ??? This should compare DECL_NAME (*tmp) == ansi_opname[TYPE_EXPR].  */
        !          1695:          if (IDENTIFIER_TYPENAME_P (DECL_ASSEMBLER_NAME (*tmp)))
        !          1696:            {
        !          1697:              tree fntype = TREE_TYPE (*tmp);
        !          1698:              tree return_type = TREE_TYPE (fntype);
        !          1699:              my_friendly_assert (TREE_CODE (fntype) == METHOD_TYPE, 171);
        !          1700: 
        !          1701:              if (typecode_p (return_type, POINTER_TYPE))
        !          1702:                {
        !          1703:                  if (TYPE_READONLY (TREE_TYPE (return_type)))
        !          1704:                    conv_index = constptr_conv;
        !          1705:                  else
        !          1706:                    conv_index = ptr_conv;
        !          1707:                }
        !          1708:              else if (typecode_p (return_type, INTEGER_TYPE)
        !          1709:                       || typecode_p (return_type, BOOLEAN_TYPE)
        !          1710:                       || typecode_p (return_type, ENUMERAL_TYPE))
        !          1711:                {
        !          1712:                  TYPE_HAS_INT_CONVERSION (t) = 1;
        !          1713:                  conv_index = int_conv;
        !          1714:                }
        !          1715:              else if (typecode_p (return_type, REAL_TYPE))
        !          1716:                {
        !          1717:                  TYPE_HAS_REAL_CONVERSION (t) = 1;
        !          1718:                  conv_index = real_conv;
        !          1719:                }
        !          1720:              else
        !          1721:                continue;
        !          1722: 
        !          1723:              if (first_conversions[(int) conv_index] == NULL_TREE)
        !          1724:                first_conversions[(int) conv_index] = *tmp;
        !          1725:              last_conversions[(int) conv_index] = *tmp;
        !          1726:            }
        !          1727:        }
        !          1728: 
        !          1729:       for (i = 0; i < (int) last_conversion_type; i++)
        !          1730:        if (first_conversions[i] != last_conversions[i])
        !          1731:          CLASSTYPE_CONVERSION (t, i) = error_mark_node;
        !          1732:        else
        !          1733:          CLASSTYPE_CONVERSION (t, i) = first_conversions[i];
        !          1734:     }
        !          1735: 
        !          1736:   /* If this type has constructors, force its mode to be BLKmode,
        !          1737:      and force its TREE_ADDRESSABLE bit to be nonzero.  */
        !          1738:   if (TYPE_NEEDS_CONSTRUCTING (t) || TYPE_NEEDS_DESTRUCTOR (t))
        !          1739:     {
        !          1740:       tree variants = t;
        !          1741: 
        !          1742:       if (TREE_CODE (TYPE_NAME (t)) == TYPE_DECL)
        !          1743:        DECL_MODE (TYPE_NAME (t)) = BLKmode;
        !          1744:       while (variants)
        !          1745:        {
        !          1746:          TYPE_MODE (variants) = BLKmode;
        !          1747:          TREE_ADDRESSABLE (variants) = 1;
        !          1748:          variants = TYPE_NEXT_VARIANT (variants);
        !          1749:        }
        !          1750:     }
        !          1751: }
        !          1752: 
        !          1753: /* Warn about duplicate methods in fn_fields.  Also compact method
        !          1754:    lists so that lookup can be made faster.
        !          1755: 
        !          1756:    Algorithm: Outer loop builds lists by method name.  Inner loop
        !          1757:    checks for redundant method names within a list.
        !          1758: 
        !          1759:    Data Structure: List of method lists.  The outer list is a
        !          1760:    TREE_LIST, whose TREE_PURPOSE field is the field name and the
        !          1761:    TREE_VALUE is the TREE_CHAIN of the FUNCTION_DECLs.  Friends are
        !          1762:    chained in the same way as member functions, but they live in the
        !          1763:    TREE_TYPE field of the outer list.  That allows them to be quickly
        !          1764:    deleted, and requires no extra storage.
        !          1765: 
        !          1766:    If there are any constructors/destructors, they are moved to the
        !          1767:    front of the list.  This makes pushclass more efficient.
        !          1768: 
        !          1769:    We also link each field which has shares a name with its baseclass
        !          1770:    to the head of the list of fields for that base class.  This allows
        !          1771:    us to reduce search time in places like `build_method_call' to
        !          1772:    consider only reasonably likely functions.  */
        !          1773: 
        !          1774: static tree
        !          1775: finish_struct_methods (t, fn_fields, nonprivate_method)
        !          1776:      tree t;
        !          1777:      tree fn_fields;
        !          1778:      int nonprivate_method;
        !          1779: {
        !          1780:   tree method_vec;
        !          1781:   tree name = constructor_name (t);
        !          1782:   int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
        !          1783: 
        !          1784:   /* Now prepare to gather fn_fields into vector.  */
        !          1785:   struct obstack *ambient_obstack = current_obstack;
        !          1786:   current_obstack = &class_obstack;
        !          1787:   method_vec = make_node (TREE_VEC);
        !          1788:   /* Room has been saved for constructors and destructors.  */
        !          1789:   current_obstack = ambient_obstack;
        !          1790:   /* Now make this a live vector.  */
        !          1791:   obstack_free (&class_obstack, method_vec);
        !          1792:   obstack_blank (&class_obstack, sizeof (struct tree_vec));
        !          1793: 
        !          1794:   while (fn_fields)
        !          1795:     {
        !          1796:       /* NEXT Pointer, TEST Pointer, and BASE Pointer.  */
        !          1797:       tree nextp, *testp;
        !          1798:       tree fn_name = DECL_NAME (fn_fields);
        !          1799:       if (fn_name == NULL_TREE)
        !          1800:        fn_name = name;
        !          1801: 
        !          1802:       nextp = TREE_CHAIN (fn_fields);
        !          1803:       TREE_CHAIN (fn_fields) = NULL_TREE;
        !          1804: 
        !          1805:       /* Clear out this flag.
        !          1806: 
        !          1807:         @@ Doug may figure out how to break
        !          1808:         @@ this with nested classes and friends.  */
        !          1809:       DECL_IN_AGGR_P (fn_fields) = 0;
        !          1810: 
        !          1811:       /* Note here that a copy ctor is private, so we don't dare generate
        !          1812:         a default copy constructor for a class that has a member
        !          1813:         of this type without making sure they have access to it.  */
        !          1814:       if (fn_name == name)
        !          1815:        {
        !          1816:          tree parmtypes = FUNCTION_ARG_CHAIN (fn_fields);
        !          1817:          tree parmtype = parmtypes ? TREE_VALUE (parmtypes) : void_type_node;
        !          1818:          
        !          1819:          if (TREE_CODE (parmtype) == REFERENCE_TYPE
        !          1820:              && TYPE_MAIN_VARIANT (TREE_TYPE (parmtype)) == t)
        !          1821:            {
        !          1822:              if (TREE_CHAIN (parmtypes) == NULL_TREE
        !          1823:                  || TREE_CHAIN (parmtypes) == void_list_node
        !          1824:                  || TREE_PURPOSE (TREE_CHAIN (parmtypes)))
        !          1825:                {
        !          1826:                  if (TREE_PROTECTED (fn_fields))
        !          1827:                    TYPE_HAS_NONPUBLIC_CTOR (t) = 1;
        !          1828:                  else if (TREE_PRIVATE (fn_fields))
        !          1829:                    TYPE_HAS_NONPUBLIC_CTOR (t) = 2;
        !          1830:                }
        !          1831:            }
        !          1832:        }
        !          1833:       else if (fn_name == ansi_opname[(int) MODIFY_EXPR])
        !          1834:        {
        !          1835:          tree parmtype = TREE_VALUE (FUNCTION_ARG_CHAIN (fn_fields));
        !          1836: 
        !          1837:          if (copy_assignment_arg_p (parmtype, DECL_VIRTUAL_P (fn_fields)))
        !          1838:            {
        !          1839:              if (TREE_PROTECTED (fn_fields))
        !          1840:                TYPE_HAS_NONPUBLIC_ASSIGN_REF (t) = 1;
        !          1841:              else if (TREE_PRIVATE (fn_fields))
        !          1842:                TYPE_HAS_NONPUBLIC_ASSIGN_REF (t) = 2;
        !          1843:            }
        !          1844:        }
        !          1845: 
        !          1846:       /* Constructors are handled easily in search routines.  */
        !          1847:       if (fn_name == name)
        !          1848:        {
        !          1849:          DECL_CHAIN (fn_fields) = TREE_VEC_ELT (method_vec, 0);
        !          1850:          TREE_VEC_ELT (method_vec, 0) = fn_fields;
        !          1851:        }
        !          1852:       else
        !          1853:        {
        !          1854:          testp = &TREE_VEC_ELT (method_vec, 0);
        !          1855:          if (*testp == NULL_TREE)
        !          1856:            testp++;
        !          1857:          while (((HOST_WIDE_INT) testp
        !          1858:                  < (HOST_WIDE_INT) obstack_next_free (&class_obstack))
        !          1859:                 && DECL_NAME (*testp) != fn_name)
        !          1860:            testp++;
        !          1861:          if ((HOST_WIDE_INT) testp
        !          1862:              < (HOST_WIDE_INT) obstack_next_free (&class_obstack))
        !          1863:            {
        !          1864:              tree x, prev_x;
        !          1865: 
        !          1866:              for (x = *testp; x; x = DECL_CHAIN (x))
        !          1867:                {
        !          1868:                  if (DECL_NAME (fn_fields) == ansi_opname[(int) DELETE_EXPR]
        !          1869:                      || DECL_NAME (fn_fields)
        !          1870:                         == ansi_opname[(int) VEC_DELETE_EXPR])
        !          1871:                    {
        !          1872:                      /* ANSI C++ June 5 1992 WP 12.5.5.1 */
        !          1873:                      cp_error_at ("`%D' overloaded", fn_fields);
        !          1874:                      cp_error_at ("previous declaration as `%D' here", x);
        !          1875:                    }
        !          1876:                  if (DECL_ASSEMBLER_NAME (fn_fields)==DECL_ASSEMBLER_NAME (x))
        !          1877:                    {
        !          1878:                      /* We complain about multiple destructors on sight,
        !          1879:                         so we do not repeat the warning here.  Friend-friend
        !          1880:                         ambiguities are warned about outside this loop.  */
        !          1881:                      if (!DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fn_fields)))
        !          1882:                        cp_error_at ("ambiguous method `%#D' in structure",
        !          1883:                                     fn_fields);
        !          1884:                      break;
        !          1885:                    }
        !          1886:                  prev_x = x;
        !          1887:                }
        !          1888:              if (x == 0)
        !          1889:                {
        !          1890:                  if (*testp)
        !          1891:                    DECL_CHAIN (prev_x) = fn_fields;
        !          1892:                  else
        !          1893:                    *testp = fn_fields;
        !          1894:                }
        !          1895:            }
        !          1896:          else
        !          1897:            {
        !          1898:              obstack_ptr_grow (&class_obstack, fn_fields);
        !          1899:              method_vec = (tree)obstack_base (&class_obstack);
        !          1900:            }
        !          1901:        }
        !          1902:       fn_fields = nextp;
        !          1903:     }
        !          1904: 
        !          1905:   TREE_VEC_LENGTH (method_vec) = (tree *)obstack_next_free (&class_obstack)
        !          1906:     - (&TREE_VEC_ELT (method_vec, 0));
        !          1907:   obstack_finish (&class_obstack);
        !          1908:   CLASSTYPE_METHOD_VEC (t) = method_vec;
        !          1909: 
        !          1910:   if (nonprivate_method == 0
        !          1911:       && CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE
        !          1912:       && DECL_FRIENDLIST (TYPE_NAME (t)) == NULL_TREE)
        !          1913:     {
        !          1914:       tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));
        !          1915:       for (i = 0; i < n_baseclasses; i++)
        !          1916:        if (TREE_VIA_PUBLIC (TREE_VEC_ELT (binfos, i))
        !          1917:            || TREE_VIA_PROTECTED (TREE_VEC_ELT (binfos, i)))
        !          1918:          {
        !          1919:            nonprivate_method = 1;
        !          1920:            break;
        !          1921:          }
        !          1922:       if (nonprivate_method == 0)
        !          1923:        cp_warning ("all member functions in class `%T' are private", t);
        !          1924:     }
        !          1925: 
        !          1926:   /* If there are constructors (and destructors), they are at the
        !          1927:      front.  Place destructors at very front.  Also warn if all
        !          1928:      constructors and/or destructors are private (in which case this
        !          1929:      class is effectively unusable.  */
        !          1930:   if (TYPE_HAS_DESTRUCTOR (t))
        !          1931:     {
        !          1932:       tree dtor, prev;
        !          1933: 
        !          1934:       for (dtor = TREE_VEC_ELT (method_vec, 0);
        !          1935:           dtor;
        !          1936:           prev = dtor, dtor = DECL_CHAIN (dtor))
        !          1937:        {
        !          1938:          if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (dtor)))
        !          1939:            {
        !          1940:              if (TREE_PRIVATE (dtor)
        !          1941:                  && CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE
        !          1942:                  && DECL_FRIENDLIST (TYPE_NAME (t)) == NULL_TREE
        !          1943:                  && warn_ctor_dtor_privacy)
        !          1944:                cp_warning ("`%#T' only defines a private destructor and has no friends",
        !          1945:                            t);
        !          1946:              break;
        !          1947:            }
        !          1948:        }
        !          1949: 
        !          1950:       /* Wild parse errors can cause this to happen.  */
        !          1951:       if (dtor == NULL_TREE)
        !          1952:        TYPE_HAS_DESTRUCTOR (t) = 0;
        !          1953:       else if (dtor != TREE_VEC_ELT (method_vec, 0))
        !          1954:        {
        !          1955:          DECL_CHAIN (prev) = DECL_CHAIN (dtor);
        !          1956:          DECL_CHAIN (dtor) = TREE_VEC_ELT (method_vec, 0);
        !          1957:          TREE_VEC_ELT (method_vec, 0) = dtor;
        !          1958:        }
        !          1959:     }
        !          1960: 
        !          1961:   /* Now for each member function (except for constructors and
        !          1962:      destructors), compute where member functions of the same
        !          1963:      name reside in base classes.  */
        !          1964:   if (n_baseclasses != 0
        !          1965:       && TREE_VEC_LENGTH (method_vec) > 1)
        !          1966:     {
        !          1967:       int len = TREE_VEC_LENGTH (method_vec);
        !          1968:       tree baselink_vec = make_tree_vec (len);
        !          1969:       int any_links = 0;
        !          1970:       tree baselink_binfo = build_tree_list (NULL_TREE, TYPE_BINFO (t));
        !          1971: 
        !          1972:       for (i = 1; i < len; i++)
        !          1973:        {
        !          1974:          TREE_VEC_ELT (baselink_vec, i)
        !          1975:            = get_baselinks (baselink_binfo, t, DECL_NAME (TREE_VEC_ELT (method_vec, i)));
        !          1976:          if (TREE_VEC_ELT (baselink_vec, i) != 0)
        !          1977:            any_links = 1;
        !          1978:        }
        !          1979:       if (any_links != 0)
        !          1980:        CLASSTYPE_BASELINK_VEC (t) = baselink_vec;
        !          1981:       else
        !          1982:        obstack_free (current_obstack, baselink_vec);
        !          1983:     }
        !          1984: 
        !          1985:   /* Now add the methods to the TYPE_METHODS of T, arranged in a chain.  */
        !          1986:   {
        !          1987:     tree x, last_x = NULL_TREE;
        !          1988:     int limit = TREE_VEC_LENGTH (method_vec);
        !          1989: 
        !          1990:     for (i = 1; i < limit; i++)
        !          1991:       {
        !          1992:        for (x = TREE_VEC_ELT (method_vec, i); x; x = DECL_CHAIN (x))
        !          1993:          {
        !          1994:            if (last_x != NULL_TREE)
        !          1995:              TREE_CHAIN (last_x) = x;
        !          1996:            last_x = x;
        !          1997:          }
        !          1998:       }
        !          1999: 
        !          2000:     /* Put ctors and dtors at the front of the list.  */
        !          2001:     x = TREE_VEC_ELT (method_vec, 0);
        !          2002:     if (x)
        !          2003:       {
        !          2004:        while (DECL_CHAIN (x))
        !          2005:          {
        !          2006:            /* Let's avoid being circular about this.  */
        !          2007:            if (x == DECL_CHAIN (x))
        !          2008:              break;
        !          2009:            TREE_CHAIN (x) = DECL_CHAIN (x);
        !          2010:            x = DECL_CHAIN (x);
        !          2011:          }
        !          2012:        if (TREE_VEC_LENGTH (method_vec) > 1)
        !          2013:          TREE_CHAIN (x) = TREE_VEC_ELT (method_vec, 1);
        !          2014:        else
        !          2015:          TREE_CHAIN (x) = NULL_TREE;
        !          2016:       }
        !          2017:   }
        !          2018: 
        !          2019:   TYPE_METHODS (t) = method_vec;
        !          2020: 
        !          2021:   return method_vec;
        !          2022: }
        !          2023: 
        !          2024: /* Emit error when a duplicate definition of a type is seen.  Patch up. */
        !          2025: 
        !          2026: void
        !          2027: duplicate_tag_error (t)
        !          2028:      tree t;
        !          2029: {
        !          2030:   cp_error ("redefinition of `%#T'", t);
        !          2031: 
        !          2032:   /* Pretend we haven't defined this type.  */
        !          2033: 
        !          2034:   /* All of the component_decl's were TREE_CHAINed together in the parser.
        !          2035:      finish_struct_methods walks these chains and assembles all methods with
        !          2036:      the same base name into DECL_CHAINs. Now we don't need the parser chains
        !          2037:      anymore, so we unravel them.
        !          2038:    */
        !          2039:   /*
        !          2040:    * This used to be in finish_struct, but it turns out that the
        !          2041:    * TREE_CHAIN is used by dbxout_type_methods and perhaps some other things...
        !          2042:    */
        !          2043:   if (CLASSTYPE_METHOD_VEC(t)) 
        !          2044:     {
        !          2045:       tree tv = CLASSTYPE_METHOD_VEC(t);
        !          2046:       int i, len  = TREE_VEC_LENGTH (tv);
        !          2047:       for (i = 0; i < len; i++)
        !          2048:        {
        !          2049:          tree unchain = TREE_VEC_ELT (tv, i);
        !          2050:          while (unchain != NULL_TREE) 
        !          2051:            {
        !          2052:              TREE_CHAIN (unchain) = NULL_TREE;
        !          2053:              unchain = DECL_CHAIN(unchain);
        !          2054:            }
        !          2055:        }
        !          2056:     }
        !          2057: 
        !          2058:   if (TYPE_LANG_SPECIFIC (t))
        !          2059:     {
        !          2060:       tree as_list = CLASSTYPE_AS_LIST (t);
        !          2061:       tree binfo = TYPE_BINFO (t);
        !          2062:       tree binfo_as_list = CLASSTYPE_BINFO_AS_LIST (t);
        !          2063:       int interface_only = CLASSTYPE_INTERFACE_ONLY (t);
        !          2064:       int interface_unknown = CLASSTYPE_INTERFACE_UNKNOWN (t);
        !          2065: 
        !          2066:       bzero ((char *) TYPE_LANG_SPECIFIC (t), sizeof (struct lang_type));
        !          2067:       BINFO_BASETYPES(binfo) = NULL_TREE;
        !          2068: 
        !          2069:       CLASSTYPE_AS_LIST (t) = as_list;
        !          2070:       TYPE_BINFO (t) = binfo;
        !          2071:       CLASSTYPE_BINFO_AS_LIST (t) = binfo_as_list;
        !          2072:       CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
        !          2073:       SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
        !          2074:       CLASSTYPE_VBASE_SIZE (t) = integer_zero_node;
        !          2075:       TYPE_REDEFINED (t) = 1;
        !          2076:     }
        !          2077:   TYPE_SIZE (t) = NULL_TREE;
        !          2078:   TYPE_MODE (t) = VOIDmode;
        !          2079:   TYPE_FIELDS (t) = NULL_TREE;
        !          2080:   TYPE_METHODS (t) = NULL_TREE;
        !          2081:   TYPE_VFIELD (t) = NULL_TREE;
        !          2082:   TYPE_CONTEXT (t) = NULL_TREE;
        !          2083: }
        !          2084: 
        !          2085: /* finish up all new vtables. */
        !          2086: static void
        !          2087: finish_vtbls (binfo, do_self, t)
        !          2088:      tree binfo, t;
        !          2089:      int do_self;
        !          2090: {
        !          2091:   tree binfos = BINFO_BASETYPES (binfo);
        !          2092:   int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
        !          2093: 
        !          2094:   /* Should we use something besides CLASSTYPE_VFIELDS? */
        !          2095:   if (do_self && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)))
        !          2096:     {
        !          2097:       if (BINFO_NEW_VTABLE_MARKED (binfo))
        !          2098:        {
        !          2099:          tree decl, context;
        !          2100: 
        !          2101:          decl = BINFO_VTABLE (binfo);
        !          2102:          context = DECL_CONTEXT (decl);
        !          2103:          DECL_CONTEXT (decl) = 0;
        !          2104:          if (write_virtuals >= 0
        !          2105:              && DECL_INITIAL (decl) != BINFO_VIRTUALS (binfo))
        !          2106:            DECL_INITIAL (decl) = build_nt (CONSTRUCTOR, NULL_TREE,
        !          2107:                                            BINFO_VIRTUALS (binfo));
        !          2108:          finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0);
        !          2109:          DECL_CONTEXT (decl) = context;
        !          2110:        }
        !          2111:       CLEAR_BINFO_NEW_VTABLE_MARKED (binfo);
        !          2112:     }
        !          2113: 
        !          2114:   for (i = 0; i < n_baselinks; i++)
        !          2115:     {
        !          2116:       tree base_binfo = TREE_VEC_ELT (binfos, i);
        !          2117:       int is_not_base_vtable =
        !          2118:        i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
        !          2119:       if (TREE_VIA_VIRTUAL (base_binfo))
        !          2120:        {
        !          2121:          base_binfo = binfo_member (BINFO_TYPE (base_binfo), CLASSTYPE_VBASECLASSES (t));
        !          2122:        }
        !          2123:       finish_vtbls (base_binfo, is_not_base_vtable, t);
        !          2124:     }
        !          2125: }
        !          2126: 
        !          2127: /* True if we should override the given BASE_FNDECL with the given
        !          2128:    FNDECL.  */
        !          2129: static int
        !          2130: overrides (fndecl, base_fndecl)
        !          2131:      tree fndecl, base_fndecl;
        !          2132: {
        !          2133:   /* Destructors have special names. */
        !          2134:   if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (base_fndecl)) &&
        !          2135:       DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl)))
        !          2136:     return 1;
        !          2137:   if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (base_fndecl)) ||
        !          2138:       DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl)))
        !          2139:     return 0;
        !          2140:   if (DECL_NAME (fndecl) == DECL_NAME (base_fndecl))
        !          2141:     {
        !          2142:       tree rettype, base_rettype, types, base_types;
        !          2143: #if 0
        !          2144:       retypes = TREE_TYPE (TREE_TYPE (fndecl));
        !          2145:       base_retypes = TREE_TYPE (TREE_TYPE (base_fndecl));
        !          2146: #endif
        !          2147:       types = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
        !          2148:       base_types = TYPE_ARG_TYPES (TREE_TYPE (base_fndecl));
        !          2149:       if ((TYPE_READONLY (TREE_TYPE (TREE_VALUE (base_types)))
        !          2150:           == TYPE_READONLY (TREE_TYPE (TREE_VALUE (types))))
        !          2151:          && compparms (TREE_CHAIN (base_types), TREE_CHAIN (types), 3))
        !          2152:        return 1;
        !          2153:     }
        !          2154:   return 0;
        !          2155: }
        !          2156: 
        !          2157: static tree
        !          2158: get_class_offset_1 (parent, binfo, context, t, fndecl)
        !          2159:      tree parent, binfo, context, t, fndecl;
        !          2160: {
        !          2161:   tree binfos = BINFO_BASETYPES (binfo);
        !          2162:   int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
        !          2163:   tree rval = NULL_TREE;
        !          2164: 
        !          2165:   if (binfo == parent)
        !          2166:     return error_mark_node;
        !          2167: 
        !          2168:   for (i = 0; i < n_baselinks; i++)
        !          2169:     {
        !          2170:       tree base_binfo = TREE_VEC_ELT (binfos, i);
        !          2171:       tree nrval;
        !          2172: 
        !          2173:       if (TREE_VIA_VIRTUAL (base_binfo))
        !          2174:        base_binfo = binfo_member (BINFO_TYPE (base_binfo),
        !          2175:                                   CLASSTYPE_VBASECLASSES (t));
        !          2176:       nrval = get_class_offset_1 (parent, base_binfo, context, t, fndecl);
        !          2177:       /* See if we have a new value */
        !          2178:       if (nrval && (nrval != error_mark_node || rval==0))
        !          2179:        {
        !          2180:          /* Only compare if we have two offsets */
        !          2181:          if (rval && rval != error_mark_node
        !          2182:              && ! tree_int_cst_equal (nrval, rval))
        !          2183:            {
        !          2184:              /* Only give error if the two offsets are different */
        !          2185:              error ("every virtual function must have a unique final overrider");
        !          2186:              cp_error ("  found two (or more) `%T' class subobjects in `%T'", context, t);
        !          2187:              cp_error ("  with virtual `%D' from virtual base class", fndecl);
        !          2188:              return rval;
        !          2189:            }
        !          2190:          rval = nrval;
        !          2191:        }
        !          2192:        
        !          2193:       if (rval && BINFO_TYPE (binfo) == context)
        !          2194:        {
        !          2195:          my_friendly_assert (rval == error_mark_node
        !          2196:                              || tree_int_cst_equal (rval, BINFO_OFFSET (binfo)), 999);
        !          2197:          rval = BINFO_OFFSET (binfo);
        !          2198:        }
        !          2199:     }
        !          2200:   return rval;
        !          2201: }
        !          2202: 
        !          2203: /* Get the offset to the CONTEXT subobject that is related to the
        !          2204:    given BINFO.  */
        !          2205: static tree
        !          2206: get_class_offset (context, t, binfo, fndecl)
        !          2207:      tree context, t, binfo, fndecl;
        !          2208: {
        !          2209:   tree first_binfo = binfo;
        !          2210:   tree offset;
        !          2211:   int i;
        !          2212: 
        !          2213:   if (context == t)
        !          2214:     return integer_zero_node;
        !          2215: 
        !          2216:   if (BINFO_TYPE (binfo) == context)
        !          2217:     return BINFO_OFFSET (binfo);
        !          2218: 
        !          2219:   /* Check less derived binfos first.  */
        !          2220:   while (BINFO_BASETYPES (binfo)
        !          2221:         && (i=CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo))) != -1)
        !          2222:     {
        !          2223:       tree binfos = BINFO_BASETYPES (binfo);
        !          2224:       binfo = TREE_VEC_ELT (binfos, i);
        !          2225:       if (BINFO_TYPE (binfo) == context)
        !          2226:        return BINFO_OFFSET (binfo);
        !          2227:     }
        !          2228: 
        !          2229:   /* Ok, not found in the less derived binfos, now check the more
        !          2230:      derived binfos. */
        !          2231:   offset = get_class_offset_1 (first_binfo, TYPE_BINFO (t), context, t, fndecl);
        !          2232:   if (offset==0 || TREE_CODE (offset) != INTEGER_CST)
        !          2233:     my_friendly_abort (999);   /* we have to find it.  */
        !          2234:   return offset;
        !          2235: }
        !          2236: 
        !          2237: static void
        !          2238: modify_one_vtable (binfo, t, fndecl, pfn)
        !          2239:      tree binfo, t, fndecl, pfn;
        !          2240: {
        !          2241:   tree virtuals = BINFO_VIRTUALS (binfo);
        !          2242:   unsigned HOST_WIDE_INT n;
        !          2243:   
        !          2244:   n = 0;
        !          2245:   /* Skip initial vtable length field and RTTI fake object. */
        !          2246:   for (; virtuals && n < 1 + flag_dossier; n++)
        !          2247:       virtuals = TREE_CHAIN (virtuals);
        !          2248:   while (virtuals)
        !          2249:     {
        !          2250:       tree current_fndecl = TREE_VALUE (virtuals);
        !          2251:       current_fndecl = FNADDR_FROM_VTABLE_ENTRY (current_fndecl);
        !          2252:       current_fndecl = TREE_OPERAND (current_fndecl, 0);
        !          2253:       if (current_fndecl && overrides (fndecl, current_fndecl))
        !          2254:        {
        !          2255:          tree base_offset, offset;
        !          2256:          tree context = DECL_CLASS_CONTEXT (fndecl);
        !          2257:          tree vfield = CLASSTYPE_VFIELD (t);
        !          2258:          tree this_offset;
        !          2259: 
        !          2260:          offset = get_class_offset (context, t, binfo, fndecl);
        !          2261: 
        !          2262:          /* Find the right offset for the this pointer based on the
        !          2263:             base class we just found.  We have to take into
        !          2264:             consideration the virtual base class pointers that we
        !          2265:             stick in before the virtual function table pointer.
        !          2266: 
        !          2267:             Also, we want just the delta bewteen the most base class
        !          2268:             that we derived this vfield from and us.  */
        !          2269:          base_offset = size_binop (PLUS_EXPR,
        !          2270:                                    get_derived_offset (binfo, DECL_CONTEXT (current_fndecl)),
        !          2271:                                    BINFO_OFFSET (binfo));
        !          2272:          this_offset = size_binop (MINUS_EXPR, offset, base_offset);
        !          2273: 
        !          2274:          /* Make sure we can modify the derived association with immunity.  */
        !          2275:          if (TREE_USED (binfo)) {
        !          2276:            my_friendly_assert (0, 999);
        !          2277: #if 0
        !          2278:            my_friendly_assert (*binfo2_ptr == binfo, 999);
        !          2279:            *binfo2_ptr = copy_binfo (binfo);
        !          2280: #endif
        !          2281:          }
        !          2282:          if (binfo == TYPE_BINFO (t))
        !          2283:            {
        !          2284:              /* In this case, it is *type*'s vtable we are modifying.
        !          2285:                 We start with the approximation that it's vtable is that
        !          2286:                 of the immediate base class.  */
        !          2287:              if (! BINFO_NEW_VTABLE_MARKED (binfo))
        !          2288:                build_vtable (TYPE_BINFO (DECL_CONTEXT (vfield)), t);
        !          2289:            }
        !          2290:          else
        !          2291:            {
        !          2292:              /* This is our very own copy of `basetype' to play with.
        !          2293:                 Later, we will fill in all the virtual functions
        !          2294:                 that override the virtual functions in these base classes
        !          2295:                 which are not defined by the current type.  */
        !          2296:              if (! BINFO_NEW_VTABLE_MARKED (binfo))
        !          2297:                prepare_fresh_vtable (binfo, t);
        !          2298:            }
        !          2299: 
        !          2300: #ifdef NOTQUITE
        !          2301:          cp_warning ("in %D", DECL_NAME (BINFO_VTABLE (binfo)));
        !          2302: #endif
        !          2303:          modify_vtable_entry (get_vtable_entry_n (BINFO_VIRTUALS (binfo), n),
        !          2304:                               build_vtable_entry (this_offset, pfn),
        !          2305:                               fndecl);
        !          2306:        }
        !          2307:       ++n;
        !          2308:       virtuals = TREE_CHAIN (virtuals);
        !          2309:     }
        !          2310: }
        !          2311: 
        !          2312: /* These are the ones that are not through virtual base classes. */
        !          2313: static void
        !          2314: modify_all_direct_vtables (binfo, do_self, t, fndecl, pfn)
        !          2315:      tree binfo, t, fndecl, pfn;
        !          2316:      int do_self;
        !          2317: {
        !          2318:   tree binfos = BINFO_BASETYPES (binfo);
        !          2319:   int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
        !          2320: 
        !          2321:   /* Should we use something besides CLASSTYPE_VFIELDS? */
        !          2322:   if (do_self && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)))
        !          2323:     {
        !          2324:       modify_one_vtable (binfo, t, fndecl, pfn);
        !          2325:     }
        !          2326: 
        !          2327:   for (i = 0; i < n_baselinks; i++)
        !          2328:     {
        !          2329:       tree base_binfo = TREE_VEC_ELT (binfos, i);
        !          2330:       int is_not_base_vtable =
        !          2331:        i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
        !          2332:       if (! TREE_VIA_VIRTUAL (base_binfo))
        !          2333:        modify_all_direct_vtables (base_binfo, is_not_base_vtable, t, fndecl, pfn);
        !          2334:     }
        !          2335: }
        !          2336: 
        !          2337: /* Fixup all the delta entries in this vtable that need updating.
        !          2338:    This happens when we have non-overridden virtual functions from a
        !          2339:    virtual base class, that are at a different offset, in the new
        !          2340:    hierarchy, because the layout of the virtual bases has changed.  */
        !          2341: static void
        !          2342: fixup_vtable_deltas (binfo, t)
        !          2343:      tree binfo, t;
        !          2344: {
        !          2345:   tree virtuals = BINFO_VIRTUALS (binfo);
        !          2346:   unsigned HOST_WIDE_INT n;
        !          2347:   
        !          2348:   n = 0;
        !          2349:   /* Skip initial vtable length field and RTTI fake object. */
        !          2350:   for (; virtuals && n < 1 + flag_dossier; n++)
        !          2351:       virtuals = TREE_CHAIN (virtuals);
        !          2352:   while (virtuals)
        !          2353:     {
        !          2354:       tree fndecl = TREE_VALUE (virtuals);
        !          2355:       tree pfn = FNADDR_FROM_VTABLE_ENTRY (fndecl);
        !          2356:       tree delta = DELTA_FROM_VTABLE_ENTRY (fndecl);
        !          2357:       fndecl = TREE_OPERAND (pfn, 0);
        !          2358:       if (fndecl)
        !          2359:        {
        !          2360:          tree base_offset, offset;
        !          2361:          tree context = DECL_CLASS_CONTEXT (fndecl);
        !          2362:          tree vfield = CLASSTYPE_VFIELD (t);
        !          2363:          tree this_offset;
        !          2364: 
        !          2365:          offset = get_class_offset (context, t, binfo, fndecl);
        !          2366: 
        !          2367:          /* Find the right offset for the this pointer based on the
        !          2368:             base class we just found.  We have to take into
        !          2369:             consideration the virtual base class pointers that we
        !          2370:             stick in before the virtual function table pointer.
        !          2371: 
        !          2372:             Also, we want just the delta bewteen the most base class
        !          2373:             that we derived this vfield from and us.  */
        !          2374:          base_offset = size_binop (PLUS_EXPR,
        !          2375:                                    get_derived_offset (binfo, DECL_CONTEXT (fndecl)),
        !          2376:                                    BINFO_OFFSET (binfo));
        !          2377:          this_offset = size_binop (MINUS_EXPR, offset, base_offset);
        !          2378: 
        !          2379:          if (! tree_int_cst_equal (this_offset, delta))
        !          2380:            {
        !          2381:              /* Make sure we can modify the derived association with immunity.  */
        !          2382:              if (TREE_USED (binfo))
        !          2383:                my_friendly_assert (0, 999);
        !          2384: 
        !          2385:              if (binfo == TYPE_BINFO (t))
        !          2386:                {
        !          2387:                  /* In this case, it is *type*'s vtable we are modifying.
        !          2388:                     We start with the approximation that it's vtable is that
        !          2389:                     of the immediate base class.  */
        !          2390:                  if (! BINFO_NEW_VTABLE_MARKED (binfo))
        !          2391:                    build_vtable (TYPE_BINFO (DECL_CONTEXT (vfield)), t);
        !          2392:                }
        !          2393:              else
        !          2394:                {
        !          2395:                  /* This is our very own copy of `basetype' to play with.
        !          2396:                     Later, we will fill in all the virtual functions
        !          2397:                     that override the virtual functions in these base classes
        !          2398:                     which are not defined by the current type.  */
        !          2399:                  if (! BINFO_NEW_VTABLE_MARKED (binfo))
        !          2400:                    prepare_fresh_vtable (binfo, t);
        !          2401:                }
        !          2402: 
        !          2403:              modify_vtable_entry (get_vtable_entry_n (BINFO_VIRTUALS (binfo), n),
        !          2404:                                   build_vtable_entry (this_offset, pfn),
        !          2405:                                   fndecl);
        !          2406:            }
        !          2407:        }
        !          2408:       ++n;
        !          2409:       virtuals = TREE_CHAIN (virtuals);
        !          2410:     }
        !          2411: }
        !          2412: 
        !          2413: /* These are the ones that are through virtual base classes. */
        !          2414: static void
        !          2415: modify_all_indirect_vtables (binfo, do_self, via_virtual, t, fndecl, pfn)
        !          2416:      tree binfo, t, fndecl, pfn;
        !          2417:      int do_self, via_virtual;
        !          2418: {
        !          2419:   tree binfos = BINFO_BASETYPES (binfo);
        !          2420:   int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
        !          2421: 
        !          2422:   /* Should we use something besides CLASSTYPE_VFIELDS? */
        !          2423:   if (do_self && via_virtual && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)))
        !          2424:     {
        !          2425:       modify_one_vtable (binfo, t, fndecl, pfn);
        !          2426:     }
        !          2427: 
        !          2428:   for (i = 0; i < n_baselinks; i++)
        !          2429:     {
        !          2430:       tree base_binfo = TREE_VEC_ELT (binfos, i);
        !          2431:       int is_not_base_vtable =
        !          2432:        i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
        !          2433:       if (TREE_VIA_VIRTUAL (base_binfo))
        !          2434:        {
        !          2435:          via_virtual = 1;
        !          2436:          base_binfo = binfo_member (BINFO_TYPE (base_binfo), CLASSTYPE_VBASECLASSES (t));
        !          2437:        }
        !          2438:       modify_all_indirect_vtables (base_binfo, is_not_base_vtable, via_virtual, t, fndecl, pfn);
        !          2439:     }
        !          2440: }
        !          2441: 
        !          2442: static void
        !          2443: modify_all_vtables (t, fndecl, vfn)
        !          2444:      tree t, fndecl, vfn;
        !          2445: {
        !          2446:   /* Do these first, so that we will make use of any non-virtual class's
        !          2447:      vtable, over a virtual classes vtable. */
        !          2448:   modify_all_direct_vtables (TYPE_BINFO (t), 1, t, fndecl, vfn);
        !          2449:   if (TYPE_USES_VIRTUAL_BASECLASSES (t))
        !          2450:     modify_all_indirect_vtables (TYPE_BINFO (t), 1, 0, t, fndecl, vfn);
        !          2451: }
        !          2452: 
        !          2453: /* Here, we already know that they match in every respect.
        !          2454:    All we have to check is where they had their declarations.  */
        !          2455: static int 
        !          2456: strictly_overrides (fndecl1, fndecl2)
        !          2457:      tree fndecl1, fndecl2;
        !          2458: {
        !          2459:   int distance = get_base_distance (DECL_CLASS_CONTEXT (fndecl2),
        !          2460:                                    DECL_CLASS_CONTEXT (fndecl1),
        !          2461:                                    0, (tree *)0);
        !          2462:   if (distance == -2 || distance > 0)
        !          2463:     return 1;
        !          2464:   return 0;
        !          2465: }
        !          2466: 
        !          2467: /* Merge overrides for one vtable.
        !          2468:    If we want to merge in same function, we are fine.
        !          2469:    else
        !          2470:      if one has a DECL_CLASS_CONTEXT that is a parent of the
        !          2471:        other, than choose the more derived one
        !          2472:      else
        !          2473:        potentially ill-formed (see 10.3 [class.virtual])
        !          2474:        we have to check later to see if there was an
        !          2475:        override in this class.  If there was ok, if not
        !          2476:        then it is ill-formed.  (mrs)
        !          2477: 
        !          2478:    We take special care to reuse a vtable, if we can.  */
        !          2479: static void
        !          2480: override_one_vtable (binfo, old, t)
        !          2481:      tree binfo, old, t;
        !          2482: {
        !          2483:   tree virtuals = BINFO_VIRTUALS (binfo);
        !          2484:   tree old_virtuals = BINFO_VIRTUALS (old);
        !          2485:   enum { REUSE_NEW, REUSE_OLD, UNDECIDED, NEITHER } choose = UNDECIDED;
        !          2486: 
        !          2487:   /* If we have already committed to modifying it, then don't try and
        !          2488:      reuse another vtable. */
        !          2489:   if (BINFO_NEW_VTABLE_MARKED (binfo))
        !          2490:     choose = NEITHER;
        !          2491: 
        !          2492:   /* Skip size entry. */
        !          2493:   virtuals = TREE_CHAIN (virtuals);
        !          2494:   /* Skip RTTI fake object. */
        !          2495:   if (flag_dossier)
        !          2496:     {
        !          2497:       virtuals = TREE_CHAIN (virtuals);
        !          2498:     }
        !          2499: 
        !          2500:   /* Skip size entry. */
        !          2501:   old_virtuals = TREE_CHAIN (old_virtuals);
        !          2502:   /* Skip RTTI fake object. */
        !          2503:   if (flag_dossier)
        !          2504:     {
        !          2505:       old_virtuals = TREE_CHAIN (old_virtuals);
        !          2506:     }
        !          2507: 
        !          2508:   while (virtuals)
        !          2509:     {
        !          2510:       tree fndecl = TREE_VALUE (virtuals);
        !          2511:       tree old_fndecl = TREE_VALUE (old_virtuals);
        !          2512:       fndecl = FNADDR_FROM_VTABLE_ENTRY (fndecl);
        !          2513:       old_fndecl = FNADDR_FROM_VTABLE_ENTRY (old_fndecl);
        !          2514:       fndecl = TREE_OPERAND (fndecl, 0);
        !          2515:       old_fndecl = TREE_OPERAND (old_fndecl, 0);
        !          2516:       /* First check to see if they are the same. */
        !          2517:       if (DECL_ASSEMBLER_NAME (fndecl) == DECL_ASSEMBLER_NAME (old_fndecl))
        !          2518:        {
        !          2519:          /* No need to do anything. */
        !          2520:        }
        !          2521:       else if (strictly_overrides (fndecl, old_fndecl))
        !          2522:        {
        !          2523:          if (choose == UNDECIDED)
        !          2524:            choose = REUSE_NEW;
        !          2525:          else if (choose == REUSE_OLD)
        !          2526:            {
        !          2527:              choose = NEITHER;
        !          2528:              if (! BINFO_NEW_VTABLE_MARKED (binfo))
        !          2529:                {
        !          2530:                  prepare_fresh_vtable (binfo, t);
        !          2531:                  override_one_vtable (binfo, old, t);
        !          2532:                  return;
        !          2533:                }
        !          2534:            }
        !          2535:        }
        !          2536:       else if (strictly_overrides (old_fndecl, fndecl))
        !          2537:        {
        !          2538:          if (choose == UNDECIDED)
        !          2539:            choose = REUSE_OLD;
        !          2540:          else if (choose == REUSE_NEW)
        !          2541:            {
        !          2542:              choose = NEITHER;
        !          2543:              if (! BINFO_NEW_VTABLE_MARKED (binfo))
        !          2544:                {
        !          2545:                  prepare_fresh_vtable (binfo, t);
        !          2546:                  override_one_vtable (binfo, old, t);
        !          2547:                  return;
        !          2548:                }
        !          2549:              TREE_VALUE (virtuals) = TREE_VALUE (old_virtuals);
        !          2550:            }
        !          2551:          else if (choose == NEITHER)
        !          2552:            {
        !          2553:              TREE_VALUE (virtuals) = TREE_VALUE (old_virtuals);
        !          2554:            }  
        !          2555:        }
        !          2556:       else
        !          2557:        {
        !          2558:          choose = NEITHER;
        !          2559:          if (! BINFO_NEW_VTABLE_MARKED (binfo))
        !          2560:            {
        !          2561:              prepare_fresh_vtable (binfo, t);
        !          2562:              override_one_vtable (binfo, old, t);
        !          2563:              return;
        !          2564:            }
        !          2565:          {
        !          2566:            /* This MUST be overriden, or the class is ill-formed.  */
        !          2567:            /* For now, we just make it abstract.  */
        !          2568:            tree fndecl = TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals)), 0);
        !          2569:            tree vfn;
        !          2570: 
        !          2571:            fndecl = copy_node (fndecl);
        !          2572:            copy_lang_decl (fndecl);
        !          2573:            DECL_ABSTRACT_VIRTUAL_P (fndecl) = 1;
        !          2574:            /* Make sure we search for it later. */
        !          2575:            if (! CLASSTYPE_ABSTRACT_VIRTUALS (t))
        !          2576:              CLASSTYPE_ABSTRACT_VIRTUALS (t) = error_mark_node;
        !          2577: 
        !          2578:            vfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, fndecl);
        !          2579:            TREE_CONSTANT (vfn) = 1;
        !          2580:            
        !          2581:            /* We can use integer_zero_node, as we will will core dump
        !          2582:               if this is used anyway. */
        !          2583:            TREE_VALUE (virtuals) = build_vtable_entry (integer_zero_node, vfn);
        !          2584:          }
        !          2585:        }
        !          2586:       virtuals = TREE_CHAIN (virtuals);
        !          2587:       old_virtuals = TREE_CHAIN (old_virtuals);
        !          2588:     }
        !          2589: 
        !          2590:   /* Let's reuse the old vtable. */
        !          2591:   if (choose == REUSE_OLD)
        !          2592:     {
        !          2593:       BINFO_VTABLE (binfo) = BINFO_VTABLE (old);
        !          2594:       BINFO_VIRTUALS (binfo) = BINFO_VIRTUALS (old);
        !          2595:     }
        !          2596: }
        !          2597: 
        !          2598: /* Merge in overrides for virtual bases.
        !          2599:    BINFO is the hierarchy we want to modify, and OLD has the potential
        !          2600:    overrides.  */
        !          2601: static void
        !          2602: merge_overrides (binfo, old, do_self, t)
        !          2603:      tree binfo, old, t;
        !          2604:      int do_self;
        !          2605: {
        !          2606:   tree binfos = BINFO_BASETYPES (binfo);
        !          2607:   tree old_binfos = BINFO_BASETYPES (old);
        !          2608:   int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
        !          2609: 
        !          2610:   /* Should we use something besides CLASSTYPE_VFIELDS? */
        !          2611:   if (do_self && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)))
        !          2612:     {
        !          2613:       override_one_vtable (binfo, old, t);
        !          2614:     }
        !          2615: 
        !          2616:   for (i = 0; i < n_baselinks; i++)
        !          2617:     {
        !          2618:       tree base_binfo = TREE_VEC_ELT (binfos, i);
        !          2619:       tree old_base_binfo = TREE_VEC_ELT (old_binfos, i);
        !          2620:       int is_not_base_vtable =
        !          2621:        i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
        !          2622:       if (! TREE_VIA_VIRTUAL (base_binfo))
        !          2623:        merge_overrides (base_binfo, old_base_binfo, is_not_base_vtable, t);
        !          2624:     }
        !          2625: }
        !          2626: 
        !          2627: /* Create a RECORD_TYPE or UNION_TYPE node for a C struct or union declaration
        !          2628:    (or C++ class declaration).
        !          2629: 
        !          2630:    For C++, we must handle the building of derived classes.
        !          2631:    Also, C++ allows static class members.  The way that this is
        !          2632:    handled is to keep the field name where it is (as the DECL_NAME
        !          2633:    of the field), and place the overloaded decl in the DECL_FIELD_BITPOS
        !          2634:    of the field.  layout_record and layout_union will know about this.
        !          2635: 
        !          2636:    More C++ hair: inline functions have text in their
        !          2637:    DECL_PENDING_INLINE_INFO nodes which must somehow be parsed into
        !          2638:    meaningful tree structure.  After the struct has been laid out, set
        !          2639:    things up so that this can happen.
        !          2640: 
        !          2641:    And still more: virtual functions.  In the case of single inheritance,
        !          2642:    when a new virtual function is seen which redefines a virtual function
        !          2643:    from the base class, the new virtual function is placed into
        !          2644:    the virtual function table at exactly the same address that
        !          2645:    it had in the base class.  When this is extended to multiple
        !          2646:    inheritance, the same thing happens, except that multiple virtual
        !          2647:    function tables must be maintained.  The first virtual function
        !          2648:    table is treated in exactly the same way as in the case of single
        !          2649:    inheritance.  Additional virtual function tables have different
        !          2650:    DELTAs, which tell how to adjust `this' to point to the right thing.
        !          2651: 
        !          2652:    LIST_OF_FIELDLISTS is just that.  The elements of the list are
        !          2653:    TREE_LIST elements, whose TREE_PURPOSE field tells what access
        !          2654:    the list has, and the TREE_VALUE slot gives the actual fields.
        !          2655: 
        !          2656:    If flag_all_virtual == 1, then we lay all functions into
        !          2657:    the virtual function table, as though they were declared
        !          2658:    virtual.  Constructors do not lay down in the virtual function table.
        !          2659: 
        !          2660:    If flag_all_virtual == 2, then we lay all functions into
        !          2661:    the virtual function table, such that virtual functions
        !          2662:    occupy a space by themselves, and then all functions
        !          2663:    of the class occupy a space by themselves.  This is illustrated
        !          2664:    in the following diagram:
        !          2665: 
        !          2666:    class A; class B : A;
        !          2667: 
        !          2668:        Class A's vtbl:                 Class B's vtbl:
        !          2669:     --------------------------------------------------------------------
        !          2670:    | A's virtual functions|            | B's virtual functions         |
        !          2671:    |                     |             | (may inherit some from A).    |
        !          2672:     --------------------------------------------------------------------
        !          2673:    | All of A's functions |            | All of A's functions          |
        !          2674:    | (such as a->A::f).          |             | (such as b->A::f)             |
        !          2675:     --------------------------------------------------------------------
        !          2676:                                        | B's new virtual functions     |
        !          2677:                                        | (not defined in A.)           |
        !          2678:                                         -------------------------------
        !          2679:                                        | All of B's functions          |
        !          2680:                                        | (such as b->B::f)             |
        !          2681:                                         -------------------------------
        !          2682: 
        !          2683:    this allows the program to make references to any function, virtual
        !          2684:    or otherwise in a type-consistent manner.  */
        !          2685: 
        !          2686: tree
        !          2687: finish_struct (t, list_of_fieldlists, warn_anon)
        !          2688:      tree t;
        !          2689:      tree list_of_fieldlists;
        !          2690:      int warn_anon;
        !          2691: {
        !          2692:   extern int interface_only, interface_unknown;
        !          2693: 
        !          2694:   int old;
        !          2695:   int round_up_size = 1;
        !          2696: 
        !          2697:   enum tree_code code = TREE_CODE (t);
        !          2698:   register tree x, last_x, method_vec;
        !          2699:   int needs_virtual_dtor;
        !          2700:   tree name = TYPE_NAME (t), fields, fn_fields, *tail;
        !          2701:   tree *tail_user_methods = &CLASSTYPE_METHODS (t);
        !          2702:   enum access_type access;
        !          2703:   int all_virtual;
        !          2704:   int has_virtual;
        !          2705:   int max_has_virtual;
        !          2706:   tree pending_virtuals = NULL_TREE;
        !          2707:   tree abstract_virtuals = NULL_TREE;
        !          2708:   tree vfield;
        !          2709:   tree vfields;
        !          2710:   int cant_have_default_ctor;
        !          2711:   int cant_have_const_ctor;
        !          2712:   int cant_synth_copy_ctor;
        !          2713:   int cant_synth_asn_ref;
        !          2714:   int no_const_asn_ref;
        !          2715: 
        !          2716:   /* The index of the first base class which has virtual
        !          2717:      functions.  Only applied to non-virtual baseclasses.  */
        !          2718:   int first_vfn_base_index;
        !          2719: 
        !          2720:   int n_baseclasses;
        !          2721:   int any_default_members = 0;
        !          2722:   int const_sans_init = 0;
        !          2723:   int ref_sans_init = 0;
        !          2724:   int nonprivate_method = 0;
        !          2725:   tree t_binfo = TYPE_BINFO (t);
        !          2726:   tree access_decls = NULL_TREE;
        !          2727: 
        !          2728:   if (TREE_CODE (name) == TYPE_DECL)
        !          2729:     {
        !          2730: #if 0                          /* Maybe later.  -jason  */
        !          2731:       struct tinst_level *til = tinst_for_decl();
        !          2732: 
        !          2733:       if (til)
        !          2734:        {
        !          2735:          DECL_SOURCE_FILE (name) = til->file;
        !          2736:          if (DECL_SOURCE_LINE (name))
        !          2737:            DECL_SOURCE_LINE (name) = til->line;
        !          2738:        }
        !          2739:       else
        !          2740: #endif
        !          2741:        {
        !          2742:          extern int lineno;
        !          2743:          
        !          2744:          DECL_SOURCE_FILE (name) = input_filename;
        !          2745:          /* For TYPE_DECL that are not typedefs (those marked with a line
        !          2746:             number of zero, we don't want to mark them as real typedefs.
        !          2747:             If this fails one needs to make sure real typedefs have a
        !          2748:             previous line number, even if it is wrong, that way the below
        !          2749:             will fill in the right line number.  (mrs) */
        !          2750:          if (DECL_SOURCE_LINE (name))
        !          2751:            DECL_SOURCE_LINE (name) = lineno;
        !          2752:          CLASSTYPE_SOURCE_LINE (t) = lineno;
        !          2753:        }
        !          2754:       name = DECL_NAME (name);
        !          2755:     }
        !          2756: 
        !          2757:   if (warn_anon && code != UNION_TYPE && ANON_AGGRNAME_P (name))
        !          2758:     pedwarn ("anonymous class type not used to declare any objects");
        !          2759: 
        !          2760:   if (TYPE_SIZE (t))
        !          2761:     {
        !          2762:       if (IS_AGGR_TYPE (t))
        !          2763:        cp_error ("redefinition of `%#T'", t);
        !          2764:       else
        !          2765:        my_friendly_abort (172);
        !          2766:       popclass (0);
        !          2767:       return t;
        !          2768:     }
        !          2769: 
        !          2770:   /* Append the fields we need for constructing signature tables.  */
        !          2771:   if (IS_SIGNATURE (t))
        !          2772:     append_signature_fields (list_of_fieldlists);
        !          2773: 
        !          2774:   GNU_xref_decl (current_function_decl, t);
        !          2775: 
        !          2776:   /* If this type was previously laid out as a forward reference,
        !          2777:      make sure we lay it out again.  */
        !          2778: 
        !          2779:   TYPE_SIZE (t) = NULL_TREE;
        !          2780:   CLASSTYPE_GOT_SEMICOLON (t) = 0;
        !          2781: 
        !          2782: #if 0
        !          2783:   /* This is in general too late to do this.  I moved the main case up to
        !          2784:      left_curly, what else needs to move?  */
        !          2785:   if (! IS_SIGNATURE (t))
        !          2786:     {
        !          2787:       my_friendly_assert (CLASSTYPE_INTERFACE_ONLY (t) == interface_only, 999);
        !          2788:       my_friendly_assert (CLASSTYPE_INTERFACE_KNOWN (t) == ! interface_unknown, 999);
        !          2789:     }
        !          2790: #endif
        !          2791: 
        !          2792:   if (flag_dossier)
        !          2793:     build_t_desc (t, 0);
        !          2794: 
        !          2795:   TYPE_BINFO (t) = NULL_TREE;
        !          2796: 
        !          2797:   old = suspend_momentary ();
        !          2798: 
        !          2799:   /* Install struct as DECL_FIELD_CONTEXT of each field decl.
        !          2800:      Also process specified field sizes.
        !          2801:      Set DECL_FIELD_SIZE to the specified size, or 0 if none specified.
        !          2802:      The specified size is found in the DECL_INITIAL.
        !          2803:      Store 0 there, except for ": 0" fields (so we can find them
        !          2804:      and delete them, below).  */
        !          2805: 
        !          2806:   if (t_binfo && BINFO_BASETYPES (t_binfo))
        !          2807:     n_baseclasses = TREE_VEC_LENGTH (BINFO_BASETYPES (t_binfo));
        !          2808:   else
        !          2809:     n_baseclasses = 0;
        !          2810: 
        !          2811:   if (n_baseclasses > 0)
        !          2812:     {
        !          2813:       struct base_info base_info;
        !          2814: 
        !          2815:       /* If using multiple inheritance, this may cause variants of our
        !          2816:         basetypes to be used (instead of their canonical forms).  */
        !          2817:       fields = layout_basetypes (t, BINFO_BASETYPES (t_binfo));
        !          2818:       last_x = tree_last (fields);
        !          2819: 
        !          2820:       first_vfn_base_index = finish_base_struct (t, &base_info, t_binfo);
        !          2821:       /* Remember where we got our vfield from */
        !          2822:       CLASSTYPE_VFIELD_PARENT (t) = first_vfn_base_index;
        !          2823:       has_virtual = base_info.has_virtual;
        !          2824:       max_has_virtual = base_info.max_has_virtual;
        !          2825:       CLASSTYPE_N_SUPERCLASSES (t) += base_info.n_ancestors;
        !          2826:       vfield = base_info.vfield;
        !          2827:       vfields = base_info.vfields;
        !          2828:       cant_have_default_ctor = base_info.cant_have_default_ctor;
        !          2829:       cant_have_const_ctor = base_info.cant_have_const_ctor;
        !          2830:       cant_synth_copy_ctor = base_info.cant_synth_copy_ctor;
        !          2831:       cant_synth_asn_ref = base_info.cant_synth_asn_ref;
        !          2832:       no_const_asn_ref = base_info.no_const_asn_ref;
        !          2833:       needs_virtual_dtor = base_info.needs_virtual_dtor;
        !          2834:       n_baseclasses = TREE_VEC_LENGTH (BINFO_BASETYPES (t_binfo));
        !          2835:     }
        !          2836:   else
        !          2837:     {
        !          2838:       first_vfn_base_index = -1;
        !          2839:       has_virtual = 0;
        !          2840:       max_has_virtual = has_virtual;
        !          2841:       vfield = NULL_TREE;
        !          2842:       vfields = NULL_TREE;
        !          2843:       fields = NULL_TREE;
        !          2844:       last_x = NULL_TREE;
        !          2845:       cant_have_default_ctor = 0;
        !          2846:       cant_have_const_ctor = 0;
        !          2847:       cant_synth_copy_ctor = 0;
        !          2848:       cant_synth_asn_ref = 0;
        !          2849:       no_const_asn_ref = 0;
        !          2850:       needs_virtual_dtor = 0;
        !          2851:     }
        !          2852: 
        !          2853: #if 0
        !          2854:   /* Both of these should be done before now.  */
        !          2855:   if (write_virtuals == 3 && CLASSTYPE_INTERFACE_KNOWN (t)
        !          2856:       && ! IS_SIGNATURE (t))
        !          2857:     {
        !          2858:       my_friendly_assert (CLASSTYPE_INTERFACE_ONLY (t) == interface_only, 999);
        !          2859:       my_friendly_assert (CLASSTYPE_VTABLE_NEEDS_WRITING (t) == ! interface_only, 999);
        !          2860:     }
        !          2861: #endif
        !          2862: 
        !          2863:   /* The three of these are approximations which may later be
        !          2864:      modified.  Needed at this point to make add_virtual_function
        !          2865:      and modify_vtable_entries work.  */
        !          2866:   TREE_CHAIN (t_binfo) = TYPE_BINFO (t);
        !          2867:   TYPE_BINFO (t) = t_binfo;
        !          2868:   CLASSTYPE_VFIELDS (t) = vfields;
        !          2869:   CLASSTYPE_VFIELD (t) = vfield;
        !          2870: 
        !          2871:   tail = &fn_fields;
        !          2872:   if (last_x && list_of_fieldlists)
        !          2873:     TREE_CHAIN (last_x) = TREE_VALUE (list_of_fieldlists);
        !          2874: 
        !          2875:   if (IS_SIGNATURE (t))
        !          2876:     all_virtual = 0;
        !          2877:   else if (flag_all_virtual == 1 && TYPE_OVERLOADS_METHOD_CALL_EXPR (t))
        !          2878:     all_virtual = 1;
        !          2879:   else
        !          2880:     all_virtual = 0;
        !          2881: 
        !          2882:   /* For signatures, we made all methods `public' in the parser and
        !          2883:      reported an error if a access specifier was used.  */
        !          2884:   if (CLASSTYPE_DECLARED_CLASS (t) == 0)
        !          2885:     {
        !          2886:       nonprivate_method = 1;
        !          2887:       if (list_of_fieldlists
        !          2888:          && TREE_PURPOSE (list_of_fieldlists) == (tree)access_default)
        !          2889:        TREE_PURPOSE (list_of_fieldlists) = (tree)access_public;
        !          2890:     }
        !          2891:   else if (list_of_fieldlists
        !          2892:           && TREE_PURPOSE (list_of_fieldlists) == (tree)access_default)
        !          2893:     TREE_PURPOSE (list_of_fieldlists) = (tree)access_private;
        !          2894: 
        !          2895:   while (list_of_fieldlists)
        !          2896:     {
        !          2897:       access = (enum access_type)TREE_PURPOSE (list_of_fieldlists);
        !          2898: 
        !          2899:       for (x = TREE_VALUE (list_of_fieldlists); x; x = TREE_CHAIN (x))
        !          2900:        {
        !          2901:          TREE_PRIVATE (x) = access == access_private;
        !          2902:          TREE_PROTECTED (x) = access == access_protected;
        !          2903:          GNU_xref_member (current_class_name, x);
        !          2904: 
        !          2905:           if (TREE_CODE (x) == TYPE_DECL)
        !          2906:             {
        !          2907:              /* Make sure we set this up.  In find_scoped_type, it explicitly
        !          2908:                 looks for a TYPE_DECL in the TYPE_FIELDS list.  If we don't
        !          2909:                 do this here, we'll miss including this TYPE_DECL in the
        !          2910:                 list.  */
        !          2911:              if (! fields)
        !          2912:                fields = x;
        !          2913:              last_x = x;
        !          2914:              continue;
        !          2915:            }
        !          2916: 
        !          2917:          /* Check for inconsistent use of this name in the class body.
        !          2918:              Enums, types and static vars have already been checked.  */
        !          2919:          if (TREE_CODE (x) != CONST_DECL && TREE_CODE (x) != VAR_DECL)
        !          2920:            {
        !          2921:              tree name = DECL_NAME (x);
        !          2922:              tree icv;
        !          2923: 
        !          2924:              /* Don't get confused by access decls.  */
        !          2925:              if (name && TREE_CODE (name) == IDENTIFIER_NODE)
        !          2926:                icv = IDENTIFIER_CLASS_VALUE (name);
        !          2927:              else
        !          2928:                icv = NULL_TREE;
        !          2929: 
        !          2930:              if (icv
        !          2931:                  /* Don't complain about constructors.  */
        !          2932:                  && name != constructor_name (current_class_type)
        !          2933:                  /* Or inherited names.  */
        !          2934:                  && id_in_current_class (name)
        !          2935:                  /* Or shadowed tags.  */
        !          2936:                  && !(TREE_CODE (icv) == TYPE_DECL
        !          2937:                       && DECL_CONTEXT (icv) == t))
        !          2938:                {
        !          2939:                  cp_error_at ("declaration of identifier `%D' as `%+#D'",
        !          2940:                               name, x);
        !          2941:                  cp_error_at ("conflicts with other use in class as `%#D'",
        !          2942:                               icv);
        !          2943:                }
        !          2944:            }
        !          2945: 
        !          2946:          if (TREE_CODE (x) == FUNCTION_DECL)
        !          2947:            {
        !          2948:              nonprivate_method |= ! TREE_PRIVATE (x);
        !          2949: 
        !          2950:              /* If this was an evil function, don't keep it in class.  */
        !          2951:              if (IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (x)))
        !          2952:                continue;
        !          2953: 
        !          2954:              if (last_x)
        !          2955:                TREE_CHAIN (last_x) = TREE_CHAIN (x);
        !          2956:              /* Link x onto end of fn_fields and CLASSTYPE_METHODS. */
        !          2957:              *tail = x;
        !          2958:              tail = &TREE_CHAIN (x);
        !          2959:              *tail_user_methods = x;
        !          2960:              tail_user_methods = &DECL_NEXT_METHOD (x);
        !          2961: 
        !          2962:              DECL_CLASS_CONTEXT (x) = t;
        !          2963: 
        !          2964:              DECL_FIELD_SIZE (x) = 0;
        !          2965: 
        !          2966:              /* The name of the field is the original field name
        !          2967:                 Save this in auxiliary field for later overloading.  */
        !          2968:              if (DECL_VINDEX (x)
        !          2969:                  || (all_virtual == 1 && ! DECL_CONSTRUCTOR_P (x)))
        !          2970:                {
        !          2971:                   pending_virtuals = add_virtual_function (pending_virtuals,
        !          2972:                                                            &has_virtual, x, t);
        !          2973:                   if (DECL_ABSTRACT_VIRTUAL_P (x))
        !          2974:                     abstract_virtuals = tree_cons (NULL_TREE, x, abstract_virtuals);
        !          2975:                }
        !          2976:              continue;
        !          2977:            }
        !          2978: 
        !          2979:          /* Handle access declarations.  */
        !          2980:          if (DECL_NAME (x) && TREE_CODE (DECL_NAME (x)) == SCOPE_REF)
        !          2981:            {
        !          2982:              tree fdecl = TREE_OPERAND (DECL_NAME (x), 1);
        !          2983: 
        !          2984:              if (last_x)
        !          2985:                TREE_CHAIN (last_x) = TREE_CHAIN (x);
        !          2986:              access_decls = tree_cons ((tree) access, fdecl, access_decls);
        !          2987:              continue;
        !          2988:            }
        !          2989: 
        !          2990:          /* If we've gotten this far, it's a data member, possibly static,
        !          2991:             or an enumerator. */
        !          2992: 
        !          2993:          DECL_FIELD_CONTEXT (x) = t;
        !          2994: 
        !          2995:          /* ``A local class cannot have static data members.'' ARM 9.4 */
        !          2996:          if (current_function_decl && TREE_STATIC (x))
        !          2997:            cp_error_at ("field `%D' in local class cannot be static", x);
        !          2998: 
        !          2999:          /* Perform error checking that did not get done in
        !          3000:              grokdeclarator.  */
        !          3001:          if (TREE_CODE (TREE_TYPE (x)) == FUNCTION_TYPE)
        !          3002:            {
        !          3003:              cp_error_at ("field `%D' invalidly declared function type",
        !          3004:                        x);
        !          3005:              TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x));
        !          3006:            }
        !          3007:          else if (TREE_CODE (TREE_TYPE (x)) == METHOD_TYPE)
        !          3008:            {
        !          3009:              cp_error_at ("field `%D' invalidly declared method type", x);
        !          3010:                  TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x));
        !          3011:            }
        !          3012:          else if (TREE_CODE (TREE_TYPE (x)) == OFFSET_TYPE)
        !          3013:            {
        !          3014:              cp_error_at ("field `%D' invalidly declared offset type", x);
        !          3015:              TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x));
        !          3016:            }
        !          3017: 
        !          3018:          if (DECL_NAME (x) == constructor_name (t))
        !          3019:            cant_have_default_ctor = cant_synth_copy_ctor = 1;
        !          3020: 
        !          3021:          if (TREE_TYPE (x) == error_mark_node)
        !          3022:            continue;
        !          3023:          
        !          3024:          if (! fields)
        !          3025:            fields = x;
        !          3026:          last_x = x;
        !          3027: 
        !          3028:          DECL_FIELD_SIZE (x) = 0;
        !          3029: 
        !          3030:          /* When this goes into scope, it will be a non-local reference.  */
        !          3031:          DECL_NONLOCAL (x) = 1;
        !          3032: 
        !          3033:          if (TREE_CODE (x) == CONST_DECL)
        !          3034:            continue;
        !          3035: 
        !          3036:          if (TREE_CODE (x) == VAR_DECL)
        !          3037:            {
        !          3038:              if (TREE_CODE (t) == UNION_TYPE)
        !          3039:                /* Unions cannot have static members.  */
        !          3040:                cp_error_at ("field `%D' declared static in union", x);
        !          3041:              
        !          3042:              continue;
        !          3043:            }
        !          3044: 
        !          3045:          /* Now it can only be a FIELD_DECL.  */
        !          3046: 
        !          3047:          /* If this is of reference type, check if it needs an init.
        !          3048:             Also do a little ANSI jig if necessary.  */
        !          3049:          if (TREE_CODE (TREE_TYPE (x)) == REFERENCE_TYPE)
        !          3050:            {
        !          3051:              if (DECL_INITIAL (x) == NULL_TREE)
        !          3052:                ref_sans_init = 1;
        !          3053: 
        !          3054:              /* ARM $12.6.2: [A member initializer list] (or, for an
        !          3055:                 aggregate, initialization by a brace-enclosed list) is the
        !          3056:                 only way to initialize nonstatic const and reference
        !          3057:                 members.  */
        !          3058:              cant_synth_asn_ref = 1;
        !          3059:              cant_have_default_ctor = 1;
        !          3060:              TYPE_HAS_COMPLEX_INIT_REF (t) = 1;
        !          3061: 
        !          3062:              if (! TYPE_HAS_CONSTRUCTOR (t) && extra_warnings)
        !          3063:                {
        !          3064:                  if (DECL_NAME (x))
        !          3065:                    cp_warning_at ("non-static reference `%#D' in class without a constructor", x);
        !          3066:                  else
        !          3067:                    cp_warning_at ("non-static reference in class without a constructor", x);
        !          3068:                }
        !          3069:            }
        !          3070: 
        !          3071:          /* If any field is const, the structure type is pseudo-const.  */
        !          3072:          if (TREE_READONLY (x))
        !          3073:            {
        !          3074:              C_TYPE_FIELDS_READONLY (t) = 1;
        !          3075:              if (DECL_INITIAL (x) == NULL_TREE)
        !          3076:                const_sans_init = 1;
        !          3077: 
        !          3078:              /* ARM $12.6.2: [A member initializer list] (or, for an
        !          3079:                 aggregate, initialization by a brace-enclosed list) is the
        !          3080:                 only way to initialize nonstatic const and reference
        !          3081:                 members.  */
        !          3082:              cant_synth_asn_ref = 1;
        !          3083:              cant_have_default_ctor = 1;
        !          3084:              TYPE_HAS_COMPLEX_INIT_REF (t) = 1;
        !          3085: 
        !          3086:              if (! TYPE_HAS_CONSTRUCTOR (t) && !IS_SIGNATURE (t)
        !          3087:                  && extra_warnings)
        !          3088:                {
        !          3089:                  if (DECL_NAME (x))
        !          3090:                    cp_warning_at ("non-static const member `%#D' in class without a constructor", x);
        !          3091:                  else
        !          3092:                    cp_warning_at ("non-static const member in class without a constructor", x);
        !          3093:                }
        !          3094:            }
        !          3095:          else
        !          3096:            {
        !          3097:              /* A field that is pseudo-const makes the structure
        !          3098:                 likewise.  */
        !          3099:              tree t1 = TREE_TYPE (x);
        !          3100:              while (TREE_CODE (t1) == ARRAY_TYPE)
        !          3101:                t1 = TREE_TYPE (t1);
        !          3102:              if (IS_AGGR_TYPE (t1))
        !          3103:                {
        !          3104:                  if (C_TYPE_FIELDS_READONLY (t1))
        !          3105:                    C_TYPE_FIELDS_READONLY (t) = 1;
        !          3106:                  if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (t1))
        !          3107:                    const_sans_init = 1;
        !          3108:                }
        !          3109:            }
        !          3110: 
        !          3111:          /* We set DECL_BIT_FIELD tentatively in grokbitfield.
        !          3112:             If the type and width are valid, we'll keep it set.
        !          3113:             Otherwise, the flag is cleared.  */
        !          3114:          if (DECL_BIT_FIELD (x))
        !          3115:            {
        !          3116:              DECL_BIT_FIELD (x) = 0;
        !          3117:              /* Invalid bit-field size done by grokfield.  */
        !          3118:              /* Detect invalid bit-field type.  */
        !          3119:              if (DECL_INITIAL (x)
        !          3120:                  && ! INTEGRAL_TYPE_P (TREE_TYPE (x)))
        !          3121:                {
        !          3122:                  cp_error_at ("bit-field `%#D' with non-integral type", x);
        !          3123:                  DECL_INITIAL (x) = NULL;
        !          3124:                }
        !          3125: 
        !          3126:              /* Detect and ignore out of range field width.  */
        !          3127:              if (DECL_INITIAL (x))
        !          3128:                {
        !          3129:                  register int width = TREE_INT_CST_LOW (DECL_INITIAL (x));
        !          3130: 
        !          3131:                  if (width < 0)
        !          3132:                    {
        !          3133:                      DECL_INITIAL (x) = NULL;
        !          3134:                      cp_error_at ("negative width in bit-field `%D'", x);
        !          3135:                    }
        !          3136:                  else if (width == 0 && DECL_NAME (x) != 0)
        !          3137:                    {
        !          3138:                      DECL_INITIAL (x) = NULL;
        !          3139:                      cp_error_at ("zero width for bit-field `%D'", x);
        !          3140:                    }
        !          3141:                  else if ((unsigned)width > TYPE_PRECISION (TREE_TYPE (x)))
        !          3142:                    {
        !          3143:                      DECL_INITIAL (x) = NULL;
        !          3144:                      cp_error_at ("width of `%D' exceeds its type", x);
        !          3145:                    }
        !          3146:                }
        !          3147: 
        !          3148:              /* Process valid field width.  */
        !          3149:              if (DECL_INITIAL (x))
        !          3150:                {
        !          3151:                  register int width = TREE_INT_CST_LOW (DECL_INITIAL (x));
        !          3152: 
        !          3153:                  if (width == 0)
        !          3154:                    {
        !          3155: #ifdef EMPTY_FIELD_BOUNDARY
        !          3156:                      /* field size 0 => mark following field as "aligned" */
        !          3157:                      if (TREE_CHAIN (x))
        !          3158:                        DECL_ALIGN (TREE_CHAIN (x))
        !          3159:                          = MAX (DECL_ALIGN (TREE_CHAIN (x)), EMPTY_FIELD_BOUNDARY);
        !          3160:                      /* field of size 0 at the end => round up the size.  */
        !          3161:                      else
        !          3162:                        round_up_size = EMPTY_FIELD_BOUNDARY;
        !          3163: #endif
        !          3164: #ifdef PCC_BITFIELD_TYPE_MATTERS
        !          3165:                      DECL_ALIGN (x) = MAX (DECL_ALIGN (x),
        !          3166:                                            TYPE_ALIGN (TREE_TYPE (x)));
        !          3167: #endif
        !          3168:                    }
        !          3169:                  else
        !          3170:                    {
        !          3171:                      DECL_INITIAL (x) = NULL_TREE;
        !          3172:                      DECL_FIELD_SIZE (x) = width;
        !          3173:                      DECL_BIT_FIELD (x) = 1;
        !          3174:                      /* Traditionally a bit field is unsigned
        !          3175:                         even if declared signed.  */
        !          3176:                      if (flag_traditional
        !          3177:                          && TREE_CODE (TREE_TYPE (x)) == INTEGER_TYPE)
        !          3178:                        TREE_TYPE (x) = unsigned_type_node;
        !          3179:                    }
        !          3180:                }
        !          3181:              else
        !          3182:                /* Non-bit-fields are aligned for their type.  */
        !          3183:                DECL_ALIGN (x) = MAX (DECL_ALIGN (x), TYPE_ALIGN (TREE_TYPE (x)));
        !          3184:            }
        !          3185:          else
        !          3186:            {
        !          3187:              tree type = TREE_TYPE (x);
        !          3188: 
        !          3189:              if (TREE_CODE (type) == ARRAY_TYPE)
        !          3190:                type = TREE_TYPE (type);
        !          3191: 
        !          3192:              if (TYPE_LANG_SPECIFIC (type) && ! ANON_UNION_P (x)
        !          3193:                  && ! TYPE_PTRMEMFUNC_P (type))
        !          3194:                {
        !          3195:                  /* Never let anything with uninheritable virtuals
        !          3196:                     make it through without complaint.  */
        !          3197:                  if (CLASSTYPE_ABSTRACT_VIRTUALS (type))
        !          3198:                    abstract_virtuals_error (x, type);
        !          3199:                      
        !          3200:                  /* Don't let signatures make it through either.  */
        !          3201:                  if (IS_SIGNATURE (type))
        !          3202:                    signature_error (x, type);
        !          3203:                      
        !          3204:                  if (code == UNION_TYPE)
        !          3205:                    {
        !          3206:                      char *fie = NULL;
        !          3207:                      if (TYPE_NEEDS_CONSTRUCTING (type))
        !          3208:                        fie = "constructor";
        !          3209:                      else if (TYPE_NEEDS_DESTRUCTOR (type))
        !          3210:                        fie = "destructor";
        !          3211:                      else if (TYPE_HAS_REAL_ASSIGNMENT (type))
        !          3212:                        fie = "assignment operator";
        !          3213:                      if (fie)
        !          3214:                        cp_error_at ("member `%#D' with %s not allowed in union", x,
        !          3215:                                     fie);
        !          3216:                    }
        !          3217:                  else
        !          3218:                    {
        !          3219:                      TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (type);
        !          3220:                      TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_NEEDS_DESTRUCTOR (type);
        !          3221:                      TYPE_HAS_COMPLEX_ASSIGN_REF (t) |= TYPE_HAS_COMPLEX_ASSIGN_REF (type);
        !          3222:                      TYPE_HAS_COMPLEX_INIT_REF (t)
        !          3223:                        |= (TYPE_HAS_COMPLEX_INIT_REF (type)
        !          3224:                            || TYPE_NEEDS_CONSTRUCTING (type));
        !          3225:                    }
        !          3226: 
        !          3227:                  if (! TYPE_HAS_INIT_REF (type)
        !          3228:                      || (TYPE_HAS_NONPUBLIC_CTOR (type)
        !          3229:                          && ! is_friend (t, type)))
        !          3230:                    cant_synth_copy_ctor = 1;
        !          3231:                  else if (!TYPE_HAS_CONST_INIT_REF (type))
        !          3232:                    cant_have_const_ctor = 1;
        !          3233: 
        !          3234:                  if (! TYPE_HAS_ASSIGN_REF (type)
        !          3235:                      || (TYPE_HAS_NONPUBLIC_ASSIGN_REF (type)
        !          3236:                          && ! is_friend (t, type)))
        !          3237:                    cant_synth_asn_ref = 1;
        !          3238:                  else if (!TYPE_HAS_CONST_ASSIGN_REF (type))
        !          3239:                    no_const_asn_ref = 1;
        !          3240: 
        !          3241:                  if (TYPE_HAS_CONSTRUCTOR (type)
        !          3242:                      && ! TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
        !          3243:                    {
        !          3244:                      cant_have_default_ctor = 1;
        !          3245:                      if (! TYPE_HAS_CONSTRUCTOR (t))
        !          3246:                        {
        !          3247:                          if (DECL_NAME (x))
        !          3248:                            cp_pedwarn_at ("member `%#D' with only non-default constructor", x);
        !          3249:                          else
        !          3250:                            cp_pedwarn_at ("member with only non-default constructor", x);
        !          3251:                          cp_pedwarn_at ("in class without a constructor",
        !          3252:                                         x);
        !          3253:                        }
        !          3254:                    }
        !          3255:                }
        !          3256:              if (DECL_INITIAL (x) != NULL_TREE)
        !          3257:                {
        !          3258:                  /* `build_class_init_list' does not recognize
        !          3259:                      non-FIELD_DECLs.  */
        !          3260:                  if (code == UNION_TYPE && any_default_members != 0)
        !          3261:                    cp_error_at ("multiple fields in union `%T' initialized");
        !          3262:                  any_default_members = 1;
        !          3263:                }
        !          3264:            }
        !          3265:        }
        !          3266:       list_of_fieldlists = TREE_CHAIN (list_of_fieldlists);
        !          3267:       /* link the tail while we have it! */
        !          3268:       if (last_x)
        !          3269:        {
        !          3270:          TREE_CHAIN (last_x) = NULL_TREE;
        !          3271: 
        !          3272:          if (list_of_fieldlists
        !          3273:              && TREE_VALUE (list_of_fieldlists)
        !          3274:              && TREE_CODE (TREE_VALUE (list_of_fieldlists)) != FUNCTION_DECL)
        !          3275:            TREE_CHAIN (last_x) = TREE_VALUE (list_of_fieldlists);
        !          3276:        }
        !          3277:     }
        !          3278: 
        !          3279:   /* If this type has any constant members which did not come
        !          3280:      with their own initialization, mark that fact here.  It is
        !          3281:      not an error here, since such types can be saved either by their
        !          3282:      constructors, or by fortuitous initialization.  */
        !          3283:   CLASSTYPE_READONLY_FIELDS_NEED_INIT (t) = const_sans_init;
        !          3284:   CLASSTYPE_REF_FIELDS_NEED_INIT (t) = ref_sans_init;
        !          3285:   CLASSTYPE_ABSTRACT_VIRTUALS (t) = abstract_virtuals;
        !          3286: 
        !          3287:   /* Synthesize any needed methods.  Note that methods will be synthesized
        !          3288:      for anonymous unions; grok_x_components undoes that.  */
        !          3289: 
        !          3290:   if (TYPE_NEEDS_DESTRUCTOR (t) && !TYPE_HAS_DESTRUCTOR (t)
        !          3291:       && !IS_SIGNATURE (t))
        !          3292:     {
        !          3293:       /* Here we must cons up a destructor on the fly.  */
        !          3294:       tree dtor = cons_up_default_function (t, name, needs_virtual_dtor != 0);
        !          3295: 
        !          3296:       /* If we couldn't make it work, then pretend we didn't need it.  */
        !          3297:       if (dtor == void_type_node)
        !          3298:        TYPE_NEEDS_DESTRUCTOR (t) = 0;
        !          3299:       else
        !          3300:        {
        !          3301:          /* Link dtor onto end of fn_fields. */
        !          3302:          *tail = dtor;
        !          3303:          tail = &TREE_CHAIN (dtor);
        !          3304: 
        !          3305:          if (DECL_VINDEX (dtor) == NULL_TREE
        !          3306:              && ! CLASSTYPE_DECLARED_EXCEPTION (t)
        !          3307:              && (needs_virtual_dtor
        !          3308:                  || pending_virtuals != NULL_TREE
        !          3309:                  || pending_hard_virtuals != NULL_TREE))
        !          3310:            DECL_VINDEX (dtor) = error_mark_node;
        !          3311:          if (DECL_VINDEX (dtor))
        !          3312:            pending_virtuals = add_virtual_function (pending_virtuals,
        !          3313:                                                     &has_virtual, dtor, t);
        !          3314:          nonprivate_method = 1;
        !          3315:        }
        !          3316:     }
        !          3317: 
        !          3318:   *tail = NULL_TREE;
        !          3319:   *tail_user_methods = NULL_TREE;
        !          3320: 
        !          3321:   TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_HAS_DESTRUCTOR (t);
        !          3322: 
        !          3323:   if (! fn_fields)
        !          3324:     nonprivate_method = 1;
        !          3325: 
        !          3326:   TYPE_HAS_COMPLEX_INIT_REF (t)
        !          3327:     |= (TYPE_HAS_INIT_REF (t) || TYPE_USES_VIRTUAL_BASECLASSES (t)
        !          3328:        || has_virtual || any_default_members || first_vfn_base_index >= 0);
        !          3329:   TYPE_NEEDS_CONSTRUCTING (t)
        !          3330:     |= (TYPE_HAS_CONSTRUCTOR (t) || TYPE_USES_VIRTUAL_BASECLASSES (t)
        !          3331:        || has_virtual || any_default_members || first_vfn_base_index >= 0);
        !          3332: 
        !          3333:   /* ARM $12.1: A default constructor will be generated for a class X
        !          3334:      only if no constructor has been declared for class X.  So we
        !          3335:      check TYPE_HAS_CONSTRUCTOR also, to make sure we don't generate
        !          3336:      one if they declared a constructor in this class.  */
        !          3337:   if (! TYPE_HAS_CONSTRUCTOR (t) && ! cant_have_default_ctor
        !          3338:       && ! IS_SIGNATURE (t))
        !          3339:     {
        !          3340:       tree default_fn = cons_up_default_function (t, name, 2);
        !          3341:       TREE_CHAIN (default_fn) = fn_fields;
        !          3342:       fn_fields = default_fn;
        !          3343:     }
        !          3344: 
        !          3345:   /* Create default copy constructor, if needed.  */
        !          3346:   if (! TYPE_HAS_INIT_REF (t) && ! cant_synth_copy_ctor
        !          3347:       && ! IS_SIGNATURE (t))
        !          3348:     {
        !          3349:       /* ARM 12.18: You get either X(X&) or X(const X&), but
        !          3350:         not both.  --Chip  */
        !          3351:       tree default_fn = cons_up_default_function (t, name,
        !          3352:                                                  3 + cant_have_const_ctor);
        !          3353:       TREE_CHAIN (default_fn) = fn_fields;
        !          3354:       fn_fields = default_fn;
        !          3355:     }
        !          3356: 
        !          3357:   TYPE_HAS_REAL_ASSIGNMENT (t) |= TYPE_HAS_ASSIGNMENT (t);
        !          3358:   TYPE_HAS_REAL_ASSIGN_REF (t) |= TYPE_HAS_ASSIGN_REF (t);
        !          3359:   TYPE_HAS_COMPLEX_ASSIGN_REF (t)
        !          3360:     |= (TYPE_HAS_ASSIGN_REF (t) || TYPE_USES_VIRTUAL_BASECLASSES (t)
        !          3361:        || has_virtual || first_vfn_base_index >= 0);
        !          3362: 
        !          3363:   if (! TYPE_HAS_ASSIGN_REF (t) && ! cant_synth_asn_ref
        !          3364:       && ! IS_SIGNATURE (t))
        !          3365:     {
        !          3366:       tree default_fn = cons_up_default_function (t, name,
        !          3367:                                                  5 + no_const_asn_ref);
        !          3368:       TREE_CHAIN (default_fn) = fn_fields;
        !          3369:       fn_fields = default_fn;
        !          3370:     }
        !          3371: 
        !          3372:   if (fn_fields)
        !          3373:     {
        !          3374:       method_vec = finish_struct_methods (t, fn_fields, nonprivate_method);
        !          3375: 
        !          3376:       if (TYPE_HAS_CONSTRUCTOR (t)
        !          3377:          && ! CLASSTYPE_DECLARED_EXCEPTION (t)
        !          3378:          && CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE
        !          3379:          && DECL_FRIENDLIST (TYPE_NAME (t)) == NULL_TREE)
        !          3380:        {
        !          3381:          int nonprivate_ctor = 0;
        !          3382:          tree ctor;
        !          3383: 
        !          3384:          for (ctor = TREE_VEC_ELT (method_vec, 0);
        !          3385:               ctor;
        !          3386:               ctor = DECL_CHAIN (ctor))
        !          3387:            if (! TREE_PRIVATE (ctor))
        !          3388:              {
        !          3389:                nonprivate_ctor = 1;
        !          3390:                break;
        !          3391:              }
        !          3392: 
        !          3393:          if (nonprivate_ctor == 0 && warn_ctor_dtor_privacy)
        !          3394:            cp_warning ("`%#T' only defines private constructors and has no friends",
        !          3395:                        t);
        !          3396:        }
        !          3397:     }
        !          3398:   else
        !          3399:     {
        !          3400:       method_vec = 0;
        !          3401: 
        !          3402:       /* Just in case these got accidentally
        !          3403:         filled in by syntax errors.  */
        !          3404:       TYPE_HAS_CONSTRUCTOR (t) = 0;
        !          3405:       TYPE_HAS_DESTRUCTOR (t) = 0;
        !          3406:     }
        !          3407: 
        !          3408:   {
        !          3409:     int n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0;
        !          3410:     
        !          3411:     for (access_decls = nreverse (access_decls); access_decls;
        !          3412:         access_decls = TREE_CHAIN (access_decls))
        !          3413:       {
        !          3414:        tree fdecl = TREE_VALUE (access_decls);
        !          3415:        tree flist = NULL_TREE;
        !          3416:        tree name;
        !          3417:        enum access_type access = (enum access_type)TREE_PURPOSE(access_decls);
        !          3418:        int i = TREE_VEC_ELT (method_vec, 0) ? 0 : 1;
        !          3419:        tree tmp;
        !          3420: 
        !          3421:        if (TREE_CODE (fdecl) == TREE_LIST)
        !          3422:          {
        !          3423:            flist = fdecl;
        !          3424:            fdecl = TREE_VALUE (flist);
        !          3425:          }
        !          3426: 
        !          3427:        name = DECL_NAME (fdecl);
        !          3428: 
        !          3429:        for (; i < n_methods; i++)
        !          3430:          if (DECL_NAME (TREE_VEC_ELT (method_vec, i)) == name)
        !          3431:            {
        !          3432:              cp_error ("cannot adjust access to `%#D' in `%#T'", fdecl, t);
        !          3433:              cp_error_at ("  because of local method `%#D' with same name",
        !          3434:                           TREE_VEC_ELT (method_vec, i));
        !          3435:              fdecl = NULL_TREE;
        !          3436:              break;
        !          3437:            }
        !          3438: 
        !          3439:        if (! fdecl)
        !          3440:          continue;
        !          3441:        
        !          3442:        for (tmp = fields; tmp; tmp = TREE_CHAIN (tmp))
        !          3443:          if (DECL_NAME (tmp) == name)
        !          3444:            {
        !          3445:              cp_error ("cannot adjust access to `%#D' in `%#T'", fdecl, t);
        !          3446:              cp_error_at ("  because of local field `%#D' with same name", tmp);
        !          3447:              fdecl = NULL_TREE;
        !          3448:              break;
        !          3449:            }
        !          3450: 
        !          3451:        if (!fdecl)
        !          3452:          continue;
        !          3453:        
        !          3454:        /* Make type T see field decl FDECL with access ACCESS.*/
        !          3455:        if (flist)
        !          3456:          {
        !          3457:            fdecl = TREE_VALUE (flist);
        !          3458:            while (fdecl)
        !          3459:              {
        !          3460:                if (alter_access (t, fdecl, access) == 0)
        !          3461:                  break;
        !          3462:                fdecl = DECL_CHAIN (fdecl);
        !          3463:              }
        !          3464:          }
        !          3465:        else
        !          3466:          alter_access (t, fdecl, access);
        !          3467:       }
        !          3468:     
        !          3469:   }
        !          3470: 
        !          3471:   if (vfield == NULL_TREE && has_virtual)
        !          3472:     {
        !          3473:       /* We build this decl with ptr_type_node, and
        !          3474:         change the type when we know what it should be.  */
        !          3475:       vfield = build_lang_field_decl (FIELD_DECL, get_vfield_name (t),
        !          3476:                                      ptr_type_node);
        !          3477:       /* If you change any of the below, take a look at all the
        !          3478:         other VFIELD_BASEs and VTABLE_BASEs in the code, and change
        !          3479:         them too. */
        !          3480:       DECL_ASSEMBLER_NAME (vfield) = get_identifier (VFIELD_BASE);
        !          3481:       CLASSTYPE_VFIELD (t) = vfield;
        !          3482:       DECL_VIRTUAL_P (vfield) = 1;
        !          3483:       DECL_FIELD_CONTEXT (vfield) = t;
        !          3484:       DECL_CLASS_CONTEXT (vfield) = t;
        !          3485:       DECL_FCONTEXT (vfield) = t;
        !          3486:       DECL_FIELD_SIZE (vfield) = 0;
        !          3487:       DECL_ALIGN (vfield) = TYPE_ALIGN (ptr_type_node);
        !          3488:       if (CLASSTYPE_DOSSIER (t))
        !          3489:        {
        !          3490:          /* vfield is always first entry in structure.  */
        !          3491:          TREE_CHAIN (vfield) = fields;
        !          3492:          fields = vfield;
        !          3493:        }
        !          3494:       else if (last_x)
        !          3495:        {
        !          3496:          my_friendly_assert (TREE_CHAIN (last_x) == NULL_TREE, 175);
        !          3497:          TREE_CHAIN (last_x) = vfield;
        !          3498:          last_x = vfield;
        !          3499:        }
        !          3500:       else
        !          3501:        fields = vfield;
        !          3502:       vfields = chainon (vfields, CLASSTYPE_AS_LIST (t));
        !          3503:     }
        !          3504: 
        !          3505:   /* Now DECL_INITIAL is null on all members except for zero-width bit-fields.
        !          3506:      And they have already done their work.
        !          3507: 
        !          3508:      C++: maybe we will support default field initialization some day...  */
        !          3509: 
        !          3510:   /* Delete all zero-width bit-fields from the front of the fieldlist */
        !          3511:   while (fields && DECL_BIT_FIELD (fields)
        !          3512:         && DECL_INITIAL (fields))
        !          3513:     fields = TREE_CHAIN (fields);
        !          3514:   /* Delete all such fields from the rest of the fields.  */
        !          3515:   for (x = fields; x;)
        !          3516:     {
        !          3517:       if (TREE_CHAIN (x) && DECL_BIT_FIELD (TREE_CHAIN (x))
        !          3518:          && DECL_INITIAL (TREE_CHAIN (x)))
        !          3519:        TREE_CHAIN (x) = TREE_CHAIN (TREE_CHAIN (x));
        !          3520:       else
        !          3521:        x = TREE_CHAIN (x);
        !          3522:     }
        !          3523:   /* Delete all duplicate fields from the fields */
        !          3524:   delete_duplicate_fields (fields);
        !          3525: 
        !          3526:   /* Catch function/field name conflict.  We don't need to do this for a
        !          3527:      signature, since it can only contain the fields constructed in
        !          3528:      append_signature_fields.  */
        !          3529:   if (! IS_SIGNATURE (t))
        !          3530:     {
        !          3531:       int n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0;
        !          3532:       for (x = fields; x; x = TREE_CHAIN (x))
        !          3533:        {
        !          3534:          tree name = DECL_NAME (x);
        !          3535:          int i = /*TREE_VEC_ELT (method_vec, 0) ? 0 : */ 1;
        !          3536:          for (; i < n_methods; ++i)
        !          3537:            if (DECL_NAME (TREE_VEC_ELT (method_vec, i)) == name)
        !          3538:              {
        !          3539:                cp_error_at ("data member `%#D' conflicts with", x);
        !          3540:                cp_error_at ("function member `%#D'",
        !          3541:                             TREE_VEC_ELT (method_vec, i));
        !          3542:                break;
        !          3543:              }
        !          3544:        }
        !          3545:     }
        !          3546: 
        !          3547:   /* Now we have the final fieldlist for the data fields.  Record it,
        !          3548:      then lay out the structure or union (including the fields).  */
        !          3549: 
        !          3550:   TYPE_FIELDS (t) = fields;
        !          3551: 
        !          3552:   /* If there's a :0 field at the end, round the size to the
        !          3553:      EMPTY_FIELD_BOUNDARY.  */
        !          3554:   TYPE_ALIGN (t) = round_up_size;
        !          3555: 
        !          3556:   /* Pass layout information about base classes to layout_type, if any.  */
        !          3557: 
        !          3558:   {
        !          3559:     tree field;
        !          3560:     for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
        !          3561:       {
        !          3562:        if (TREE_STATIC (field))
        !          3563:          continue;
        !          3564:        if (TREE_CODE (field) != FIELD_DECL)
        !          3565:          continue;
        !          3566: 
        !          3567:        /* If this field is an anonymous union,
        !          3568:           give each union-member the same position as the union has.
        !          3569: 
        !          3570:           ??? This is a real kludge because it makes the structure
        !          3571:           of the types look strange.  This feature is only used by
        !          3572:           C++, which should have build_component_ref build two
        !          3573:           COMPONENT_REF operations, one for the union and one for
        !          3574:           the inner field.  We set the offset of this field to zero
        !          3575:           so that either the old or the correct method will work.
        !          3576:           Setting DECL_FIELD_CONTEXT is wrong unless the inner fields are
        !          3577:           moved into the type of this field, but nothing seems to break
        !          3578:           by doing this.  */
        !          3579: 
        !          3580:        if (DECL_NAME (field) == NULL_TREE
        !          3581:            && TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
        !          3582:          {
        !          3583:            tree uelt = TYPE_FIELDS (TREE_TYPE (field));
        !          3584:            for (; uelt; uelt = TREE_CHAIN (uelt))
        !          3585:              {
        !          3586:                if (TREE_CODE (uelt) != FIELD_DECL)
        !          3587:                  continue;
        !          3588: 
        !          3589:                DECL_FIELD_CONTEXT (uelt) = DECL_FIELD_CONTEXT (field);
        !          3590:                DECL_FIELD_BITPOS (uelt) = DECL_FIELD_BITPOS (field);
        !          3591:              }
        !          3592: 
        !          3593:            DECL_FIELD_BITPOS (field) = integer_zero_node;
        !          3594:          }
        !          3595:       }
        !          3596:   }
        !          3597: 
        !          3598:   if (n_baseclasses)
        !          3599:     {
        !          3600:       tree pseudo_basetype = TREE_TYPE (base_layout_decl);
        !          3601: 
        !          3602:       TREE_CHAIN (base_layout_decl) = TYPE_FIELDS (t);
        !          3603:       TYPE_FIELDS (t) = base_layout_decl;
        !          3604: 
        !          3605:       TYPE_SIZE (pseudo_basetype) = CLASSTYPE_SIZE (t);
        !          3606:       TYPE_MODE (pseudo_basetype) = TYPE_MODE (t);
        !          3607:       TYPE_ALIGN (pseudo_basetype) = CLASSTYPE_ALIGN (t);
        !          3608:       DECL_ALIGN (base_layout_decl) = TYPE_ALIGN (pseudo_basetype);
        !          3609:       /* Don't re-use old size. */
        !          3610:       DECL_SIZE (base_layout_decl) = NULL_TREE;
        !          3611:     }
        !          3612: 
        !          3613:   layout_type (t);
        !          3614: 
        !          3615:   {
        !          3616:     tree field;
        !          3617:     for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
        !          3618:       {
        !          3619:        if (TREE_STATIC (field))
        !          3620:          continue;
        !          3621:        if (TREE_CODE (field) != FIELD_DECL)
        !          3622:          continue;
        !          3623: 
        !          3624:        /* If this field is an anonymous union,
        !          3625:           give each union-member the same position as the union has.
        !          3626: 
        !          3627:           ??? This is a real kludge because it makes the structure
        !          3628:           of the types look strange.  This feature is only used by
        !          3629:           C++, which should have build_component_ref build two
        !          3630:           COMPONENT_REF operations, one for the union and one for
        !          3631:           the inner field.  We set the offset of this field to zero
        !          3632:           so that either the old or the correct method will work.
        !          3633:           Setting DECL_FIELD_CONTEXT is wrong unless the inner fields are
        !          3634:           moved into the type of this field, but nothing seems to break
        !          3635:           by doing this.  */
        !          3636: 
        !          3637:        if (DECL_NAME (field) == NULL_TREE
        !          3638:            && TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
        !          3639:          {
        !          3640:            tree uelt = TYPE_FIELDS (TREE_TYPE (field));
        !          3641:            for (; uelt; uelt = TREE_CHAIN (uelt))
        !          3642:              {
        !          3643:                if (TREE_CODE (uelt) != FIELD_DECL)
        !          3644:                  continue;
        !          3645: 
        !          3646:                DECL_FIELD_CONTEXT (uelt) = DECL_FIELD_CONTEXT (field);
        !          3647:                DECL_FIELD_BITPOS (uelt) = DECL_FIELD_BITPOS (field);
        !          3648:              }
        !          3649: 
        !          3650:            DECL_FIELD_BITPOS (field) = integer_zero_node;
        !          3651:          }
        !          3652:       }
        !          3653:   }
        !          3654: 
        !          3655:   if (n_baseclasses)
        !          3656:     TYPE_FIELDS (t) = TREE_CHAIN (TYPE_FIELDS (t));
        !          3657: 
        !          3658:   /* C++: do not let empty structures exist.  */
        !          3659:   if (integer_zerop (TYPE_SIZE (t)))
        !          3660:     TYPE_SIZE (t) = TYPE_SIZE (char_type_node);
        !          3661: 
        !          3662:   /* Set the TYPE_DECL for this type to contain the right
        !          3663:      value for DECL_OFFSET, so that we can use it as part
        !          3664:      of a COMPONENT_REF for multiple inheritance.  */
        !          3665: 
        !          3666:   if (TREE_CODE (TYPE_NAME (t)) == TYPE_DECL)
        !          3667:     layout_decl (TYPE_NAME (t), 0);
        !          3668: 
        !          3669:   /* Now fix up any virtual base class types that we left lying
        !          3670:      around.  We must get these done before we try to lay out the
        !          3671:      virtual function table.  */
        !          3672:   doing_hard_virtuals = 1;
        !          3673:   pending_hard_virtuals = nreverse (pending_hard_virtuals);
        !          3674: 
        !          3675:   if (TYPE_USES_VIRTUAL_BASECLASSES (t))
        !          3676:     {
        !          3677:       tree vbases;
        !          3678: 
        !          3679:       max_has_virtual = layout_vbasetypes (t, max_has_virtual);
        !          3680:       vbases = CLASSTYPE_VBASECLASSES (t);
        !          3681:       CLASSTYPE_N_VBASECLASSES (t) = list_length (vbases);
        !          3682: 
        !          3683:       while (vbases)
        !          3684:        {
        !          3685:          /* The rtti code should do this.  (mrs) */
        !          3686:          /* Update dossier info with offsets for virtual baseclasses.  */
        !          3687:          if (flag_dossier && ! BINFO_NEW_VTABLE_MARKED (vbases))
        !          3688:            prepare_fresh_vtable (vbases, t);
        !          3689:          vbases = TREE_CHAIN (vbases);
        !          3690:        }
        !          3691: 
        !          3692:       {
        !          3693:        /* Now fixup overrides of all functions in vtables from all
        !          3694:           direct or indirect virtual base classes.  */
        !          3695:        tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));
        !          3696:        int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
        !          3697: 
        !          3698:        for (i = 0; i < n_baseclasses; i++)
        !          3699:          {
        !          3700:            tree base_binfo = TREE_VEC_ELT (binfos, i);
        !          3701:            tree basetype = BINFO_TYPE (base_binfo);
        !          3702:            tree vbases;
        !          3703: 
        !          3704:            vbases = CLASSTYPE_VBASECLASSES (basetype);
        !          3705:            while (vbases)
        !          3706:              {
        !          3707:                merge_overrides (binfo_member (BINFO_TYPE (vbases),
        !          3708:                                               CLASSTYPE_VBASECLASSES (t)),
        !          3709:                                 vbases, 1, t);
        !          3710:                vbases = TREE_CHAIN (vbases);
        !          3711:              }
        !          3712:          }
        !          3713:        }
        !          3714: 
        !          3715:       /* Now fixup any virtual function entries from virtual bases
        !          3716:         that have different deltas.  */
        !          3717:       vbases = CLASSTYPE_VBASECLASSES (t);
        !          3718:       while (vbases)
        !          3719:        {
        !          3720:          /* We might be able to shorten the ammount of work we do by
        !          3721:             only doing this for vtables that come from virtual bases
        !          3722:             that have differing offsets, but don't want to miss any
        !          3723:             entries.  */
        !          3724:          fixup_vtable_deltas (vbases, t);
        !          3725:          vbases = TREE_CHAIN (vbases);
        !          3726:        }
        !          3727:     }
        !          3728: 
        !          3729:   /* Set up the DECL_FIELD_BITPOS of the vfield if we need to, as we
        !          3730:      might need to know it for setting up the offsets in the vtable
        !          3731:      (or in thunks) below.  */
        !          3732:   if (vfield != NULL_TREE
        !          3733:       && DECL_FIELD_CONTEXT (vfield) != t)
        !          3734:     {
        !          3735:       tree binfo = get_binfo (DECL_FIELD_CONTEXT (vfield), t, 0);
        !          3736:       tree offset = BINFO_OFFSET (binfo);
        !          3737: 
        !          3738:       vfield = copy_node (vfield);
        !          3739:       copy_lang_decl (vfield);
        !          3740: 
        !          3741:       if (! integer_zerop (offset))
        !          3742:        offset = size_binop (MULT_EXPR, offset, size_int (BITS_PER_UNIT));
        !          3743:       DECL_FIELD_CONTEXT (vfield) = t;
        !          3744:       DECL_CLASS_CONTEXT (vfield) = t;
        !          3745:       DECL_FIELD_BITPOS (vfield)
        !          3746:        = size_binop (PLUS_EXPR, offset, DECL_FIELD_BITPOS (vfield));
        !          3747:       CLASSTYPE_VFIELD (t) = vfield;
        !          3748:     }
        !          3749:     
        !          3750: #ifdef NOTQUITE
        !          3751:   cp_warning ("Doing hard virtuals for %T...", t);
        !          3752: #endif
        !          3753:   while (pending_hard_virtuals)
        !          3754:     {
        !          3755:       modify_all_vtables (t,
        !          3756:                          TREE_PURPOSE (pending_hard_virtuals),
        !          3757:                          TREE_VALUE (pending_hard_virtuals));
        !          3758:       pending_hard_virtuals = TREE_CHAIN (pending_hard_virtuals);
        !          3759:     }
        !          3760:   doing_hard_virtuals = 0;
        !          3761: 
        !          3762:   /* Under our model of GC, every C++ class gets its own virtual
        !          3763:      function table, at least virtually.  */
        !          3764:   if (pending_virtuals || CLASSTYPE_DOSSIER (t))
        !          3765:     {
        !          3766:       pending_virtuals = nreverse (pending_virtuals);
        !          3767:       /* We must enter these virtuals into the table.  */
        !          3768:       if (first_vfn_base_index < 0)
        !          3769:        {
        !          3770:          if (flag_dossier)
        !          3771:            pending_virtuals = tree_cons (NULL_TREE,
        !          3772:                                          build_vtable_entry (integer_zero_node,
        !          3773:                                                              build_t_desc (t, 0)),
        !          3774:                                          pending_virtuals);
        !          3775:          pending_virtuals = tree_cons (NULL_TREE, the_null_vtable_entry,
        !          3776:                                        pending_virtuals);
        !          3777:          build_vtable (NULL_TREE, t);
        !          3778:        }
        !          3779:       else
        !          3780:        {
        !          3781:          /* Here we know enough to change the type of our virtual
        !          3782:             function table, but we will wait until later this function.  */
        !          3783: 
        !          3784:          if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t)))
        !          3785:            build_vtable (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (t), first_vfn_base_index), t);
        !          3786: 
        !          3787:          /* Update the dossier pointer for this class.  */
        !          3788:          if (flag_dossier)
        !          3789:            TREE_VALUE (TREE_CHAIN (TYPE_BINFO_VIRTUALS (t)))
        !          3790:              = build_vtable_entry (integer_zero_node, build_t_desc (t, 0));
        !          3791:        }
        !          3792: 
        !          3793:       /* If this type has basetypes with constructors, then those
        !          3794:         constructors might clobber the virtual function table.  But
        !          3795:         they don't if the derived class shares the exact vtable of the base
        !          3796:         class.  */
        !          3797: 
        !          3798:       CLASSTYPE_NEEDS_VIRTUAL_REINIT (t) = 1;
        !          3799:     }
        !          3800:   else if (first_vfn_base_index >= 0)
        !          3801:     {
        !          3802:       tree binfo = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (t), first_vfn_base_index);
        !          3803:       /* This class contributes nothing new to the virtual function
        !          3804:         table.  However, it may have declared functions which
        !          3805:         went into the virtual function table "inherited" from the
        !          3806:         base class.  If so, we grab a copy of those updated functions,
        !          3807:         and pretend they are ours.  */
        !          3808: 
        !          3809:       /* See if we should steal the virtual info from base class.  */
        !          3810:       if (TYPE_BINFO_VTABLE (t) == NULL_TREE)
        !          3811:        TYPE_BINFO_VTABLE (t) = BINFO_VTABLE (binfo);
        !          3812:       if (TYPE_BINFO_VIRTUALS (t) == NULL_TREE)
        !          3813:        TYPE_BINFO_VIRTUALS (t) = BINFO_VIRTUALS (binfo);
        !          3814:       if (TYPE_BINFO_VTABLE (t) != BINFO_VTABLE (binfo))
        !          3815:        CLASSTYPE_NEEDS_VIRTUAL_REINIT (t) = 1;
        !          3816:     }
        !          3817: 
        !          3818:   if (has_virtual > max_has_virtual)
        !          3819:     max_has_virtual = has_virtual;
        !          3820:   if (max_has_virtual || first_vfn_base_index >= 0)
        !          3821:     {
        !          3822:       TYPE_VIRTUAL_P (t) = 1;
        !          3823:       CLASSTYPE_VSIZE (t) = has_virtual;
        !          3824:       if (first_vfn_base_index >= 0)
        !          3825:        {
        !          3826:          if (pending_virtuals)
        !          3827:            TYPE_BINFO_VIRTUALS (t) = chainon (TYPE_BINFO_VIRTUALS (t),
        !          3828:                                                pending_virtuals);
        !          3829:        }
        !          3830:       else if (has_virtual)
        !          3831:        {
        !          3832:          TYPE_BINFO_VIRTUALS (t) = pending_virtuals;
        !          3833:          if (write_virtuals >= 0)
        !          3834:            DECL_VIRTUAL_P (TYPE_BINFO_VTABLE (t)) = 1;
        !          3835:        }
        !          3836:     }
        !          3837: 
        !          3838:   /* Now lay out the virtual function table.  */
        !          3839:   if (has_virtual)
        !          3840:     {
        !          3841:       tree atype, itype;
        !          3842: 
        !          3843:       if (TREE_TYPE (vfield) == ptr_type_node)
        !          3844:        {
        !          3845:          /* We must create a pointer to this table because
        !          3846:             the one inherited from base class does not exist.
        !          3847:             We will fill in the type when we know what it
        !          3848:             should really be.  Use `size_int' so values are memoized
        !          3849:             in common cases.  */
        !          3850:          itype = build_index_type (size_int (has_virtual));
        !          3851:          atype = build_array_type (vtable_entry_type, itype);
        !          3852:          layout_type (atype);
        !          3853:          TREE_TYPE (vfield) = build_pointer_type (atype);
        !          3854:        }
        !          3855:       else
        !          3856:        {
        !          3857:          atype = TREE_TYPE (TREE_TYPE (vfield));
        !          3858: 
        !          3859:          if (has_virtual != TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (atype))))
        !          3860:            {
        !          3861:              /* We must extend (or create) the boundaries on this array,
        !          3862:                 because we picked up virtual functions from multiple
        !          3863:                 base classes.  */
        !          3864:              itype = build_index_type (size_int (has_virtual));
        !          3865:              atype = build_array_type (vtable_entry_type, itype);
        !          3866:              layout_type (atype);
        !          3867:              vfield = copy_node (vfield);
        !          3868:              TREE_TYPE (vfield) = build_pointer_type (atype);
        !          3869:            }
        !          3870:        }
        !          3871: 
        !          3872:       CLASSTYPE_VFIELD (t) = vfield;
        !          3873:       if (TREE_TYPE (TYPE_BINFO_VTABLE (t)) != atype)
        !          3874:        {
        !          3875:          TREE_TYPE (TYPE_BINFO_VTABLE (t)) = atype;
        !          3876:          layout_decl (TYPE_BINFO_VTABLE (t), 0);
        !          3877:          /* At one time the vtable info was grabbed 2 words at a time.  This
        !          3878:             fails on sparc unless you have 8-byte alignment.  (tiemann) */
        !          3879:          DECL_ALIGN (TYPE_BINFO_VTABLE (t))
        !          3880:            = MAX (TYPE_ALIGN (double_type_node),
        !          3881:                   DECL_ALIGN (TYPE_BINFO_VTABLE (t)));
        !          3882:        }
        !          3883:     }
        !          3884:   else if (first_vfn_base_index >= 0)
        !          3885:     CLASSTYPE_VFIELD (t) = vfield;
        !          3886:   CLASSTYPE_VFIELDS (t) = vfields;
        !          3887: 
        !          3888:   finish_struct_bits (t, max_has_virtual);
        !          3889: 
        !          3890:   /* Promote each bit-field's type to int if it is narrower than that.
        !          3891:      There's more: complete the rtl for any static member objects which
        !          3892:      is of the same type we're working on.  */
        !          3893:   for (x = fields; x; x = TREE_CHAIN (x))
        !          3894:     {
        !          3895:       if (DECL_BIT_FIELD (x)
        !          3896:          && (C_PROMOTING_INTEGER_TYPE_P (TREE_TYPE (x))
        !          3897:              || DECL_FIELD_SIZE (x) < TYPE_PRECISION (integer_type_node)))
        !          3898:        {
        !          3899:          tree type = TREE_TYPE (x);
        !          3900: 
        !          3901:          /* Preserve unsignedness if traditional or if not really getting
        !          3902:             any wider.  */
        !          3903:          if (TREE_UNSIGNED (type)
        !          3904:              && (flag_traditional
        !          3905:                  ||
        !          3906:                  (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)
        !          3907:                   && DECL_FIELD_SIZE (x) == TYPE_PRECISION (integer_type_node))))
        !          3908:            TREE_TYPE (x) = unsigned_type_node;
        !          3909:          else
        !          3910:            TREE_TYPE (x) = integer_type_node;
        !          3911:        }
        !          3912: 
        !          3913:       if (TREE_CODE (x) == VAR_DECL && TREE_STATIC (x)
        !          3914:          && TREE_TYPE (x) == t)
        !          3915:        {
        !          3916:          DECL_MODE (x) = TYPE_MODE (t);
        !          3917:          make_decl_rtl (x, NULL, 0);
        !          3918:        }
        !          3919:     }
        !          3920: 
        !          3921:   /* Now add the tags, if any, to the list of TYPE_DECLs
        !          3922:      defined for this type.  */
        !          3923:   if (CLASSTYPE_TAGS (t))
        !          3924:     {
        !          3925:       x = CLASSTYPE_TAGS (t);
        !          3926:       last_x = tree_last (TYPE_FIELDS (t));
        !          3927:       while (x)
        !          3928:        {
        !          3929: #if 0 /* What's wrong with using the decl the type already has? */
        !          3930:          tree tag = build_decl (TYPE_DECL, TREE_PURPOSE (x), TREE_VALUE (x));
        !          3931:          DECL_CONTEXT (tag) = t;
        !          3932: #else
        !          3933:          tree tag = TYPE_NAME (TREE_VALUE (x));
        !          3934: #endif
        !          3935: 
        !          3936: #ifdef DWARF_DEBUGGING_INFO
        !          3937:          if (write_symbols == DWARF_DEBUG)
        !          3938:            {
        !          3939:              /* Notify dwarfout.c that this TYPE_DECL node represent a
        !          3940:                 gratuitous typedef.  */
        !          3941:              DECL_IGNORED_P (tag) = 1;
        !          3942:            }
        !          3943: #endif /* DWARF_DEBUGGING_INFO */
        !          3944: 
        !          3945:          TREE_NONLOCAL_FLAG (TREE_VALUE (x)) = 0;
        !          3946:          x = TREE_CHAIN (x);
        !          3947:          last_x = chainon (last_x, tag);
        !          3948:        }
        !          3949:       if (TYPE_FIELDS (t) == NULL_TREE)
        !          3950:        TYPE_FIELDS (t) = last_x;
        !          3951:       CLASSTYPE_LOCAL_TYPEDECLS (t) = 1;
        !          3952:     }
        !          3953: 
        !          3954:   if (TYPE_HAS_CONSTRUCTOR (t))
        !          3955:     {
        !          3956:       tree vfields = CLASSTYPE_VFIELDS (t);
        !          3957: 
        !          3958:       while (vfields)
        !          3959:        {
        !          3960:          /* Mark the fact that constructor for T
        !          3961:             could affect anybody inheriting from T
        !          3962:             who wants to initialize vtables for VFIELDS's type.  */
        !          3963:          if (VF_DERIVED_VALUE (vfields))
        !          3964:            TREE_ADDRESSABLE (vfields) = 1;
        !          3965:          vfields = TREE_CHAIN (vfields);
        !          3966:        }
        !          3967:       if (any_default_members != 0)
        !          3968:        build_class_init_list (t);
        !          3969:     }
        !          3970:   else if (TYPE_NEEDS_CONSTRUCTING (t))
        !          3971:     build_class_init_list (t);
        !          3972: 
        !          3973:   if (! CLASSTYPE_DECLARED_EXCEPTION (t) && ! IS_SIGNATURE (t))
        !          3974:     embrace_waiting_friends (t);
        !          3975: 
        !          3976:   /* Write out inline function definitions.  */
        !          3977:   do_inline_function_hair (t, CLASSTYPE_INLINE_FRIENDS (t));
        !          3978:   CLASSTYPE_INLINE_FRIENDS (t) = 0;
        !          3979: 
        !          3980:   if (CLASSTYPE_VSIZE (t) != 0)
        !          3981:     {
        !          3982:       if ((flag_this_is_variable & 1) == 0)
        !          3983:        {
        !          3984:          tree vtbl_ptr = build_decl (VAR_DECL, get_identifier (VPTR_NAME),
        !          3985:                                      TREE_TYPE (vfield));
        !          3986:          DECL_REGISTER (vtbl_ptr) = 1;
        !          3987:          CLASSTYPE_VTBL_PTR (t) = vtbl_ptr;
        !          3988:        }
        !          3989: #if 0
        !          3990:       /* This is now done above. */
        !          3991:       if (DECL_FIELD_CONTEXT (vfield) != t)
        !          3992:        {
        !          3993:          tree binfo = get_binfo (DECL_FIELD_CONTEXT (vfield), t, 0);
        !          3994:          tree offset = BINFO_OFFSET (binfo);
        !          3995: 
        !          3996:          vfield = copy_node (vfield);
        !          3997:          copy_lang_decl (vfield);
        !          3998: 
        !          3999:          if (! integer_zerop (offset))
        !          4000:            offset = size_binop (MULT_EXPR, offset, size_int (BITS_PER_UNIT));
        !          4001:          DECL_FIELD_CONTEXT (vfield) = t;
        !          4002:          DECL_CLASS_CONTEXT (vfield) = t;
        !          4003:          DECL_FIELD_BITPOS (vfield)
        !          4004:            = size_binop (PLUS_EXPR, offset, DECL_FIELD_BITPOS (vfield));
        !          4005:          CLASSTYPE_VFIELD (t) = vfield;
        !          4006:        }
        !          4007: #endif
        !          4008: 
        !          4009:       /* In addition to this one, all the other vfields should be listed. */
        !          4010:       /* Before that can be done, we have to have FIELD_DECLs for them, and
        !          4011:         a place to find them.  */
        !          4012:       TYPE_NONCOPIED_PARTS (t) = build_tree_list (default_conversion (TYPE_BINFO_VTABLE (t)), vfield);
        !          4013: 
        !          4014:       if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (t)
        !          4015:          && DECL_VINDEX (TREE_VEC_ELT (method_vec, 0)) == NULL_TREE)
        !          4016:        cp_warning ("`%#T' has virtual functions but non-virtual destructor",
        !          4017:                    t);
        !          4018:     }
        !          4019: 
        !          4020:   /* Make the rtl for any new vtables we have created, and unmark
        !          4021:      the base types we marked.  */
        !          4022:   finish_vtbls (TYPE_BINFO (t), 1, t);
        !          4023:   TYPE_BEING_DEFINED (t) = 0;
        !          4024: 
        !          4025:   if (flag_dossier && CLASSTYPE_VTABLE_NEEDS_WRITING (t))
        !          4026:     {
        !          4027:       tree variants;
        !          4028:       tree tdecl;
        !          4029: 
        !          4030:       /* Now instantiate its type descriptors.  */
        !          4031:       tdecl = TREE_OPERAND (build_t_desc (t, 1), 0);
        !          4032:       variants = TYPE_POINTER_TO (t);
        !          4033:       build_type_variant (variants, 1, 0);
        !          4034:       while (variants)
        !          4035:        {
        !          4036:          build_t_desc (variants, 1);
        !          4037:          variants = TYPE_NEXT_VARIANT (variants);
        !          4038:        }
        !          4039:       variants = build_reference_type (t);
        !          4040:       build_type_variant (variants, 1, 0);
        !          4041:       while (variants)
        !          4042:        {
        !          4043:          build_t_desc (variants, 1);
        !          4044:          variants = TYPE_NEXT_VARIANT (variants);
        !          4045:        }
        !          4046:       DECL_CONTEXT (tdecl) = t;
        !          4047:     }
        !          4048:   /* Still need to instantiate this C struct's type descriptor.  */
        !          4049:   else if (flag_dossier && ! CLASSTYPE_DOSSIER (t))
        !          4050:     build_t_desc (t, 1);
        !          4051: 
        !          4052: #if 0
        !          4053:   if (TYPE_NAME (t) && TYPE_IDENTIFIER (t))
        !          4054:     undo_template_name_overload (TYPE_IDENTIFIER (t), 1);
        !          4055: #endif
        !          4056:   if (current_class_type)
        !          4057:     popclass (0);
        !          4058:   else
        !          4059:     error ("trying to finish struct, but kicked out due to previous parse errors.");
        !          4060: 
        !          4061:   hack_incomplete_structures (t);
        !          4062: 
        !          4063:   resume_momentary (old);
        !          4064: 
        !          4065:   if (flag_cadillac)
        !          4066:     cadillac_finish_struct (t);
        !          4067: 
        !          4068: #if 0
        !          4069:   /* This has to be done after we have sorted out what to do with
        !          4070:      the enclosing type.  */
        !          4071:   if (write_symbols != DWARF_DEBUG)
        !          4072:     {
        !          4073:       /* Be smarter about nested classes here.  If a type is nested,
        !          4074:         only output it if we would output the enclosing type.  */
        !          4075:       if (DECL_CONTEXT (TYPE_NAME (t))
        !          4076:          && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (TYPE_NAME (t)))) == 't')
        !          4077:        DECL_IGNORED_P (TYPE_NAME (t)) = TREE_ASM_WRITTEN (TYPE_NAME (t));
        !          4078:     }
        !          4079: #endif
        !          4080: 
        !          4081:   if (write_symbols != DWARF_DEBUG)
        !          4082:     {
        !          4083:       /* If the type has methods, we want to think about cutting down
        !          4084:         the amount of symbol table stuff we output.  The value stored in
        !          4085:         the TYPE_DECL's DECL_IGNORED_P slot is a first approximation.
        !          4086:         For example, if a member function is seen and we decide to
        !          4087:         write out that member function, then we can change the value
        !          4088:         of the DECL_IGNORED_P slot, and the type will be output when
        !          4089:         that member function's debug info is written out.  */
        !          4090:       if (CLASSTYPE_METHOD_VEC (t))
        !          4091:        {
        !          4092:          extern tree pending_vtables;
        !          4093: 
        !          4094:          /* Don't output full info about any type
        !          4095:             which does not have its implementation defined here.  */
        !          4096:          if (TYPE_VIRTUAL_P (t) && write_virtuals == 2)
        !          4097:            TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t))
        !          4098:              = (value_member (TYPE_IDENTIFIER (t), pending_vtables) == 0);
        !          4099:          else if (CLASSTYPE_INTERFACE_ONLY (t))
        !          4100:            TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 1;
        !          4101:          else if (CLASSTYPE_INTERFACE_UNKNOWN (t))
        !          4102:            /* Only a first approximation!  */
        !          4103:            TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 1;
        !          4104:        }
        !          4105:       else if (CLASSTYPE_INTERFACE_ONLY (t))
        !          4106:        TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 1;
        !          4107:     }
        !          4108: 
        !          4109:   /* Finish debugging output for this type.  */
        !          4110:   rest_of_type_compilation (t, global_bindings_p ());
        !          4111: 
        !          4112:   return t;
        !          4113: }
        !          4114: 
        !          4115: /* Return non-zero if the effective type of INSTANCE is static.
        !          4116:    Used to determine whether the virtual function table is needed
        !          4117:    or not.
        !          4118: 
        !          4119:    *NONNULL is set iff INSTANCE can be known to be nonnull, regardless
        !          4120:    of our knowledge of its type.  */
        !          4121: int
        !          4122: resolves_to_fixed_type_p (instance, nonnull)
        !          4123:      tree instance;
        !          4124:      int *nonnull;
        !          4125: {
        !          4126:   switch (TREE_CODE (instance))
        !          4127:     {
        !          4128:     case INDIRECT_REF:
        !          4129:       /* Check that we are not going through a cast of some sort.  */
        !          4130:       if (TREE_TYPE (instance)
        !          4131:          == TREE_TYPE (TREE_TYPE (TREE_OPERAND (instance, 0))))
        !          4132:        instance = TREE_OPERAND (instance, 0);
        !          4133:       /* fall through...  */
        !          4134:     case CALL_EXPR:
        !          4135:       /* This is a call to a constructor, hence it's never zero.  */
        !          4136:       if (TREE_HAS_CONSTRUCTOR (instance))
        !          4137:        {
        !          4138:          if (nonnull)
        !          4139:            *nonnull = 1;
        !          4140:          return 1;
        !          4141:        }
        !          4142:       return 0;
        !          4143: 
        !          4144:     case SAVE_EXPR:
        !          4145:       /* This is a call to a constructor, hence it's never zero.  */
        !          4146:       if (TREE_HAS_CONSTRUCTOR (instance))
        !          4147:        {
        !          4148:          if (nonnull)
        !          4149:            *nonnull = 1;
        !          4150:          return 1;
        !          4151:        }
        !          4152:       return resolves_to_fixed_type_p (TREE_OPERAND (instance, 0), nonnull);
        !          4153: 
        !          4154:     case RTL_EXPR:
        !          4155:       /* This is a call to `new', hence it's never zero.  */
        !          4156:       if (TREE_CALLS_NEW (instance))
        !          4157:        {
        !          4158:          if (nonnull)
        !          4159:            *nonnull = 1;
        !          4160:          return 1;
        !          4161:        }
        !          4162:       return 0;
        !          4163: 
        !          4164:     case PLUS_EXPR:
        !          4165:     case MINUS_EXPR:
        !          4166:       if (TREE_CODE (TREE_OPERAND (instance, 1)) == INTEGER_CST)
        !          4167:        /* Propagate nonnull.  */
        !          4168:        resolves_to_fixed_type_p (TREE_OPERAND (instance, 0), nonnull);
        !          4169:       if (TREE_CODE (TREE_OPERAND (instance, 0)) == ADDR_EXPR)
        !          4170:        return resolves_to_fixed_type_p (TREE_OPERAND (instance, 0), nonnull);
        !          4171:       return 0;
        !          4172: 
        !          4173:     case NOP_EXPR:
        !          4174:     case CONVERT_EXPR:
        !          4175:       return resolves_to_fixed_type_p (TREE_OPERAND (instance, 0), nonnull);
        !          4176: 
        !          4177:     case ADDR_EXPR:
        !          4178:       if (nonnull)
        !          4179:        *nonnull = 1;
        !          4180:       return resolves_to_fixed_type_p (TREE_OPERAND (instance, 0), nonnull);
        !          4181: 
        !          4182:     case COMPONENT_REF:
        !          4183:       return resolves_to_fixed_type_p (TREE_OPERAND (instance, 1), nonnull);
        !          4184: 
        !          4185:     case WITH_CLEANUP_EXPR:
        !          4186:       if (TREE_CODE (TREE_OPERAND (instance, 0)) == ADDR_EXPR)
        !          4187:        return resolves_to_fixed_type_p (TREE_OPERAND (instance, 0), nonnull);
        !          4188:       /* fall through... */
        !          4189:     case VAR_DECL:
        !          4190:     case FIELD_DECL:
        !          4191:       if (TREE_CODE (TREE_TYPE (instance)) == ARRAY_TYPE
        !          4192:          && IS_AGGR_TYPE (TREE_TYPE (TREE_TYPE (instance))))
        !          4193:        {
        !          4194:          if (nonnull)
        !          4195:            *nonnull = 1;
        !          4196:          return 1;
        !          4197:        }
        !          4198:       /* fall through... */
        !          4199:     case TARGET_EXPR:
        !          4200:     case PARM_DECL:
        !          4201:       if (IS_AGGR_TYPE (TREE_TYPE (instance)))
        !          4202:        {
        !          4203:          if (nonnull)
        !          4204:            *nonnull = 1;
        !          4205:          return 1;
        !          4206:        }
        !          4207:       else if (nonnull)
        !          4208:        {
        !          4209:          if (instance == current_class_decl
        !          4210:              && flag_this_is_variable <= 0)
        !          4211:            {
        !          4212:              /* Some people still use `this = 0' inside destructors.  */
        !          4213:              *nonnull = ! DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (current_function_decl));
        !          4214:              /* In a constructor, we know our type.  */
        !          4215:              if (flag_this_is_variable < 0)
        !          4216:                return 1;
        !          4217:            }
        !          4218:          else if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)
        !          4219:            /* Reference variables should be references to objects.  */
        !          4220:            *nonnull = 1;
        !          4221:        }
        !          4222:       return 0;
        !          4223: 
        !          4224:     default:
        !          4225:       return 0;
        !          4226:     }
        !          4227: }
        !          4228: 
        !          4229: void
        !          4230: init_class_processing ()
        !          4231: {
        !          4232:   current_class_depth = 0;
        !          4233:   current_class_stacksize = 10;
        !          4234:   current_class_base = (tree *)xmalloc(current_class_stacksize * sizeof (tree));
        !          4235:   current_class_stack = current_class_base;
        !          4236: 
        !          4237:   current_lang_stacksize = 10;
        !          4238:   current_lang_base = (tree *)xmalloc(current_lang_stacksize * sizeof (tree));
        !          4239:   current_lang_stack = current_lang_base;
        !          4240: 
        !          4241:   /* Keep these values lying around.  */
        !          4242:   the_null_vtable_entry = build_vtable_entry (integer_zero_node, integer_zero_node);
        !          4243:   base_layout_decl = build_lang_field_decl (FIELD_DECL, NULL_TREE, error_mark_node);
        !          4244:   TREE_TYPE (base_layout_decl) = make_node (RECORD_TYPE);
        !          4245: 
        !          4246:   gcc_obstack_init (&class_obstack);
        !          4247: }
        !          4248: 
        !          4249: /* Set current scope to NAME. CODE tells us if this is a
        !          4250:    STRUCT, UNION, or ENUM environment.
        !          4251: 
        !          4252:    NAME may end up being NULL_TREE if this is an anonymous or
        !          4253:    late-bound struct (as in "struct { ... } foo;")  */
        !          4254: 
        !          4255: /* Set global variables CURRENT_CLASS_NAME and CURRENT_CLASS_TYPE to
        !          4256:    appropriate values, found by looking up the type definition of
        !          4257:    NAME (as a CODE).
        !          4258: 
        !          4259:    If MODIFY is 1, we set IDENTIFIER_CLASS_VALUE's of names
        !          4260:    which can be seen locally to the class.  They are shadowed by
        !          4261:    any subsequent local declaration (including parameter names).
        !          4262: 
        !          4263:    If MODIFY is 2, we set IDENTIFIER_CLASS_VALUE's of names
        !          4264:    which have static meaning (i.e., static members, static
        !          4265:    member functions, enum declarations, etc).
        !          4266: 
        !          4267:    If MODIFY is 3, we set IDENTIFIER_CLASS_VALUE of names
        !          4268:    which can be seen locally to the class (as in 1), but
        !          4269:    know that we are doing this for declaration purposes
        !          4270:    (i.e. friend foo::bar (int)).
        !          4271: 
        !          4272:    So that we may avoid calls to lookup_name, we cache the _TYPE
        !          4273:    nodes of local TYPE_DECLs in the TREE_TYPE field of the name.
        !          4274: 
        !          4275:    For multiple inheritance, we perform a two-pass depth-first search
        !          4276:    of the type lattice.  The first pass performs a pre-order search,
        !          4277:    marking types after the type has had its fields installed in
        !          4278:    the appropriate IDENTIFIER_CLASS_VALUE slot.  The second pass merely
        !          4279:    unmarks the marked types.  If a field or member function name
        !          4280:    appears in an ambiguous way, the IDENTIFIER_CLASS_VALUE of
        !          4281:    that name becomes `error_mark_node'.  */
        !          4282: 
        !          4283: void
        !          4284: pushclass (type, modify)
        !          4285:      tree type;
        !          4286:      int modify;
        !          4287: {
        !          4288:   push_memoized_context (type, modify);
        !          4289: 
        !          4290:   current_class_depth++;
        !          4291:   *current_class_stack++ = current_class_name;
        !          4292:   *current_class_stack++ = current_class_type;
        !          4293:   if (current_class_stack >= current_class_base + current_class_stacksize)
        !          4294:     {
        !          4295:       current_class_base =
        !          4296:        (tree *)xrealloc (current_class_base,
        !          4297:                          sizeof (tree) * (current_class_stacksize + 10));
        !          4298:       current_class_stack = current_class_base + current_class_stacksize;
        !          4299:       current_class_stacksize += 10;
        !          4300:     }
        !          4301: 
        !          4302:   current_class_name = TYPE_NAME (type);
        !          4303:   if (TREE_CODE (current_class_name) == TYPE_DECL)
        !          4304:     current_class_name = DECL_NAME (current_class_name);
        !          4305:   current_class_type = type;
        !          4306: 
        !          4307:   if (previous_class_type != NULL_TREE
        !          4308:       && (type != previous_class_type || TYPE_SIZE (previous_class_type) == NULL_TREE)
        !          4309:       && current_class_depth == 1)
        !          4310:     {
        !          4311:       /* Forcibly remove any old class remnants.  */
        !          4312:       popclass (-1);
        !          4313:       previous_class_type = NULL_TREE;
        !          4314:     }
        !          4315: 
        !          4316:   pushlevel_class ();
        !          4317: 
        !          4318:   if (modify)
        !          4319:     {
        !          4320:       tree tags;
        !          4321:       tree this_fndecl = current_function_decl;
        !          4322: 
        !          4323:       if (current_function_decl
        !          4324:          && DECL_CONTEXT (current_function_decl)
        !          4325:          && TREE_CODE (DECL_CONTEXT (current_function_decl)) == FUNCTION_DECL)
        !          4326:        current_function_decl = DECL_CONTEXT (current_function_decl);
        !          4327:       else
        !          4328:        current_function_decl = NULL_TREE;
        !          4329: 
        !          4330:       if (TREE_CODE (type) == UNINSTANTIATED_P_TYPE)
        !          4331:        declare_uninstantiated_type_level ();
        !          4332:       else if (type != previous_class_type || current_class_depth > 1)
        !          4333:        {
        !          4334:          build_mi_matrix (type);
        !          4335:          push_class_decls (type);
        !          4336:          free_mi_matrix ();
        !          4337:          if (current_class_depth == 1)
        !          4338:            previous_class_type = type;
        !          4339:        }
        !          4340:       else
        !          4341:        {
        !          4342:          tree item;
        !          4343: 
        !          4344:          /* Hooray, our cacheing was successful, let's just install the
        !          4345:             cached class_shadowed list, and walk through it to get the
        !          4346:             IDENTIFIER_TYPE_VALUEs correct.  */
        !          4347:          set_class_shadows (previous_class_values);
        !          4348:          for (item = previous_class_values; item; item = TREE_CHAIN (item))
        !          4349:            {
        !          4350:              tree id = TREE_PURPOSE (item);
        !          4351:              tree decl = IDENTIFIER_CLASS_VALUE (id);
        !          4352: 
        !          4353:              if (TREE_CODE (decl) == TYPE_DECL)
        !          4354:                set_identifier_type_value (id, TREE_TYPE (decl));
        !          4355:            }
        !          4356:          unuse_fields (type);
        !          4357:        }
        !          4358: 
        !          4359:       if (IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (type)))
        !          4360:        overload_template_name (current_class_name, 0);
        !          4361: 
        !          4362:       for (tags = CLASSTYPE_TAGS (type); tags; tags = TREE_CHAIN (tags))
        !          4363:        {
        !          4364:          TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 1;
        !          4365:          if (! TREE_PURPOSE (tags))
        !          4366:            continue;
        !          4367:          pushtag (TREE_PURPOSE (tags), TREE_VALUE (tags), 0);
        !          4368:        }
        !          4369: 
        !          4370:       current_function_decl = this_fndecl;
        !          4371:     }
        !          4372: 
        !          4373:   if (flag_cadillac)
        !          4374:     cadillac_push_class (type);
        !          4375: }
        !          4376:  
        !          4377: /* Get out of the current class scope. If we were in a class scope
        !          4378:    previously, that is the one popped to.  The flag MODIFY tells whether
        !          4379:    the current scope declarations needs to be modified as a result of
        !          4380:    popping to the previous scope.  0 is used for class definitions.  */
        !          4381: void
        !          4382: popclass (modify)
        !          4383:      int modify;
        !          4384: {
        !          4385:   if (flag_cadillac)
        !          4386:     cadillac_pop_class ();
        !          4387: 
        !          4388:   if (modify < 0)
        !          4389:     {
        !          4390:       /* Back this old class out completely.  */
        !          4391:       tree tags = CLASSTYPE_TAGS (previous_class_type);
        !          4392:       tree t;
        !          4393: 
        !          4394:       /* This code can be seen as a cache miss.  When we've cached a
        !          4395:         class' scope's bindings and we can't use them, we need to reset
        !          4396:         them.  This is it!  */
        !          4397:       for (t = previous_class_values; t; t = TREE_CHAIN (t))
        !          4398:        IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE;
        !          4399:       while (tags)
        !          4400:        {
        !          4401:          TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0;
        !          4402:          tags = TREE_CHAIN (tags);
        !          4403:        }
        !          4404:       goto ret;
        !          4405:     }
        !          4406: 
        !          4407:   if (modify)
        !          4408:     {
        !          4409:       /* Just remove from this class what didn't make
        !          4410:         it into IDENTIFIER_CLASS_VALUE.  */
        !          4411:       tree tags = CLASSTYPE_TAGS (current_class_type);
        !          4412: 
        !          4413:       while (tags)
        !          4414:        {
        !          4415:          TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0;
        !          4416:          tags = TREE_CHAIN (tags);
        !          4417:        }
        !          4418:       if (IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (current_class_type)))
        !          4419:        undo_template_name_overload (current_class_name, 0);
        !          4420:     }
        !          4421: 
        !          4422:   /* Force clearing of IDENTIFIER_CLASS_VALUEs after a class definition,
        !          4423:      since not all class decls make it there currently.  */
        !          4424:   poplevel_class (! modify);
        !          4425: 
        !          4426:   /* Since poplevel_class does the popping of class decls nowadays,
        !          4427:      this really only frees the obstack used for these decls.
        !          4428:      That's why it had to be moved down here.  */
        !          4429:   if (modify)
        !          4430:     pop_class_decls (current_class_type);
        !          4431: 
        !          4432:   current_class_depth--;
        !          4433:   current_class_type = *--current_class_stack;
        !          4434:   current_class_name = *--current_class_stack;
        !          4435: 
        !          4436:   if (current_class_type)
        !          4437:     {
        !          4438:       if (CLASSTYPE_VTBL_PTR (current_class_type))
        !          4439:        {
        !          4440:          current_vtable_decl
        !          4441:            = lookup_name (DECL_NAME (CLASSTYPE_VTBL_PTR (current_class_type)),
        !          4442:                           0);
        !          4443:          if (current_vtable_decl)
        !          4444:            current_vtable_decl = build_indirect_ref (current_vtable_decl,
        !          4445:                                                      NULL_PTR);
        !          4446:        }
        !          4447:       current_class_decl = lookup_name (this_identifier, 0);
        !          4448:       if (current_class_decl)
        !          4449:        {
        !          4450:          if (TREE_CODE (TREE_TYPE (current_class_decl)) == POINTER_TYPE)
        !          4451:            {
        !          4452:              tree temp;
        !          4453:              /* Can't call build_indirect_ref here, because it has special
        !          4454:                 logic to return C_C_D given this argument.  */
        !          4455:              C_C_D = build1 (INDIRECT_REF, current_class_type, current_class_decl);
        !          4456:              temp = TREE_TYPE (TREE_TYPE (current_class_decl));
        !          4457:              TREE_READONLY (C_C_D) = TYPE_READONLY (temp);
        !          4458:              TREE_SIDE_EFFECTS (C_C_D) = TYPE_VOLATILE (temp);
        !          4459:              TREE_THIS_VOLATILE (C_C_D) = TYPE_VOLATILE (temp);
        !          4460:            }
        !          4461:          else
        !          4462:            C_C_D = current_class_decl;
        !          4463:        }
        !          4464:       else
        !          4465:        C_C_D = NULL_TREE;
        !          4466:     }
        !          4467:   else
        !          4468:     {
        !          4469:       current_class_decl = NULL_TREE;
        !          4470:       current_vtable_decl = NULL_TREE;
        !          4471:       C_C_D = NULL_TREE;
        !          4472:     }
        !          4473: 
        !          4474:   pop_memoized_context (modify);
        !          4475: 
        !          4476:  ret:
        !          4477:   ;
        !          4478: }
        !          4479: 
        !          4480: /* When entering a class scope, all enclosing class scopes' names with
        !          4481:    static meaning (static variables, static functions, types and enumerators)
        !          4482:    have to be visible.  This recursive function calls pushclass for all
        !          4483:    enclosing class contexts until global or a local scope is reached.
        !          4484:    TYPE is the enclosed class and MODIFY is equivalent with the pushclass
        !          4485:    formal of the same name.  */
        !          4486: 
        !          4487: void
        !          4488: push_nested_class (type, modify)
        !          4489:      tree type;
        !          4490:      int modify;
        !          4491: {
        !          4492:   tree context;
        !          4493: 
        !          4494:   if (type == error_mark_node || ! IS_AGGR_TYPE (type))
        !          4495:     return;
        !          4496:   
        !          4497:   context = DECL_CONTEXT (TYPE_NAME (type));
        !          4498: 
        !          4499:   if (context && TREE_CODE (context) == RECORD_TYPE)
        !          4500:     push_nested_class (context, 2);
        !          4501:   pushclass (type, modify);
        !          4502: }
        !          4503: 
        !          4504: /* Undoes a push_nested_class call.  MODIFY is passed on to popclass.  */
        !          4505: 
        !          4506: void
        !          4507: pop_nested_class (modify)
        !          4508:      int modify;
        !          4509: {
        !          4510:   tree context = DECL_CONTEXT (TYPE_NAME (current_class_type));
        !          4511: 
        !          4512:   popclass (modify);
        !          4513:   if (context && TREE_CODE (context) == RECORD_TYPE)
        !          4514:     pop_nested_class (modify);
        !          4515: }
        !          4516: 
        !          4517: /* Set global variables CURRENT_LANG_NAME to appropriate value
        !          4518:    so that behavior of name-mangling machinery is correct.  */
        !          4519: 
        !          4520: void
        !          4521: push_lang_context (name)
        !          4522:      tree name;
        !          4523: {
        !          4524:   *current_lang_stack++ = current_lang_name;
        !          4525:   if (current_lang_stack >= current_lang_base + current_lang_stacksize)
        !          4526:     {
        !          4527:       current_lang_base =
        !          4528:        (tree *)xrealloc (current_lang_base,
        !          4529:                          sizeof (tree) * (current_lang_stacksize + 10));
        !          4530:       current_lang_stack = current_lang_base + current_lang_stacksize;
        !          4531:       current_lang_stacksize += 10;
        !          4532:     }
        !          4533: 
        !          4534:   if (name == lang_name_cplusplus)
        !          4535:     {
        !          4536:       strict_prototype = strict_prototypes_lang_cplusplus;
        !          4537:       current_lang_name = name;
        !          4538:     }
        !          4539:   else if (name == lang_name_c)
        !          4540:     {
        !          4541:       strict_prototype = strict_prototypes_lang_c;
        !          4542:       current_lang_name = name;
        !          4543:     }
        !          4544:   else
        !          4545:     error ("language string `\"%s\"' not recognized", IDENTIFIER_POINTER (name));
        !          4546: 
        !          4547:   if (flag_cadillac)
        !          4548:     cadillac_push_lang (name);
        !          4549: }
        !          4550:   
        !          4551: /* Get out of the current language scope.  */
        !          4552: void
        !          4553: pop_lang_context ()
        !          4554: {
        !          4555:   if (flag_cadillac)
        !          4556:     cadillac_pop_lang ();
        !          4557: 
        !          4558:   current_lang_name = *--current_lang_stack;
        !          4559:   if (current_lang_name == lang_name_cplusplus)
        !          4560:     strict_prototype = strict_prototypes_lang_cplusplus;
        !          4561:   else if (current_lang_name == lang_name_c)
        !          4562:     strict_prototype = strict_prototypes_lang_c;
        !          4563: }
        !          4564: 
        !          4565: int
        !          4566: root_lang_context_p ()
        !          4567: {
        !          4568:   return current_lang_stack == current_lang_base;
        !          4569: }
        !          4570: 
        !          4571: /* Type instantiation routines.  */
        !          4572: 
        !          4573: /* This function will instantiate the type of the expression given
        !          4574:    in RHS to match the type of LHSTYPE.  If LHSTYPE is NULL_TREE,
        !          4575:    or other errors exist, the TREE_TYPE of RHS will be ERROR_MARK_NODE.
        !          4576: 
        !          4577:    This function is used in build_modify_expr, convert_arguments,
        !          4578:    build_c_cast, and compute_conversion_costs.  */
        !          4579: tree
        !          4580: instantiate_type (lhstype, rhs, complain)
        !          4581:      tree lhstype, rhs;
        !          4582:      int complain;
        !          4583: {
        !          4584:   if (TREE_CODE (lhstype) == UNKNOWN_TYPE)
        !          4585:     {
        !          4586:       if (complain)
        !          4587:        error ("not enough type information");
        !          4588:       return error_mark_node;
        !          4589:     }
        !          4590: 
        !          4591:   if (TREE_TYPE (rhs) != NULL_TREE && ! (type_unknown_p (rhs)))
        !          4592:     return rhs;
        !          4593: 
        !          4594:   /* This should really only be used when attempting to distinguish
        !          4595:      what sort of a pointer to function we have.  For now, any
        !          4596:      arithmetic operation which is not supported on pointers
        !          4597:      is rejected as an error.  */
        !          4598: 
        !          4599:   switch (TREE_CODE (rhs))
        !          4600:     {
        !          4601:     case TYPE_EXPR:
        !          4602:     case CONVERT_EXPR:
        !          4603:     case SAVE_EXPR:
        !          4604:     case CONSTRUCTOR:
        !          4605:     case BUFFER_REF:
        !          4606:       my_friendly_abort (177);
        !          4607:       return error_mark_node;
        !          4608: 
        !          4609:     case INDIRECT_REF:
        !          4610:     case ARRAY_REF:
        !          4611:       TREE_TYPE (rhs) = lhstype;
        !          4612:       lhstype = build_pointer_type (lhstype);
        !          4613:       TREE_OPERAND (rhs, 0)
        !          4614:        = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
        !          4615:       if (TREE_OPERAND (rhs, 0) == error_mark_node)
        !          4616:        return error_mark_node;
        !          4617: 
        !          4618:       return rhs;
        !          4619: 
        !          4620:     case NOP_EXPR:
        !          4621:       rhs = copy_node (TREE_OPERAND (rhs, 0));
        !          4622:       TREE_TYPE (rhs) = unknown_type_node;
        !          4623:       return instantiate_type (lhstype, rhs, complain);
        !          4624: 
        !          4625:     case COMPONENT_REF:
        !          4626:       {
        !          4627:        tree field = TREE_OPERAND (rhs, 1);
        !          4628:        if (TREE_CODE (field) == TREE_LIST)
        !          4629:          {
        !          4630:            tree function = instantiate_type (lhstype, field, complain);
        !          4631:            if (function == error_mark_node)
        !          4632:              return error_mark_node;
        !          4633:            my_friendly_assert (TREE_CODE (function) == FUNCTION_DECL, 185);
        !          4634:            if (DECL_VINDEX (function))
        !          4635:              {
        !          4636:                tree base = TREE_OPERAND (rhs, 0);
        !          4637:                tree base_ptr = build_unary_op (ADDR_EXPR, base, 0);
        !          4638:                if (base_ptr == error_mark_node)
        !          4639:                  return error_mark_node;
        !          4640:                base_ptr = convert_pointer_to (DECL_CONTEXT (function), base_ptr);
        !          4641:                if (base_ptr == error_mark_node)
        !          4642:                  return error_mark_node;
        !          4643:                return build_vfn_ref (&base_ptr, base, DECL_VINDEX (function));
        !          4644:              }
        !          4645:            return function;
        !          4646:          }
        !          4647: 
        !          4648:        my_friendly_assert (TREE_CODE (field) == FIELD_DECL, 178);
        !          4649:        my_friendly_assert (!(TREE_CODE (TREE_TYPE (field)) == FUNCTION_TYPE
        !          4650:                              || TREE_CODE (TREE_TYPE (field)) == METHOD_TYPE),
        !          4651:                            179);
        !          4652: 
        !          4653:        TREE_TYPE (rhs) = lhstype;
        !          4654:        /* First look for an exact match  */
        !          4655: 
        !          4656:        while (field && TREE_TYPE (field) != lhstype)
        !          4657:          field = TREE_CHAIN (field);
        !          4658:        if (field)
        !          4659:          {
        !          4660:            TREE_OPERAND (rhs, 1) = field;
        !          4661:            return rhs;
        !          4662:          }
        !          4663: 
        !          4664:        /* No exact match found, look for a compatible function.  */
        !          4665:        field = TREE_OPERAND (rhs, 1);
        !          4666:        while (field && ! comptypes (lhstype, TREE_TYPE (field), 0))
        !          4667:          field = TREE_CHAIN (field);
        !          4668:        if (field)
        !          4669:          {
        !          4670:            TREE_OPERAND (rhs, 1) = field;
        !          4671:            field = TREE_CHAIN (field);
        !          4672:            while (field && ! comptypes (lhstype, TREE_TYPE (field), 0))
        !          4673:              field = TREE_CHAIN (field);
        !          4674:            if (field)
        !          4675:              {
        !          4676:                if (complain)
        !          4677:                  error ("ambiguous overload for COMPONENT_REF requested");
        !          4678:                return error_mark_node;
        !          4679:              }
        !          4680:          }
        !          4681:        else
        !          4682:          {
        !          4683:            if (complain)
        !          4684:              error ("no appropriate overload exists for COMPONENT_REF");
        !          4685:            return error_mark_node;
        !          4686:          }
        !          4687:        return rhs;
        !          4688:       }
        !          4689: 
        !          4690:     case TREE_LIST:
        !          4691:       {
        !          4692:        tree elem, baselink, name;
        !          4693:        int globals = overloaded_globals_p (rhs);
        !          4694: 
        !          4695: #if 0 /* obsolete */
        !          4696:        /* If there's only one function we know about, return that.  */
        !          4697:        if (globals > 0 && TREE_CHAIN (rhs) == NULL_TREE)
        !          4698:          return TREE_VALUE (rhs);
        !          4699: #endif
        !          4700: 
        !          4701:        /* First look for an exact match.  Search either overloaded
        !          4702:           functions or member functions.  May have to undo what
        !          4703:           `default_conversion' might do to lhstype.  */
        !          4704: 
        !          4705:        if (TREE_CODE (lhstype) == POINTER_TYPE)
        !          4706:          if (TREE_CODE (TREE_TYPE (lhstype)) == FUNCTION_TYPE
        !          4707:              || TREE_CODE (TREE_TYPE (lhstype)) == METHOD_TYPE)
        !          4708:            lhstype = TREE_TYPE (lhstype);
        !          4709:          else
        !          4710:            {
        !          4711:              if (complain)
        !          4712:                error ("invalid type combination for overload");
        !          4713:              return error_mark_node;
        !          4714:            }
        !          4715: 
        !          4716:        if (TREE_CODE (lhstype) != FUNCTION_TYPE && globals > 0)
        !          4717:          {
        !          4718:            if (complain)
        !          4719:              cp_error ("cannot resolve overloaded function `%D' based on non-function type",
        !          4720:                     TREE_PURPOSE (rhs));
        !          4721:            return error_mark_node;
        !          4722:          }
        !          4723: 
        !          4724:        if (globals > 0)
        !          4725:          {
        !          4726:            elem = get_first_fn (rhs);
        !          4727:            while (elem)
        !          4728:              if (! comptypes (lhstype, TREE_TYPE (elem), 1))
        !          4729:                elem = DECL_CHAIN (elem);
        !          4730:              else
        !          4731:                return elem;
        !          4732: 
        !          4733:            /* No exact match found, look for a compatible template.  */
        !          4734:            {
        !          4735:              tree save_elem = 0;
        !          4736:              for (elem = get_first_fn (rhs); elem; elem = DECL_CHAIN (elem))
        !          4737:                if (TREE_CODE (elem) == TEMPLATE_DECL)
        !          4738:                  {
        !          4739:                    int n = TREE_VEC_LENGTH (DECL_TEMPLATE_PARMS (elem));
        !          4740:                    tree *t = (tree *) alloca (sizeof (tree) * n);
        !          4741:                    int i, d;
        !          4742:                    i = type_unification (DECL_TEMPLATE_PARMS (elem), t,
        !          4743:                                          TYPE_ARG_TYPES (TREE_TYPE (elem)),
        !          4744:                                          TYPE_ARG_TYPES (lhstype), &d, 0);
        !          4745:                    if (i == 0)
        !          4746:                      {
        !          4747:                        if (save_elem)
        !          4748:                          {
        !          4749:                            cp_error ("ambiguous template instantiation converting to `%#T'", lhstype);
        !          4750:                            return error_mark_node;
        !          4751:                          }
        !          4752:                        save_elem = instantiate_template (elem, t);
        !          4753:                        /* Check the return type.  */
        !          4754:                        if (! comptypes (TREE_TYPE (lhstype),
        !          4755:                                         TREE_TYPE (TREE_TYPE (save_elem)), 1))
        !          4756:                          save_elem = 0;
        !          4757:                      }
        !          4758:                  }
        !          4759:              if (save_elem)
        !          4760:                return save_elem;
        !          4761:            }
        !          4762: 
        !          4763:            /* No match found, look for a compatible function.  */
        !          4764:            elem = get_first_fn (rhs);
        !          4765:            while (elem && ! comp_target_types (lhstype, TREE_TYPE (elem), 1))
        !          4766:              elem = DECL_CHAIN (elem);
        !          4767:            if (elem)
        !          4768:              {
        !          4769:                tree save_elem = elem;
        !          4770:                elem = DECL_CHAIN (elem);
        !          4771:                while (elem && ! comp_target_types (lhstype, TREE_TYPE (elem),
        !          4772:                                                    0))
        !          4773:                  elem = DECL_CHAIN (elem);
        !          4774:                if (elem)
        !          4775:                  {
        !          4776:                    if (complain)
        !          4777:                      {
        !          4778:                        cp_error ("cannot resolve overload to target type `%#T'",
        !          4779:                                  lhstype);
        !          4780:                        cp_error_at ("  ambiguity between `%#D'", save_elem);
        !          4781:                        cp_error_at ("  and `%#D', at least", elem);
        !          4782:                      }
        !          4783:                    return error_mark_node;
        !          4784:                  }
        !          4785:                return save_elem;
        !          4786:              }
        !          4787:            if (complain)
        !          4788:              {
        !          4789:                cp_error ("cannot resolve overload to target type `%#T'",
        !          4790:                          lhstype);
        !          4791:                cp_error ("  because no suitable overload of function `%D' exists",
        !          4792:                          TREE_PURPOSE (rhs));
        !          4793:              }
        !          4794:            return error_mark_node;
        !          4795:          }
        !          4796: 
        !          4797:        if (TREE_NONLOCAL_FLAG (rhs))
        !          4798:          {
        !          4799:            /* Got to get it as a baselink.  */
        !          4800:            rhs = lookup_fnfields (TYPE_BINFO (current_class_type),
        !          4801:                                   TREE_PURPOSE (rhs), 0);
        !          4802:          }
        !          4803:        else
        !          4804:          {
        !          4805:            my_friendly_assert (TREE_CHAIN (rhs) == NULL_TREE, 181);
        !          4806:            if (TREE_CODE (TREE_VALUE (rhs)) == TREE_LIST)
        !          4807:              rhs = TREE_VALUE (rhs);
        !          4808:            my_friendly_assert (TREE_CODE (TREE_VALUE (rhs)) == FUNCTION_DECL,
        !          4809:                                182);
        !          4810:          }
        !          4811: 
        !          4812:        for (baselink = rhs; baselink;
        !          4813:             baselink = next_baselink (baselink))
        !          4814:          {
        !          4815:            elem = TREE_VALUE (baselink);
        !          4816:            while (elem)
        !          4817:              if (comptypes (lhstype, TREE_TYPE (elem), 1))
        !          4818:                return elem;
        !          4819:              else
        !          4820:                elem = TREE_CHAIN (elem);
        !          4821:          }
        !          4822: 
        !          4823:        /* No exact match found, look for a compatible method.  */
        !          4824:        for (baselink = rhs; baselink;
        !          4825:             baselink = next_baselink (baselink))
        !          4826:          {
        !          4827:            elem = TREE_VALUE (baselink);
        !          4828:            while (elem && ! comp_target_types (lhstype, TREE_TYPE (elem), 1))
        !          4829:              elem = TREE_CHAIN (elem);
        !          4830:            if (elem)
        !          4831:              {
        !          4832:                tree save_elem = elem;
        !          4833:                elem = TREE_CHAIN (elem);
        !          4834:                while (elem && ! comp_target_types (lhstype, TREE_TYPE (elem), 0))
        !          4835:                  elem = TREE_CHAIN (elem);
        !          4836:                if (elem)
        !          4837:                  {
        !          4838:                    if (complain)
        !          4839:                      error ("ambiguous overload for overloaded method requested");
        !          4840:                    return error_mark_node;
        !          4841:                  }
        !          4842:                return save_elem;
        !          4843:              }
        !          4844:            name = DECL_NAME (TREE_VALUE (rhs));
        !          4845: #if 0
        !          4846:            if (TREE_CODE (lhstype) == FUNCTION_TYPE && globals < 0)
        !          4847:              {
        !          4848:                /* Try to instantiate from non-member functions.  */
        !          4849:                rhs = lookup_name_nonclass (name);
        !          4850:                if (rhs && TREE_CODE (rhs) == TREE_LIST)
        !          4851:                  {
        !          4852:                    /* This code seems to be missing a `return'.  */
        !          4853:                    my_friendly_abort (4);
        !          4854:                    instantiate_type (lhstype, rhs, complain);
        !          4855:                  }
        !          4856:              }
        !          4857: #endif
        !          4858:          }
        !          4859:        if (complain)
        !          4860:          error ("no static member functions named `%s'",
        !          4861:                 IDENTIFIER_POINTER (name));
        !          4862:        return error_mark_node;
        !          4863:       }
        !          4864: 
        !          4865:     case CALL_EXPR:
        !          4866:       /* This is too hard for now.  */
        !          4867:       my_friendly_abort (183);
        !          4868:       return error_mark_node;
        !          4869: 
        !          4870:     case PLUS_EXPR:
        !          4871:     case MINUS_EXPR:
        !          4872:     case COMPOUND_EXPR:
        !          4873:       TREE_OPERAND (rhs, 0)
        !          4874:        = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
        !          4875:       if (TREE_OPERAND (rhs, 0) == error_mark_node)
        !          4876:        return error_mark_node;
        !          4877:       TREE_OPERAND (rhs, 1)
        !          4878:        = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), complain);
        !          4879:       if (TREE_OPERAND (rhs, 1) == error_mark_node)
        !          4880:        return error_mark_node;
        !          4881: 
        !          4882:       TREE_TYPE (rhs) = lhstype;
        !          4883:       return rhs;
        !          4884: 
        !          4885:     case MULT_EXPR:
        !          4886:     case TRUNC_DIV_EXPR:
        !          4887:     case FLOOR_DIV_EXPR:
        !          4888:     case CEIL_DIV_EXPR:
        !          4889:     case ROUND_DIV_EXPR:
        !          4890:     case RDIV_EXPR:
        !          4891:     case TRUNC_MOD_EXPR:
        !          4892:     case FLOOR_MOD_EXPR:
        !          4893:     case CEIL_MOD_EXPR:
        !          4894:     case ROUND_MOD_EXPR:
        !          4895:     case FIX_ROUND_EXPR:
        !          4896:     case FIX_FLOOR_EXPR:
        !          4897:     case FIX_CEIL_EXPR:
        !          4898:     case FIX_TRUNC_EXPR:
        !          4899:     case FLOAT_EXPR:
        !          4900:     case NEGATE_EXPR:
        !          4901:     case ABS_EXPR:
        !          4902:     case MAX_EXPR:
        !          4903:     case MIN_EXPR:
        !          4904:     case FFS_EXPR:
        !          4905: 
        !          4906:     case BIT_AND_EXPR:
        !          4907:     case BIT_IOR_EXPR:
        !          4908:     case BIT_XOR_EXPR:
        !          4909:     case LSHIFT_EXPR:
        !          4910:     case RSHIFT_EXPR:
        !          4911:     case LROTATE_EXPR:
        !          4912:     case RROTATE_EXPR:
        !          4913: 
        !          4914:     case PREINCREMENT_EXPR:
        !          4915:     case PREDECREMENT_EXPR:
        !          4916:     case POSTINCREMENT_EXPR:
        !          4917:     case POSTDECREMENT_EXPR:
        !          4918:       if (complain)
        !          4919:        error ("illegal operation on uninstantiated type");
        !          4920:       return error_mark_node;
        !          4921: 
        !          4922:     case TRUTH_AND_EXPR:
        !          4923:     case TRUTH_OR_EXPR:
        !          4924:     case TRUTH_XOR_EXPR:
        !          4925:     case LT_EXPR:
        !          4926:     case LE_EXPR:
        !          4927:     case GT_EXPR:
        !          4928:     case GE_EXPR:
        !          4929:     case EQ_EXPR:
        !          4930:     case NE_EXPR:
        !          4931:     case TRUTH_ANDIF_EXPR:
        !          4932:     case TRUTH_ORIF_EXPR:
        !          4933:     case TRUTH_NOT_EXPR:
        !          4934:       if (complain)
        !          4935:        error ("not enough type information");
        !          4936:       return error_mark_node;
        !          4937: 
        !          4938:     case COND_EXPR:
        !          4939:       if (type_unknown_p (TREE_OPERAND (rhs, 0)))
        !          4940:        {
        !          4941:          if (complain)
        !          4942:            error ("not enough type information");
        !          4943:          return error_mark_node;
        !          4944:        }
        !          4945:       TREE_OPERAND (rhs, 1)
        !          4946:        = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), complain);
        !          4947:       if (TREE_OPERAND (rhs, 1) == error_mark_node)
        !          4948:        return error_mark_node;
        !          4949:       TREE_OPERAND (rhs, 2)
        !          4950:        = instantiate_type (lhstype, TREE_OPERAND (rhs, 2), complain);
        !          4951:       if (TREE_OPERAND (rhs, 2) == error_mark_node)
        !          4952:        return error_mark_node;
        !          4953: 
        !          4954:       TREE_TYPE (rhs) = lhstype;
        !          4955:       return rhs;
        !          4956: 
        !          4957:     case MODIFY_EXPR:
        !          4958:       TREE_OPERAND (rhs, 1)
        !          4959:        = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), complain);
        !          4960:       if (TREE_OPERAND (rhs, 1) == error_mark_node)
        !          4961:        return error_mark_node;
        !          4962: 
        !          4963:       TREE_TYPE (rhs) = lhstype;
        !          4964:       return rhs;
        !          4965:       
        !          4966:     case ADDR_EXPR:
        !          4967:       if (TYPE_PTRMEMFUNC_P (lhstype))
        !          4968:        lhstype = TYPE_PTRMEMFUNC_FN_TYPE (lhstype);
        !          4969:       else if (TREE_CODE (lhstype) != POINTER_TYPE)
        !          4970:        {
        !          4971:          if (complain)
        !          4972:            error ("type for resolving address of overloaded function must be pointer type");
        !          4973:          return error_mark_node;
        !          4974:        }
        !          4975:       TREE_TYPE (rhs) = lhstype;
        !          4976:       lhstype = TREE_TYPE (lhstype);
        !          4977:       {
        !          4978:        tree fn = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
        !          4979:        if (fn == error_mark_node)
        !          4980:          return error_mark_node;
        !          4981:        mark_addressable (fn);
        !          4982:        TREE_OPERAND (rhs, 0) = fn;
        !          4983:        TREE_CONSTANT (rhs) = staticp (fn);
        !          4984:       }
        !          4985:       return rhs;
        !          4986: 
        !          4987:     case ENTRY_VALUE_EXPR:
        !          4988:       my_friendly_abort (184);
        !          4989:       return error_mark_node;
        !          4990: 
        !          4991:     case ERROR_MARK:
        !          4992:       return error_mark_node;
        !          4993: 
        !          4994:     default:
        !          4995:       my_friendly_abort (185);
        !          4996:       return error_mark_node;
        !          4997:     }
        !          4998: }
        !          4999: 
        !          5000: /* Return the name of the virtual function pointer field
        !          5001:    (as an IDENTIFIER_NODE) for the given TYPE.  Note that
        !          5002:    this may have to look back through base types to find the
        !          5003:    ultimate field name.  (For single inheritance, these could
        !          5004:    all be the same name.  Who knows for multiple inheritance).  */
        !          5005: static tree
        !          5006: get_vfield_name (type)
        !          5007:      tree type;
        !          5008: {
        !          5009:   tree binfo = TYPE_BINFO (type);
        !          5010:   char *buf;
        !          5011: 
        !          5012:   while (BINFO_BASETYPES (binfo)
        !          5013:         && TYPE_VIRTUAL_P (BINFO_TYPE (BINFO_BASETYPE (binfo, 0)))
        !          5014:         && ! TREE_VIA_VIRTUAL (BINFO_BASETYPE (binfo, 0)))
        !          5015:     binfo = BINFO_BASETYPE (binfo, 0);
        !          5016: 
        !          5017:   type = BINFO_TYPE (binfo);
        !          5018:   buf = (char *)alloca (sizeof (VFIELD_NAME_FORMAT)
        !          5019:                        + TYPE_NAME_LENGTH (type) + 2);
        !          5020:   sprintf (buf, VFIELD_NAME_FORMAT, TYPE_NAME_STRING (type));
        !          5021:   return get_identifier (buf);
        !          5022: }
        !          5023: 
        !          5024: void
        !          5025: print_class_statistics ()
        !          5026: {
        !          5027: #ifdef GATHER_STATISTICS
        !          5028:   fprintf (stderr, "convert_harshness = %d\n", n_convert_harshness);
        !          5029:   fprintf (stderr, "compute_conversion_costs = %d\n", n_compute_conversion_costs);
        !          5030:   fprintf (stderr, "build_method_call = %d (inner = %d)\n",
        !          5031:           n_build_method_call, n_inner_fields_searched);
        !          5032:   if (n_vtables)
        !          5033:     {
        !          5034:       fprintf (stderr, "vtables = %d; vtable searches = %d\n",
        !          5035:               n_vtables, n_vtable_searches);
        !          5036:       fprintf (stderr, "vtable entries = %d; vtable elems = %d\n",
        !          5037:               n_vtable_entries, n_vtable_elems);
        !          5038:     }
        !          5039: #endif
        !          5040: }
        !          5041: 
        !          5042: /* Push an obstack which is sufficiently long-lived to hold such class
        !          5043:    decls that may be cached in the previous_class_values list.  For now, let's
        !          5044:    use the permanent obstack, later we may create a dedicated obstack just
        !          5045:    for this purpose.  The effect is undone by pop_obstacks.  */
        !          5046: void
        !          5047: maybe_push_cache_obstack ()
        !          5048: {
        !          5049:   push_obstacks_nochange ();
        !          5050:   if (current_class_depth == 1)
        !          5051:     current_obstack = &permanent_obstack;
        !          5052: }

unix.superglobalmegacorp.com

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