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

unix.superglobalmegacorp.com

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