Annotation of gcc/cp/init.c, revision 1.1.1.2

1.1       root        1: /* Handle initialization things in C++.
1.1.1.2 ! root        2:    Copyright (C) 1987, 89, 92, 93, 94, 1995 Free Software Foundation, Inc.
1.1       root        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
1.1.1.2 ! root       19: the Free Software Foundation, 59 Temple Place - Suite 330,
        !            20: Boston, MA 02111-1307, USA.  */
1.1       root       21: 
                     22: 
                     23: /* High-level class interface. */
                     24: 
                     25: #include "config.h"
                     26: #include "tree.h"
                     27: #include "rtl.h"
                     28: #include "cp-tree.h"
                     29: #include "flags.h"
1.1.1.2 ! root       30: #include "output.h"
1.1       root       31: 
                     32: #undef NULL
                     33: #define NULL 0
                     34: 
                     35: /* In C++, structures with well-defined constructors are initialized by
                     36:    those constructors, unasked.  CURRENT_BASE_INIT_LIST
                     37:    holds a list of stmts for a BASE_INIT term in the grammar.
                     38:    This list has one element for each base class which must be
                     39:    initialized.  The list elements are [basename, init], with
                     40:    type basetype.  This allows the possibly anachronistic form
                     41:    (assuming d : a, b, c) "d (int a) : c(a+5), b (a-4), a (a+3)"
                     42:    where each successive term can be handed down the constructor
                     43:    line.  Perhaps this was not intended.  */
                     44: tree current_base_init_list, current_member_init_list;
                     45: 
                     46: void emit_base_init ();
                     47: void check_base_init ();
                     48: static void expand_aggr_vbase_init ();
                     49: void expand_member_init ();
                     50: void expand_aggr_init ();
                     51: 
                     52: static void expand_aggr_init_1 ();
                     53: static void expand_recursive_init_1 ();
                     54: static void expand_recursive_init ();
                     55: static void expand_virtual_init PROTO((tree, tree));
                     56: tree expand_vec_init ();
                     57: 
                     58: static void add_friend (), add_friends ();
                     59: 
                     60: /* Cache _builtin_new and _builtin_delete exprs.  */
                     61: static tree BIN, BID, BIVN, BIVD;
                     62: 
                     63: /* Cache the identifier nodes for the two magic field of a new cookie.  */
                     64: static tree nc_nelts_field_id;
                     65: #if 0
                     66: static tree nc_ptr_2comp_field_id;
                     67: #endif
                     68: 
                     69: static tree minus_one;
                     70: 
                     71: /* Set up local variable for this file.  MUST BE CALLED AFTER
                     72:    INIT_DECL_PROCESSING.  */
                     73: 
                     74: tree BI_header_type, BI_header_size;
                     75: 
                     76: void init_init_processing ()
                     77: {
                     78:   tree fields[1];
                     79: 
                     80:   /* Define implicit `operator new' and `operator delete' functions.  */
                     81:   BIN = default_conversion (get_first_fn (IDENTIFIER_GLOBAL_VALUE (ansi_opname[(int) NEW_EXPR])));
                     82:   TREE_USED (TREE_OPERAND (BIN, 0)) = 0;
                     83:   BID = default_conversion (get_first_fn (IDENTIFIER_GLOBAL_VALUE (ansi_opname[(int) DELETE_EXPR])));
                     84:   TREE_USED (TREE_OPERAND (BID, 0)) = 0;
                     85:   BIVN = default_conversion (get_first_fn (IDENTIFIER_GLOBAL_VALUE (ansi_opname[(int) VEC_NEW_EXPR])));
                     86:   TREE_USED (TREE_OPERAND (BIVN, 0)) = 0;
                     87:   BIVD = default_conversion (get_first_fn (IDENTIFIER_GLOBAL_VALUE (ansi_opname[(int) VEC_DELETE_EXPR])));
                     88:   TREE_USED (TREE_OPERAND (BIVD, 0)) = 0;
                     89:   minus_one = build_int_2 (-1, -1);
                     90: 
                     91:   /* Define the structure that holds header information for
                     92:      arrays allocated via operator new.  */
                     93:   BI_header_type = make_lang_type (RECORD_TYPE);
                     94:   nc_nelts_field_id = get_identifier ("nelts");
                     95:   fields[0] = build_lang_field_decl (FIELD_DECL, nc_nelts_field_id, sizetype);
                     96:   finish_builtin_type (BI_header_type, "__new_cookie", fields,
                     97:                       0, double_type_node);
                     98:   BI_header_size = size_in_bytes (BI_header_type);
                     99: }
                    100: 
                    101: /* Subroutine of emit_base_init.  For BINFO, initialize all the
                    102:    virtual function table pointers, except those that come from
                    103:    virtual base classes.  Initialize binfo's vtable pointer, if
                    104:    INIT_SELF is true.  CAN_ELIDE is true when we know that all virtual
                    105:    function table pointers in all bases have been initialized already,
                    106:    probably because their constructors have just be run.  ADDR is the
                    107:    pointer to the object whos vtables we are going to initialize.
                    108: 
                    109:    REAL_BINFO is usually the same as BINFO, except when addr is not of
                    110:    pointer to the type of the real derived type that we want to
                    111:    initialize for.  This is the case when addr is a pointer to a sub
                    112:    object of a complete object, and we only want to do part of the
1.1.1.2 ! root      113:    complete object's initialization of vtable pointers.  This is done
1.1       root      114:    for all virtual table pointers in virtual base classes.  REAL_BINFO
                    115:    is used to find the BINFO_VTABLE that we initialize with.  BINFO is
                    116:    used for conversions of addr to subobjects.
                    117: 
                    118:    BINFO_TYPE (real_binfo) must be BINFO_TYPE (binfo).
                    119: 
                    120:    Relies upon binfo being inside TYPE_BINFO (TREE_TYPE (TREE_TYPE
                    121:    (addr))).  */
                    122: void
                    123: expand_direct_vtbls_init (real_binfo, binfo, init_self, can_elide, addr)
                    124:      tree real_binfo, binfo, addr;
                    125:      int init_self, can_elide;
                    126: {
                    127:   tree real_binfos = BINFO_BASETYPES (real_binfo);
                    128:   tree binfos = BINFO_BASETYPES (binfo);
                    129:   int i, n_baselinks = real_binfos ? TREE_VEC_LENGTH (real_binfos) : 0;
                    130: 
                    131:   for (i = 0; i < n_baselinks; i++)
                    132:     {
                    133:       tree real_base_binfo = TREE_VEC_ELT (real_binfos, i);
                    134:       tree base_binfo = TREE_VEC_ELT (binfos, i);
                    135:       int is_not_base_vtable =
                    136:        i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (real_binfo));
                    137:       if (! TREE_VIA_VIRTUAL (real_base_binfo))
                    138:        expand_direct_vtbls_init (real_base_binfo, base_binfo,
                    139:                                  is_not_base_vtable, can_elide, addr);
                    140:     }
                    141: #if 0
                    142:   /* Before turning this on, make sure it is correct.  */
1.1.1.2 ! root      143:   if (can_elide && ! BINFO_MODIFIED (binfo))
1.1       root      144:     return;
                    145: #endif
                    146:   /* Should we use something besides CLASSTYPE_VFIELDS? */
                    147:   if (init_self && CLASSTYPE_VFIELDS (BINFO_TYPE (real_binfo)))
                    148:     {
                    149:       tree base_ptr = convert_pointer_to_real (binfo, addr);
                    150:       expand_virtual_init (real_binfo, base_ptr);
                    151:     }
                    152: }
                    153: 
                    154: /* 348 - 351 */
                    155: /* Subroutine of emit_base_init.  */
                    156: static void
1.1.1.2 ! root      157: perform_member_init (member, name, init, explicit, protect_list)
        !           158:      tree member, name, init, *protect_list;
1.1       root      159:      int explicit;
                    160: {
                    161:   tree decl;
                    162:   tree type = TREE_TYPE (member);
                    163: 
                    164:   if (TYPE_NEEDS_CONSTRUCTING (type)
                    165:       || (init && TYPE_HAS_CONSTRUCTOR (type)))
                    166:     {
                    167:       /* Since `init' is already a TREE_LIST on the current_member_init_list,
                    168:         only build it into one if we aren't already a list.  */
                    169:       if (init != NULL_TREE && TREE_CODE (init) != TREE_LIST)
                    170:        init = build_tree_list (NULL_TREE, init);
                    171: 
                    172:       decl = build_component_ref (C_C_D, name, 0, explicit);
                    173: 
                    174:       if (explicit
                    175:          && TREE_CODE (type) == ARRAY_TYPE
                    176:          && init != NULL_TREE
                    177:          && TREE_CHAIN (init) == NULL_TREE
                    178:          && TREE_CODE (TREE_TYPE (TREE_VALUE (init))) == ARRAY_TYPE)
                    179:        {
                    180:          /* Initialization of one array from another.  */
                    181:          expand_vec_init (TREE_OPERAND (decl, 1), decl,
                    182:                           array_type_nelts (type), TREE_VALUE (init), 1);
                    183:        }
                    184:       else
1.1.1.2 ! root      185:        expand_aggr_init (decl, init, 0, 0);
1.1       root      186:     }
                    187:   else
                    188:     {
                    189:       if (init == NULL_TREE)
                    190:        {
                    191:          if (explicit)
                    192:            {
                    193:              cp_error ("incomplete initializer for member `%D' of class `%T' which has no constructor",
                    194:                        member, current_class_type);
                    195:              init = error_mark_node;
                    196:            }
                    197:          /* member traversal: note it leaves init NULL */
                    198:          else if (TREE_CODE (TREE_TYPE (member)) == REFERENCE_TYPE)
                    199:            cp_pedwarn ("uninitialized reference member `%D'", member);
                    200:        }
                    201:       else if (TREE_CODE (init) == TREE_LIST)
                    202:        {
                    203:          /* There was an explicit member initialization.  Do some
                    204:             work in that case.  */
                    205:          if (TREE_CHAIN (init))
                    206:            {
                    207:              warning ("initializer list treated as compound expression");
                    208:              init = build_compound_expr (init);
                    209:            }
                    210:          else
                    211:            init = TREE_VALUE (init);
                    212:        }
                    213: 
                    214:       /* We only build this with a null init if we got it from the
                    215:         current_member_init_list.  */
                    216:       if (init || explicit)
                    217:        {
                    218:          decl = build_component_ref (C_C_D, name, 0, explicit);
                    219:          expand_expr_stmt (build_modify_expr (decl, INIT_EXPR, init));
                    220:        }
                    221:     }
                    222:   expand_cleanups_to (NULL_TREE);
1.1.1.2 ! root      223: 
        !           224:   if (TYPE_NEEDS_DESTRUCTOR (type))
        !           225:     {
        !           226:       tree expr = build_component_ref (C_C_D, name, 0, explicit);
        !           227:       expr = build_delete (type, expr, integer_zero_node,
        !           228:                           LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0);
        !           229: 
        !           230:       if (expr != error_mark_node)
        !           231:        {
        !           232:          start_protect ();
        !           233:          *protect_list = tree_cons (NULL_TREE, expr, *protect_list);
        !           234:        }
        !           235:     }
1.1       root      236: }
                    237: 
1.1.1.2 ! root      238: extern int warn_reorder;
        !           239: 
1.1       root      240: /* Subroutine of emit_member_init.  */
                    241: static tree
                    242: sort_member_init (t)
                    243:      tree t;
                    244: {
                    245:   tree x, member, name, field, init;
                    246:   tree init_list = NULL_TREE;
                    247:   tree fields_to_unmark = NULL_TREE;
                    248:   int last_pos = 0;
                    249:   tree last_field;
                    250: 
                    251:   for (member = TYPE_FIELDS (t); member ; member = TREE_CHAIN (member))
                    252:     {
                    253:       int pos;
1.1.1.2 ! root      254: 
        !           255:       /* member could be, for example, a CONST_DECL for an enumerated
        !           256:         tag; we don't want to try to initialize that, since it already
        !           257:         has a value.  */
        !           258:       if (TREE_CODE (member) != FIELD_DECL || !DECL_NAME (member))
        !           259:        continue;
        !           260: 
1.1       root      261:       for (x = current_member_init_list, pos = 0; x; x = TREE_CHAIN (x), ++pos)
                    262:        {
                    263:          /* If we cleared this out, then pay no attention to it.  */
                    264:          if (TREE_PURPOSE (x) == NULL_TREE)
                    265:            continue;
                    266:          name = TREE_PURPOSE (x);
                    267: 
                    268: #if 0
                    269:          field = (TREE_CODE (name) == COMPONENT_REF
                    270:                   ? TREE_OPERAND (name, 1) : IDENTIFIER_CLASS_VALUE (name));
                    271: #else
                    272:          /* Let's find out when this happens.  */
                    273:          my_friendly_assert (TREE_CODE (name) != COMPONENT_REF, 348);
                    274:          field = IDENTIFIER_CLASS_VALUE (name);
                    275: #endif
                    276: 
                    277:          /* If one member shadows another, get the outermost one.  */
                    278:          if (TREE_CODE (field) == TREE_LIST)
                    279:            field = TREE_VALUE (field);
                    280: 
                    281:          if (field == member)
                    282:            {
1.1.1.2 ! root      283:              if (warn_reorder)
1.1       root      284:                {
1.1.1.2 ! root      285:                  if (pos < last_pos)
1.1       root      286:                    {
                    287:                      cp_warning_at ("member initializers for `%#D'", last_field);
                    288:                      cp_warning_at ("  and `%#D'", field);
                    289:                      warning ("  will be re-ordered to match declaration order");
                    290:                    }
                    291:                  last_pos = pos;
                    292:                  last_field = field;
                    293:                }
                    294: 
                    295:              /* Make sure we won't try to work on this init again.  */
                    296:              TREE_PURPOSE (x) = NULL_TREE;
1.1.1.2 ! root      297:              x = build_tree_list (name, TREE_VALUE (x));
        !           298:              goto got_it;
1.1       root      299:            }
                    300:        }
                    301: 
                    302:       /* If we didn't find MEMBER in the list, create a dummy entry
                    303:         so the two lists (INIT_LIST and the list of members) will be
                    304:         symmetrical.  */
1.1.1.2 ! root      305:       x = build_tree_list (NULL_TREE, NULL_TREE);
        !           306:     got_it:
        !           307:       init_list = chainon (init_list, x); 
1.1       root      308:     }
                    309: 
1.1.1.2 ! root      310:   /* Initializers for base members go at the end.  */
1.1       root      311:   for (x = current_member_init_list ; x ; x = TREE_CHAIN (x))
                    312:     {
1.1.1.2 ! root      313:       name = TREE_PURPOSE (x);
        !           314:       if (name)
1.1       root      315:        {
1.1.1.2 ! root      316:          if (purpose_member (name, init_list))
1.1       root      317:            {
1.1.1.2 ! root      318:              cp_error ("multiple initializations given for member `%D'",
        !           319:                        IDENTIFIER_CLASS_VALUE (name));
        !           320:              continue;
1.1       root      321:            }
1.1.1.2 ! root      322:              
        !           323:          init_list = chainon (init_list,
        !           324:                               build_tree_list (name, TREE_VALUE (x)));
        !           325:          TREE_PURPOSE (x) = NULL_TREE;
        !           326:        }
        !           327:     }
1.1       root      328: 
1.1.1.2 ! root      329:   return init_list;
        !           330: }
1.1       root      331: 
1.1.1.2 ! root      332: static void
        !           333: sort_base_init (t, rbase_ptr, vbase_ptr)
        !           334:      tree t, *rbase_ptr, *vbase_ptr;
        !           335: {
        !           336:   tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));
        !           337:   int n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
        !           338: 
        !           339:   int i;
        !           340:   tree x;
        !           341:   tree last;
        !           342: 
        !           343:   /* For warn_reorder.  */
        !           344:   int last_pos = 0;
        !           345:   tree last_base = NULL_TREE;
        !           346: 
        !           347:   tree rbases = NULL_TREE;
        !           348:   tree vbases = NULL_TREE;
1.1       root      349: 
1.1.1.2 ! root      350:   /* First walk through and splice out vbase and invalid initializers.
        !           351:      Also replace names with binfos.  */
        !           352: 
        !           353:   last = tree_cons (NULL_TREE, NULL_TREE, current_base_init_list);
        !           354:   for (x = TREE_CHAIN (last); x; x = TREE_CHAIN (x))
        !           355:     {
        !           356:       tree basename = TREE_PURPOSE (x);
        !           357:       tree binfo;
        !           358: 
        !           359:       if (basename == NULL_TREE)
        !           360:        {
        !           361:          /* Initializer for single base class.  Must not
        !           362:             use multiple inheritance or this is ambiguous.  */
        !           363:          switch (n_baseclasses)
1.1       root      364:            {
1.1.1.2 ! root      365:            case 0:
        !           366:              cp_error ("`%T' does not have a base class to initialize",
        !           367:                        current_class_type);
        !           368:              return;
        !           369:            case 1:
        !           370:              break;
        !           371:            default:
        !           372:              cp_error ("unnamed initializer ambiguous for `%T' which uses multiple inheritance",
        !           373:                        current_class_type);
        !           374:              return;
1.1       root      375:            }
1.1.1.2 ! root      376:          binfo = TREE_VEC_ELT (binfos, 0);
        !           377:        }
        !           378:       else if (is_aggr_typedef (basename, 1))
        !           379:        {
        !           380:          binfo = binfo_or_else (IDENTIFIER_TYPE_VALUE (basename), t);
        !           381:          if (binfo == NULL_TREE)
        !           382:            continue;
1.1       root      383: 
1.1.1.2 ! root      384:          /* Virtual base classes are special cases.  Their initializers
        !           385:             are recorded with this constructor, and they are used when
        !           386:             this constructor is the top-level constructor called.  */
        !           387:          if (TREE_VIA_VIRTUAL (binfo))
        !           388:            {
        !           389:              tree v = CLASSTYPE_VBASECLASSES (t);
        !           390:              while (BINFO_TYPE (v) != BINFO_TYPE (binfo))
        !           391:                v = TREE_CHAIN (v);
1.1       root      392: 
1.1.1.2 ! root      393:              vbases = tree_cons (v, TREE_VALUE (x), vbases);
        !           394:              continue;
        !           395:            }
        !           396:          else
        !           397:            {
        !           398:              /* Otherwise, if it is not an immediate base class, complain.  */
        !           399:              for (i = n_baseclasses-1; i >= 0; i--)
        !           400:                if (BINFO_TYPE (binfo) == BINFO_TYPE (TREE_VEC_ELT (binfos, i)))
        !           401:                  break;
        !           402:              if (i < 0)
        !           403:                {
        !           404:                  cp_error ("`%T' is not an immediate base class of `%T'",
        !           405:                            IDENTIFIER_TYPE_VALUE (basename),
        !           406:                            current_class_type);
        !           407:                  continue;
        !           408:                }
        !           409:            }
1.1       root      410:        }
1.1.1.2 ! root      411:       else
        !           412:        my_friendly_abort (365);
        !           413: 
        !           414:       TREE_PURPOSE (x) = binfo;
        !           415:       TREE_CHAIN (last) = x;
        !           416:       last = x;
1.1       root      417:     }
1.1.1.2 ! root      418:   TREE_CHAIN (last) = NULL_TREE;
        !           419: 
        !           420:   /* Now walk through our regular bases and make sure they're initialized.  */
1.1       root      421: 
1.1.1.2 ! root      422:   for (i = 0; i < n_baseclasses; ++i)
1.1       root      423:     {
1.1.1.2 ! root      424:       tree base_binfo = TREE_VEC_ELT (binfos, i);
        !           425:       int pos;
        !           426: 
        !           427:       if (TREE_VIA_VIRTUAL (base_binfo))
        !           428:        continue;
        !           429: 
        !           430:       for (x = current_base_init_list, pos = 0; x; x = TREE_CHAIN (x), ++pos)
        !           431:        {
        !           432:          tree binfo = TREE_PURPOSE (x);
        !           433: 
        !           434:          if (binfo == NULL_TREE)
        !           435:            continue;
        !           436: 
        !           437:          if (binfo == base_binfo)
        !           438:            {
        !           439:              if (warn_reorder)
        !           440:                {
        !           441:                  if (pos < last_pos)
        !           442:                    {
        !           443:                      cp_warning_at ("base initializers for `%#T'", last_base);
        !           444:                      cp_warning_at ("  and `%#T'", BINFO_TYPE (binfo));
        !           445:                      warning ("  will be re-ordered to match inheritance order");
        !           446:                    }
        !           447:                  last_pos = pos;
        !           448:                  last_base = BINFO_TYPE (binfo);
        !           449:                }
        !           450: 
        !           451:              /* Make sure we won't try to work on this init again.  */
        !           452:              TREE_PURPOSE (x) = NULL_TREE;
        !           453:              x = build_tree_list (binfo, TREE_VALUE (x));
        !           454:              goto got_it;
        !           455:            }
        !           456:        }
        !           457: 
        !           458:       /* If we didn't find BASE_BINFO in the list, create a dummy entry
        !           459:         so the two lists (RBASES and the list of bases) will be
        !           460:         symmetrical.  */
        !           461:       x = build_tree_list (NULL_TREE, NULL_TREE);
        !           462:     got_it:
        !           463:       rbases = chainon (rbases, x);
1.1       root      464:     }
                    465: 
1.1.1.2 ! root      466:   *rbase_ptr = rbases;
        !           467:   *vbase_ptr = vbases;
        !           468: }
        !           469: 
        !           470: /* Perform partial cleanups for a base for exception handling.  */
        !           471: static tree
        !           472: build_partial_cleanup_for (binfo)
        !           473:      tree binfo;
        !           474: {
        !           475:   tree expr = convert_pointer_to_real (binfo,
        !           476:                                       build_unary_op (ADDR_EXPR, C_C_D, 0));
        !           477: 
        !           478:   return build_delete (TREE_TYPE (expr),
        !           479:                       expr,
        !           480:                       integer_zero_node,
        !           481:                       LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0);
1.1       root      482: }
                    483: 
                    484: /* Perform whatever initializations have yet to be done on the base
                    485:    class of the class variable.  These actions are in the global
                    486:    variable CURRENT_BASE_INIT_LIST.  Such an action could be
                    487:    NULL_TREE, meaning that the user has explicitly called the base
                    488:    class constructor with no arguments.
                    489: 
                    490:    If there is a need for a call to a constructor, we must surround
                    491:    that call with a pushlevel/poplevel pair, since we are technically
                    492:    at the PARM level of scope.
                    493: 
                    494:    Argument IMMEDIATELY, if zero, forces a new sequence to be
                    495:    generated to contain these new insns, so it can be emitted later.
1.1.1.2 ! root      496:    This sequence is saved in the global variable BASE_INIT_EXPR.
1.1       root      497:    Otherwise, the insns are emitted into the current sequence.
                    498: 
                    499:    Note that emit_base_init does *not* initialize virtual base
                    500:    classes.  That is done specially, elsewhere.  */
1.1.1.2 ! root      501: 
        !           502: extern tree base_init_expr, rtl_expr_chain;
        !           503: 
1.1       root      504: void
                    505: emit_base_init (t, immediately)
                    506:      tree t;
                    507:      int immediately;
                    508: {
                    509:   extern tree in_charge_identifier;
                    510: 
1.1.1.2 ! root      511:   tree member, x;
        !           512:   tree mem_init_list;
        !           513:   tree rbase_init_list, vbase_init_list;
1.1       root      514:   tree t_binfo = TYPE_BINFO (t);
                    515:   tree binfos = BINFO_BASETYPES (t_binfo);
                    516:   int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
1.1.1.2 ! root      517:   tree expr = NULL_TREE;
        !           518: 
        !           519:   my_friendly_assert (protect_list == NULL_TREE, 999);
1.1       root      520: 
                    521:   if (! immediately)
                    522:     {
1.1.1.2 ! root      523:       int momentary;
1.1       root      524:       do_pending_stack_adjust ();
1.1.1.2 ! root      525:       /* Make the RTL_EXPR node temporary, not momentary,
        !           526:         so that rtl_expr_chain doesn't become garbage.  */
        !           527:       momentary = suspend_momentary ();
        !           528:       expr = make_node (RTL_EXPR);
        !           529:       resume_momentary (momentary);
        !           530:       start_sequence_for_rtl_expr (expr); 
1.1       root      531:     }
                    532: 
                    533:   if (write_symbols == NO_DEBUG)
                    534:     /* As a matter of principle, `start_sequence' should do this.  */
                    535:     emit_note (0, -1);
                    536:   else
                    537:     /* Always emit a line number note so we can step into constructors.  */
                    538:     emit_line_note_force (DECL_SOURCE_FILE (current_function_decl),
                    539:                          DECL_SOURCE_LINE (current_function_decl));
                    540: 
1.1.1.2 ! root      541:   mem_init_list = sort_member_init (t);
        !           542:   current_member_init_list = NULL_TREE;
1.1       root      543: 
1.1.1.2 ! root      544:   sort_base_init (t, &rbase_init_list, &vbase_init_list);
        !           545:   current_base_init_list = NULL_TREE;
1.1       root      546: 
1.1.1.2 ! root      547:   if (TYPE_USES_VIRTUAL_BASECLASSES (t))
        !           548:     {
        !           549:       tree first_arg = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl));
1.1       root      550: 
1.1.1.2 ! root      551:       expand_start_cond (first_arg, 0);
        !           552:       expand_aggr_vbase_init (t_binfo, C_C_D, current_class_decl,
        !           553:                              vbase_init_list);
        !           554:       expand_end_cond ();
        !           555:     }
1.1       root      556: 
1.1.1.2 ! root      557:   /* Now, perform initialization of non-virtual base classes.  */
        !           558:   for (i = 0; i < n_baseclasses; i++)
        !           559:     {
        !           560:       tree base = current_class_decl;
        !           561:       tree base_binfo = TREE_VEC_ELT (binfos, i);
        !           562:       tree init = void_list_node;
1.1       root      563: 
1.1.1.2 ! root      564:       if (TREE_VIA_VIRTUAL (base_binfo))
        !           565:        continue;
1.1       root      566: 
1.1.1.2 ! root      567: #if 0 /* Once unsharing happens soon enough.  */
        !           568:       my_friendly_assert (BINFO_INHERITANCE_CHAIN (base_binfo) == t_binfo);
        !           569: #else
        !           570:       BINFO_INHERITANCE_CHAIN (base_binfo) = t_binfo;
        !           571: #endif
1.1       root      572: 
1.1.1.2 ! root      573:       if (TREE_PURPOSE (rbase_init_list))
        !           574:        init = TREE_VALUE (rbase_init_list);
        !           575:       else if (TYPE_NEEDS_CONSTRUCTING (BINFO_TYPE (base_binfo)))
        !           576:        init = NULL_TREE;
1.1       root      577: 
1.1.1.2 ! root      578:       if (init != void_list_node)
        !           579:        {
        !           580:          member = convert_pointer_to_real (base_binfo, current_class_decl);
        !           581:          expand_aggr_init_1 (base_binfo, 0,
1.1       root      582:                              build_indirect_ref (member, NULL_PTR), init,
1.1.1.2 ! root      583:                              BINFO_OFFSET_ZEROP (base_binfo), LOOKUP_NORMAL);
1.1       root      584:          expand_cleanups_to (NULL_TREE);
                    585:        }
                    586: 
1.1.1.2 ! root      587:       if (TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo)))
1.1       root      588:        {
1.1.1.2 ! root      589:          start_protect ();
        !           590:          protect_list = tree_cons (NULL_TREE,
        !           591:                                    build_partial_cleanup_for (base_binfo),
        !           592:                                    protect_list);
1.1       root      593:        }
                    594: 
1.1.1.2 ! root      595:       rbase_init_list = TREE_CHAIN (rbase_init_list);
1.1       root      596:     }
                    597: 
                    598:   /* Initialize all the virtual function table fields that
                    599:      do come from virtual base classes. */
                    600:   if (TYPE_USES_VIRTUAL_BASECLASSES (t))
                    601:     expand_indirect_vtbls_init (t_binfo, C_C_D, current_class_decl, 0);
                    602: 
                    603:   /* Initialize all the virtual function table fields that
                    604:      do not come from virtual base classes.  */
                    605:   expand_direct_vtbls_init (t_binfo, t_binfo, 1, 1, current_class_decl);
                    606: 
                    607:   for (member = TYPE_FIELDS (t); member; member = TREE_CHAIN (member))
                    608:     {
                    609:       tree init, name;
1.1.1.2 ! root      610:       int from_init_list;
        !           611: 
        !           612:       /* member could be, for example, a CONST_DECL for an enumerated
        !           613:         tag; we don't want to try to initialize that, since it already
        !           614:         has a value.  */
        !           615:       if (TREE_CODE (member) != FIELD_DECL || !DECL_NAME (member))
        !           616:        continue;
1.1       root      617: 
                    618:       /* See if we had a user-specified member initialization.  */
1.1.1.2 ! root      619:       if (TREE_PURPOSE (mem_init_list))
1.1       root      620:        {
1.1.1.2 ! root      621:          name = TREE_PURPOSE (mem_init_list);
        !           622:          init = TREE_VALUE (mem_init_list);
        !           623:          from_init_list = 1;
        !           624: 
        !           625:          /* Also see if it's ever a COMPONENT_REF here.  If it is, we
        !           626:             need to do `expand_assignment (name, init, 0, 0);' and
        !           627:             a continue.  */
        !           628:          my_friendly_assert (TREE_CODE (name) != COMPONENT_REF, 349);
1.1       root      629:        }
1.1.1.2 ! root      630:       else
1.1       root      631:        {
                    632:          name = DECL_NAME (member);
                    633:          init = DECL_INITIAL (member);
1.1.1.2 ! root      634: 
        !           635:          from_init_list = 0;
1.1       root      636:        }
                    637: 
1.1.1.2 ! root      638:       perform_member_init (member, name, init, from_init_list, &protect_list);
        !           639:       mem_init_list = TREE_CHAIN (mem_init_list);
1.1       root      640:     }
                    641: 
1.1.1.2 ! root      642:   /* Now initialize any members from our bases.  */
        !           643:   while (mem_init_list)
        !           644:     {
        !           645:       tree name, init, field;
        !           646: 
        !           647:       if (TREE_PURPOSE (mem_init_list))
        !           648:        {
        !           649:          name = TREE_PURPOSE (mem_init_list);
        !           650:          init = TREE_VALUE (mem_init_list);
        !           651:          /* XXX: this may need the COMPONENT_REF operand 0 check if
        !           652:             it turns out we actually get them.  */
        !           653:          field = IDENTIFIER_CLASS_VALUE (name);
        !           654: 
        !           655:          /* If one member shadows another, get the outermost one.  */
        !           656:          if (TREE_CODE (field) == TREE_LIST)
        !           657:            {
        !           658:              field = TREE_VALUE (field);
        !           659:              if (decl_type_context (field) != current_class_type)
        !           660:                cp_error ("field `%D' not in immediate context", field);
        !           661:            }
        !           662: 
        !           663: #if 0
        !           664:          /* It turns out if you have an anonymous union in the
        !           665:             class, a member from it can end up not being on the
        !           666:             list of fields (rather, the type is), and therefore
        !           667:             won't be seen by the for loop above.  */
        !           668: 
        !           669:          /* The code in this for loop is derived from a general loop
        !           670:             which had this check in it.  Theoretically, we've hit
        !           671:             every initialization for the list of members in T, so
        !           672:             we shouldn't have anything but these left in this list.  */
        !           673:          my_friendly_assert (DECL_FIELD_CONTEXT (field) != t, 351);
        !           674: #endif
        !           675: 
        !           676:          perform_member_init (field, name, init, 1, &protect_list);
        !           677:        }
        !           678:       mem_init_list = TREE_CHAIN (mem_init_list);
        !           679:     }
1.1       root      680: 
                    681:   if (! immediately)
                    682:     {
                    683:       do_pending_stack_adjust ();
1.1.1.2 ! root      684:       my_friendly_assert (base_init_expr == 0, 207);
        !           685:       base_init_expr = expr;
        !           686:       TREE_TYPE (expr) = void_type_node;
        !           687:       RTL_EXPR_RTL (expr) = const0_rtx;
        !           688:       RTL_EXPR_SEQUENCE (expr) = get_insns ();
        !           689:       rtl_expr_chain = tree_cons (NULL_TREE, expr, rtl_expr_chain);
1.1       root      690:       end_sequence ();
1.1.1.2 ! root      691:       TREE_SIDE_EFFECTS (expr) = 1;
1.1       root      692:     }
                    693: 
                    694:   /* All the implicit try blocks we built up will be zapped
                    695:      when we come to a real binding contour boundary.  */
                    696: }
                    697: 
                    698: /* Check that all fields are properly initialized after
                    699:    an assignment to `this'.  */
                    700: void
                    701: check_base_init (t)
                    702:      tree t;
                    703: {
                    704:   tree member;
                    705:   for (member = TYPE_FIELDS (t); member; member = TREE_CHAIN (member))
                    706:     if (DECL_NAME (member) && TREE_USED (member))
                    707:       cp_error ("field `%D' used before initialized (after assignment to `this')",
                    708:                member);
                    709: }
                    710: 
                    711: /* This code sets up the virtual function tables appropriate for
                    712:    the pointer DECL.  It is a one-ply initialization.
                    713: 
                    714:    BINFO is the exact type that DECL is supposed to be.  In
                    715:    multiple inheritance, this might mean "C's A" if C : A, B.  */
                    716: static void
                    717: expand_virtual_init (binfo, decl)
                    718:      tree binfo, decl;
                    719: {
                    720:   tree type = BINFO_TYPE (binfo);
                    721:   tree vtbl, vtbl_ptr;
                    722:   tree vtype, vtype_binfo;
                    723: 
                    724:   /* This code is crusty.  Should be simple, like:
                    725:      vtbl = BINFO_VTABLE (binfo);
                    726:      */
                    727:   vtype = DECL_CONTEXT (CLASSTYPE_VFIELD (type));
                    728:   vtype_binfo = get_binfo (vtype, TREE_TYPE (TREE_TYPE (decl)), 0);
                    729:   vtbl = BINFO_VTABLE (binfo_value (DECL_FIELD_CONTEXT (CLASSTYPE_VFIELD (type)), binfo));
1.1.1.2 ! root      730:   assemble_external (vtbl);
1.1       root      731:   TREE_USED (vtbl) = 1;
1.1.1.2 ! root      732:   vtbl = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (vtbl)), vtbl);
1.1       root      733:   decl = convert_pointer_to_real (vtype_binfo, decl);
                    734:   vtbl_ptr = build_vfield_ref (build_indirect_ref (decl, NULL_PTR), vtype);
                    735:   if (vtbl_ptr == error_mark_node)
                    736:     return;
                    737: 
                    738:   /* Have to convert VTBL since array sizes may be different.  */
1.1.1.2 ! root      739:   vtbl = convert_force (TREE_TYPE (vtbl_ptr), vtbl, 0);
1.1       root      740:   expand_expr_stmt (build_modify_expr (vtbl_ptr, NOP_EXPR, vtbl));
                    741: }
                    742: 
                    743: /* Subroutine of `expand_aggr_vbase_init'.
                    744:    BINFO is the binfo of the type that is being initialized.
                    745:    INIT_LIST is the list of initializers for the virtual baseclass.  */
                    746: static void
                    747: expand_aggr_vbase_init_1 (binfo, exp, addr, init_list)
                    748:      tree binfo, exp, addr, init_list;
                    749: {
1.1.1.2 ! root      750:   tree init = purpose_member (binfo, init_list);
1.1       root      751:   tree ref = build_indirect_ref (addr, NULL_PTR);
                    752:   if (init)
1.1.1.2 ! root      753:     init = TREE_VALUE (init);
1.1       root      754:   /* Call constructors, but don't set up vtables.  */
1.1.1.2 ! root      755:   expand_aggr_init_1 (binfo, exp, ref, init, 0, LOOKUP_COMPLAIN);
1.1       root      756:   expand_cleanups_to (NULL_TREE);
                    757: }
                    758: 
                    759: /* Initialize this object's virtual base class pointers.  This must be
                    760:    done only at the top-level of the object being constructed.
                    761: 
                    762:    INIT_LIST is list of initialization for constructor to perform.  */
                    763: static void
                    764: expand_aggr_vbase_init (binfo, exp, addr, init_list)
                    765:      tree binfo;
                    766:      tree exp;
                    767:      tree addr;
                    768:      tree init_list;
                    769: {
                    770:   tree type = BINFO_TYPE (binfo);
                    771: 
                    772:   if (TYPE_USES_VIRTUAL_BASECLASSES (type))
                    773:     {
                    774:       tree result = init_vbase_pointers (type, addr);
                    775:       tree vbases;
                    776: 
                    777:       if (result)
                    778:        expand_expr_stmt (build_compound_expr (result));
                    779: 
1.1.1.2 ! root      780:       for (vbases = CLASSTYPE_VBASECLASSES (type); vbases;
        !           781:           vbases = TREE_CHAIN (vbases))
        !           782:        {
        !           783:          tree tmp = purpose_member (vbases, result);
        !           784:          expand_aggr_vbase_init_1 (vbases, exp,
        !           785:                                    TREE_OPERAND (TREE_VALUE (tmp), 0),
        !           786:                                    init_list);
        !           787:        }
1.1       root      788:     }
                    789: }
                    790: 
                    791: /* Subroutine to perform parser actions for member initialization.
                    792:    S_ID is the scoped identifier.
                    793:    NAME is the name of the member.
                    794:    INIT is the initializer, or `void_type_node' if none.  */
                    795: void
                    796: do_member_init (s_id, name, init)
                    797:      tree s_id, name, init;
                    798: {
                    799:   tree binfo, base;
                    800: 
                    801:   if (current_class_type == NULL_TREE
                    802:       || ! is_aggr_typedef (s_id, 1))
                    803:     return;
                    804:   binfo = get_binfo (IDENTIFIER_TYPE_VALUE (s_id),
                    805:                          current_class_type, 1);
                    806:   if (binfo == error_mark_node)
                    807:     return;
                    808:   if (binfo == 0)
                    809:     {
                    810:       error_not_base_type (IDENTIFIER_TYPE_VALUE (s_id), current_class_type);
                    811:       return;
                    812:     }
                    813: 
                    814:   base = convert_pointer_to (binfo, current_class_decl);
                    815:   expand_member_init (build_indirect_ref (base, NULL_PTR), name, init);
                    816: }
                    817: 
                    818: /* Function to give error message if member initialization specification
                    819:    is erroneous.  FIELD is the member we decided to initialize.
                    820:    TYPE is the type for which the initialization is being performed.
                    821:    FIELD must be a member of TYPE, or the base type from which FIELD
                    822:    comes must not need a constructor.
                    823:    
                    824:    MEMBER_NAME is the name of the member.  */
                    825: 
                    826: static int
                    827: member_init_ok_or_else (field, type, member_name)
                    828:      tree field;
                    829:      tree type;
                    830:      char *member_name;
                    831: {
                    832:   if (field == error_mark_node)
                    833:     return 0;
                    834:   if (field == NULL_TREE)
                    835:     {
                    836:       cp_error ("class `%T' does not have any field named `%s'", type,
1.1.1.2 ! root      837:                member_name);
1.1       root      838:       return 0;
                    839:     }
                    840:   if (DECL_CONTEXT (field) != type
                    841:       && TYPE_NEEDS_CONSTRUCTING (DECL_CONTEXT (field)))
                    842:     {
1.1.1.2 ! root      843:       if (current_function_decl && DECL_CONSTRUCTOR_P (current_function_decl))
        !           844:        cp_error ("initialization of `%D' inside constructor for `%T'",
        !           845:                  field, type);
        !           846:       else
        !           847:        cp_error ("member `%D' comes from base class needing constructor",
        !           848:                  field);
        !           849:       return 0;
        !           850:     }
        !           851:   if (TREE_STATIC (field))
        !           852:     {
        !           853:       cp_error ("field `%#D' is static; only point of initialization is its declaration",
1.1       root      854:                field);
                    855:       return 0;
                    856:     }
1.1.1.2 ! root      857: 
1.1       root      858:   return 1;
                    859: }
                    860: 
                    861: /* If NAME is a viable field name for the aggregate DECL,
                    862:    and PARMS is a viable parameter list, then expand an _EXPR
                    863:    which describes this initialization.
                    864: 
                    865:    Note that we do not need to chase through the class's base classes
                    866:    to look for NAME, because if it's in that list, it will be handled
                    867:    by the constructor for that base class.
                    868: 
                    869:    We do not yet have a fixed-point finder to instantiate types
                    870:    being fed to overloaded constructors.  If there is a unique
                    871:    constructor, then argument types can be got from that one.
                    872: 
                    873:    If INIT is non-NULL, then it the initialization should
                    874:    be placed in `current_base_init_list', where it will be processed
                    875:    by `emit_base_init'.  */
                    876: void
                    877: expand_member_init (exp, name, init)
                    878:      tree exp, name, init;
                    879: {
                    880:   extern tree ptr_type_node;   /* should be in tree.h */
                    881: 
                    882:   tree basetype = NULL_TREE, field;
                    883:   tree parm;
                    884:   tree rval, type;
                    885:   tree actual_name;
                    886: 
                    887:   if (exp == NULL_TREE)
                    888:     return;                    /* complain about this later */
                    889: 
                    890:   type = TYPE_MAIN_VARIANT (TREE_TYPE (exp));
                    891: 
                    892:   if (name == NULL_TREE && IS_AGGR_TYPE (type))
                    893:     switch (CLASSTYPE_N_BASECLASSES (type))
                    894:       {
                    895:       case 0:
                    896:        error ("base class initializer specified, but no base class to initialize");
                    897:        return;
                    898:       case 1:
                    899:        basetype = TYPE_BINFO_BASETYPE (type, 0);
                    900:        break;
                    901:       default:
                    902:        error ("initializer for unnamed base class ambiguous");
                    903:        cp_error ("(type `%T' uses multiple inheritance)", type);
                    904:        return;
                    905:       }
                    906: 
                    907:   if (init)
                    908:     {
                    909:       /* The grammar should not allow fields which have names
                    910:         that are TYPENAMEs.  Therefore, if the field has
                    911:         a non-NULL TREE_TYPE, we may assume that this is an
                    912:         attempt to initialize a base class member of the current
                    913:         type.  Otherwise, it is an attempt to initialize a
                    914:         member field.  */
                    915: 
                    916:       if (init == void_type_node)
                    917:        init = NULL_TREE;
                    918: 
                    919:       if (name == NULL_TREE || IDENTIFIER_HAS_TYPE_VALUE (name))
                    920:        {
                    921:          tree base_init;
                    922: 
                    923:          if (name == NULL_TREE)
                    924:            {
                    925: /*
                    926:              if (basetype)
                    927:                name = TYPE_IDENTIFIER (basetype);
                    928:              else
                    929:                {
                    930:                  error ("no base class to initialize");
                    931:                  return;
                    932:                }
                    933: */
                    934:            }
                    935:          else
                    936:            {
                    937:              basetype = IDENTIFIER_TYPE_VALUE (name);
                    938:              if (basetype != type
                    939:                  && ! binfo_member (basetype, TYPE_BINFO (type))
                    940:                  && ! binfo_member (basetype, CLASSTYPE_VBASECLASSES (type)))
                    941:                {
                    942:                  if (IDENTIFIER_CLASS_VALUE (name))
                    943:                    goto try_member;
                    944:                  if (TYPE_USES_VIRTUAL_BASECLASSES (type))
                    945:                    error ("type `%s' is not an immediate or virtual basetype for `%s'",
                    946:                           IDENTIFIER_POINTER (name),
                    947:                           TYPE_NAME_STRING (type));
                    948:                  else
                    949:                    error ("type `%s' is not an immediate basetype for `%s'",
                    950:                           IDENTIFIER_POINTER (name),
                    951:                           TYPE_NAME_STRING (type));
                    952:                  return;
                    953:                }
                    954:            }
                    955: 
                    956:          if (purpose_member (name, current_base_init_list))
                    957:            {
                    958:              error ("base class `%s' already initialized",
                    959:                     IDENTIFIER_POINTER (name));
                    960:              return;
                    961:            }
                    962: 
                    963:          base_init = build_tree_list (name, init);
                    964:          TREE_TYPE (base_init) = basetype;
                    965:          current_base_init_list = chainon (current_base_init_list, base_init);
                    966:        }
                    967:       else
                    968:        {
                    969:          tree member_init;
                    970: 
                    971:        try_member:
                    972:          field = lookup_field (type, name, 1, 0);
                    973: 
                    974:          if (! member_init_ok_or_else (field, type, IDENTIFIER_POINTER (name)))
                    975:            return;
                    976: 
                    977:          if (purpose_member (name, current_member_init_list))
                    978:            {
                    979:              error ("field `%s' already initialized", IDENTIFIER_POINTER (name));
                    980:              return;
                    981:            }
                    982: 
                    983:          member_init = build_tree_list (name, init);
                    984:          TREE_TYPE (member_init) = TREE_TYPE (field);
                    985:          current_member_init_list = chainon (current_member_init_list, member_init);
                    986:        }
                    987:       return;
                    988:     }
                    989:   else if (name == NULL_TREE)
                    990:     {
                    991:       compiler_error ("expand_member_init: name == NULL_TREE");
                    992:       return;
                    993:     }
                    994: 
                    995:   basetype = type;
                    996:   field = lookup_field (basetype, name, 0, 0);
                    997: 
                    998:   if (! member_init_ok_or_else (field, basetype, IDENTIFIER_POINTER (name)))
                    999:     return;
                   1000: 
                   1001:   /* now see if there is a constructor for this type
                   1002:      which will take these args. */
                   1003: 
                   1004:   if (TYPE_HAS_CONSTRUCTOR (TREE_TYPE (field)))
                   1005:     {
                   1006:       tree parmtypes, fndecl;
                   1007: 
                   1008:       if (TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == PARM_DECL)
                   1009:        {
                   1010:          /* just know that we've seen something for this node */
                   1011:          DECL_INITIAL (exp) = error_mark_node;
                   1012:          TREE_USED (exp) = 1;
                   1013:        }
                   1014:       type = TYPE_MAIN_VARIANT (TREE_TYPE (field));
                   1015:       actual_name = TYPE_IDENTIFIER (type);
                   1016:       parm = build_component_ref (exp, name, 0, 0);
                   1017: 
                   1018:       /* Now get to the constructor.  */
                   1019:       fndecl = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 0);
                   1020:       /* Get past destructor, if any.  */
                   1021:       if (TYPE_HAS_DESTRUCTOR (type))
                   1022:        fndecl = DECL_CHAIN (fndecl);
                   1023: 
                   1024:       if (fndecl)
                   1025:        my_friendly_assert (TREE_CODE (fndecl) == FUNCTION_DECL, 209);
                   1026: 
                   1027:       /* If the field is unique, we can use the parameter
                   1028:         types to guide possible type instantiation.  */
                   1029:       if (DECL_CHAIN (fndecl) == NULL_TREE)
                   1030:        {
                   1031:          /* There was a confusion here between
                   1032:             FIELD and FNDECL.  The following code
                   1033:             should be correct, but abort is here
                   1034:             to make sure.  */
                   1035:          my_friendly_abort (48);
                   1036:          parmtypes = FUNCTION_ARG_CHAIN (fndecl);
                   1037:        }
                   1038:       else
                   1039:        {
                   1040:          parmtypes = NULL_TREE;
                   1041:          fndecl = NULL_TREE;
                   1042:        }
                   1043: 
                   1044:       init = convert_arguments (parm, parmtypes, NULL_TREE, fndecl, LOOKUP_NORMAL);
                   1045:       if (init == NULL_TREE || TREE_TYPE (init) != error_mark_node)
                   1046:        rval = build_method_call (NULL_TREE, actual_name, init, NULL_TREE, LOOKUP_NORMAL);
                   1047:       else
                   1048:        return;
                   1049: 
                   1050:       if (rval != error_mark_node)
                   1051:        {
                   1052:          /* Now, fill in the first parm with our guy */
                   1053:          TREE_VALUE (TREE_OPERAND (rval, 1))
                   1054:            = build_unary_op (ADDR_EXPR, parm, 0);
                   1055:          TREE_TYPE (rval) = ptr_type_node;
                   1056:          TREE_SIDE_EFFECTS (rval) = 1;
                   1057:        }
                   1058:     }
                   1059:   else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (field)))
                   1060:     {
                   1061:       parm = build_component_ref (exp, name, 0, 0);
1.1.1.2 ! root     1062:       expand_aggr_init (parm, NULL_TREE, 0, 0);
1.1       root     1063:       rval = error_mark_node;
                   1064:     }
                   1065: 
                   1066:   /* Now initialize the member.  It does not have to
                   1067:      be of aggregate type to receive initialization.  */
                   1068:   if (rval != error_mark_node)
                   1069:     expand_expr_stmt (rval);
                   1070: }
                   1071: 
                   1072: /* This is like `expand_member_init', only it stores one aggregate
                   1073:    value into another.
                   1074: 
                   1075:    INIT comes in two flavors: it is either a value which
                   1076:    is to be stored in EXP, or it is a parameter list
                   1077:    to go to a constructor, which will operate on EXP.
1.1.1.2 ! root     1078:    If INIT is not a parameter list for a constructor, then set
        !          1079:    LOOKUP_ONLYCONVERTING.
        !          1080:    If FLAGS is LOOKUP_ONLYCONVERTING then it is the = init form of
        !          1081:    the initializer, if FLAGS is 0, then it is the (init) form.
1.1       root     1082:    If `init' is a CONSTRUCTOR, then we emit a warning message,
1.1.1.2 ! root     1083:    explaining that such initializations are invalid.
1.1       root     1084: 
                   1085:    ALIAS_THIS is nonzero iff we are initializing something which is
                   1086:    essentially an alias for C_C_D.  In this case, the base constructor
                   1087:    may move it on us, and we must keep track of such deviations.
                   1088: 
                   1089:    If INIT resolves to a CALL_EXPR which happens to return
                   1090:    something of the type we are looking for, then we know
                   1091:    that we can safely use that call to perform the
                   1092:    initialization.
                   1093: 
                   1094:    The virtual function table pointer cannot be set up here, because
                   1095:    we do not really know its type.
                   1096: 
                   1097:    Virtual baseclass pointers are also set up here.
                   1098: 
                   1099:    This never calls operator=().
                   1100: 
                   1101:    When initializing, nothing is CONST.
                   1102: 
                   1103:    A default copy constructor may have to be used to perform the
                   1104:    initialization.
                   1105: 
                   1106:    A constructor or a conversion operator may have to be used to
                   1107:    perform the initialization, but not both, as it would be ambiguous.
                   1108:    */
                   1109: 
                   1110: void
1.1.1.2 ! root     1111: expand_aggr_init (exp, init, alias_this, flags)
1.1       root     1112:      tree exp, init;
                   1113:      int alias_this;
1.1.1.2 ! root     1114:      int flags;
1.1       root     1115: {
                   1116:   tree type = TREE_TYPE (exp);
                   1117:   int was_const = TREE_READONLY (exp);
1.1.1.2 ! root     1118:   int was_volatile = TREE_THIS_VOLATILE (exp);
1.1       root     1119: 
                   1120:   if (init == error_mark_node)
                   1121:     return;
                   1122: 
                   1123:   TREE_READONLY (exp) = 0;
1.1.1.2 ! root     1124:   TREE_THIS_VOLATILE (exp) = 0;
        !          1125: 
        !          1126:   if (init && TREE_CODE (init) != TREE_LIST)
        !          1127:     flags |= LOOKUP_ONLYCONVERTING;
1.1       root     1128: 
                   1129:   if (TREE_CODE (type) == ARRAY_TYPE)
                   1130:     {
                   1131:       /* Must arrange to initialize each element of EXP
                   1132:         from elements of INIT.  */
                   1133:       tree itype = init ? TREE_TYPE (init) : NULL_TREE;
1.1.1.2 ! root     1134:       if (TYPE_READONLY (TREE_TYPE (type)) || TYPE_VOLATILE (TREE_TYPE (type)))
1.1       root     1135:        {
                   1136:          TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type);
                   1137:          if (init)
                   1138:            TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype);
                   1139:        }
                   1140:       if (init && TREE_TYPE (init) == NULL_TREE)
                   1141:        {
                   1142:          /* Handle bad initializers like:
                   1143:             class COMPLEX {
                   1144:             public:
                   1145:               double re, im;
                   1146:               COMPLEX(double r = 0.0, double i = 0.0) {re = r; im = i;};
                   1147:               ~COMPLEX() {};
                   1148:             };
                   1149: 
                   1150:             int main(int argc, char **argv) {
                   1151:               COMPLEX zees(1.0, 0.0)[10];
                   1152:             }
                   1153:          */
                   1154:          error ("bad array initializer");
                   1155:          return;
                   1156:        }
                   1157:       expand_vec_init (exp, exp, array_type_nelts (type), init,
                   1158:                       init && comptypes (TREE_TYPE (init), TREE_TYPE (exp), 1));
                   1159:       TREE_READONLY (exp) = was_const;
1.1.1.2 ! root     1160:       TREE_THIS_VOLATILE (exp) = was_volatile;
1.1       root     1161:       TREE_TYPE (exp) = type;
                   1162:       if (init)
                   1163:        TREE_TYPE (init) = itype;
                   1164:       return;
                   1165:     }
                   1166: 
                   1167:   if (TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == PARM_DECL)
                   1168:     /* just know that we've seen something for this node */
                   1169:     TREE_USED (exp) = 1;
                   1170: 
                   1171: #if 0
                   1172:   /* If initializing from a GNU C CONSTRUCTOR, consider the elts in the
                   1173:      constructor as parameters to an implicit GNU C++ constructor.  */
                   1174:   if (init && TREE_CODE (init) == CONSTRUCTOR
                   1175:       && TYPE_HAS_CONSTRUCTOR (type)
                   1176:       && TREE_TYPE (init) == type)
                   1177:     init = CONSTRUCTOR_ELTS (init);
                   1178: #endif
1.1.1.2 ! root     1179: 
        !          1180:   TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type);
1.1       root     1181:   expand_aggr_init_1 (TYPE_BINFO (type), exp, exp,
1.1.1.2 ! root     1182:                      init, alias_this, LOOKUP_NORMAL|flags);
        !          1183:   TREE_TYPE (exp) = type;
1.1       root     1184:   TREE_READONLY (exp) = was_const;
1.1.1.2 ! root     1185:   TREE_THIS_VOLATILE (exp) = was_volatile;
1.1       root     1186: }
                   1187: 
                   1188: static void
                   1189: expand_default_init (binfo, true_exp, exp, type, init, alias_this, flags)
                   1190:      tree binfo;
                   1191:      tree true_exp, exp;
                   1192:      tree type;
                   1193:      tree init;
                   1194:      int alias_this;
                   1195:      int flags;
                   1196: {
                   1197:   /* It fails because there may not be a constructor which takes
                   1198:      its own type as the first (or only parameter), but which does
                   1199:      take other types via a conversion.  So, if the thing initializing
                   1200:      the expression is a unit element of type X, first try X(X&),
                   1201:      followed by initialization by X.  If neither of these work
                   1202:      out, then look hard.  */
                   1203:   tree rval;
                   1204:   tree parms;
                   1205: 
1.1.1.2 ! root     1206:   if (init == NULL_TREE
        !          1207:       || (TREE_CODE (init) == TREE_LIST && ! TREE_TYPE (init)))
1.1       root     1208:     {
                   1209:       parms = init;
1.1.1.2 ! root     1210:       if (parms)
        !          1211:        init = TREE_VALUE (parms);
1.1       root     1212:     }
1.1.1.2 ! root     1213:   else if (TREE_CODE (init) == INDIRECT_REF && TREE_HAS_CONSTRUCTOR (init)
        !          1214:           && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (init)))
1.1       root     1215:     {
                   1216:       rval = convert_for_initialization (exp, type, init, 0, 0, 0, 0);
                   1217:       TREE_USED (rval) = 1;
                   1218:       expand_expr_stmt (rval);
                   1219:       return;
                   1220:     }
                   1221:   else
                   1222:     parms = build_tree_list (NULL_TREE, init);
                   1223: 
                   1224:   if (TYPE_USES_VIRTUAL_BASECLASSES (type))
                   1225:     {
                   1226:       if (true_exp == exp)
                   1227:        parms = tree_cons (NULL_TREE, integer_one_node, parms);
                   1228:       else
                   1229:        parms = tree_cons (NULL_TREE, integer_zero_node, parms);
                   1230:       flags |= LOOKUP_HAS_IN_CHARGE;
                   1231:     }
                   1232: 
1.1.1.2 ! root     1233:   if (init && TREE_CHAIN (parms) == NULL_TREE
        !          1234:       && TYPE_HAS_TRIVIAL_INIT_REF (type)
        !          1235:       && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (init)))
        !          1236:     {
        !          1237:       rval = build (INIT_EXPR, type, exp, init);
        !          1238:       TREE_SIDE_EFFECTS (rval) = 1;
        !          1239:       expand_expr_stmt (rval);
        !          1240:     }
        !          1241:   else
        !          1242:     {
        !          1243:       if (flags & LOOKUP_ONLYCONVERTING)
        !          1244:        flags |= LOOKUP_NO_CONVERSION;
        !          1245:       rval = build_method_call (exp, constructor_name_full (type),
        !          1246:                                parms, binfo, flags);
        !          1247: 
        !          1248:       /* Private, protected, or otherwise unavailable.  */
        !          1249:       if (rval == error_mark_node)
        !          1250:        {
        !          1251:          if (flags & LOOKUP_COMPLAIN)
        !          1252:            cp_error ("in base initialization for %sclass `%T'",
        !          1253:                      TREE_VIA_VIRTUAL (binfo) ? "virtual base " : "",
        !          1254:                      binfo);
1.1       root     1255:        }
1.1.1.2 ! root     1256:       else if (rval == NULL_TREE)
        !          1257:        my_friendly_abort (361);
1.1       root     1258:       else
                   1259:        {
1.1.1.2 ! root     1260:          /* p. 222: if the base class assigns to `this', then that
        !          1261:             value is used in the derived class.  */
        !          1262:          if ((flag_this_is_variable & 1) && alias_this)
        !          1263:            {
        !          1264:              TREE_TYPE (rval) = TREE_TYPE (current_class_decl);
        !          1265:              expand_assignment (current_class_decl, rval, 0, 0);
        !          1266:            }
        !          1267:          else
        !          1268:            expand_expr_stmt (rval);
1.1       root     1269:        }
                   1270:     }
                   1271: }
                   1272: 
                   1273: /* This function is responsible for initializing EXP with INIT
                   1274:    (if any).
                   1275: 
                   1276:    BINFO is the binfo of the type for who we are performing the
                   1277:    initialization.  For example, if W is a virtual base class of A and B,
                   1278:    and C : A, B.
                   1279:    If we are initializing B, then W must contain B's W vtable, whereas
                   1280:    were we initializing C, W must contain C's W vtable.
                   1281: 
                   1282:    TRUE_EXP is nonzero if it is the true expression being initialized.
                   1283:    In this case, it may be EXP, or may just contain EXP.  The reason we
                   1284:    need this is because if EXP is a base element of TRUE_EXP, we
                   1285:    don't necessarily know by looking at EXP where its virtual
                   1286:    baseclass fields should really be pointing.  But we do know
                   1287:    from TRUE_EXP.  In constructors, we don't know anything about
                   1288:    the value being initialized.
                   1289: 
                   1290:    ALIAS_THIS serves the same purpose it serves for expand_aggr_init.
                   1291: 
                   1292:    FLAGS is just passes to `build_method_call'.  See that function for
                   1293:    its description.  */
                   1294: 
                   1295: static void
                   1296: expand_aggr_init_1 (binfo, true_exp, exp, init, alias_this, flags)
                   1297:      tree binfo;
                   1298:      tree true_exp, exp;
                   1299:      tree init;
                   1300:      int alias_this;
                   1301:      int flags;
                   1302: {
                   1303:   tree type = TREE_TYPE (exp);
                   1304:   tree init_type = NULL_TREE;
                   1305: 
                   1306:   my_friendly_assert (init != error_mark_node && type != error_mark_node, 211);
                   1307: 
                   1308:   /* Use a function returning the desired type to initialize EXP for us.
                   1309:      If the function is a constructor, and its first argument is
                   1310:      NULL_TREE, know that it was meant for us--just slide exp on
                   1311:      in and expand the constructor.  Constructors now come
                   1312:      as TARGET_EXPRs.  */
                   1313:   if (init)
                   1314:     {
                   1315:       tree init_list = NULL_TREE;
                   1316: 
                   1317:       if (TREE_CODE (init) == TREE_LIST)
                   1318:        {
                   1319:          init_list = init;
                   1320:          if (TREE_CHAIN (init) == NULL_TREE)
                   1321:            init = TREE_VALUE (init);
                   1322:        }
                   1323: 
                   1324:       init_type = TREE_TYPE (init);
                   1325: 
                   1326:       if (TREE_CODE (init) != TREE_LIST)
                   1327:        {
                   1328:          if (TREE_CODE (init_type) == ERROR_MARK)
                   1329:            return;
                   1330: 
                   1331: #if 0
                   1332:          /* These lines are found troublesome 5/11/89.  */
                   1333:          if (TREE_CODE (init_type) == REFERENCE_TYPE)
                   1334:            init_type = TREE_TYPE (init_type);
                   1335: #endif
                   1336: 
                   1337:          /* This happens when we use C++'s functional cast notation.
                   1338:             If the types match, then just use the TARGET_EXPR
                   1339:             directly.  Otherwise, we need to create the initializer
                   1340:             separately from the object being initialized.  */
                   1341:          if (TREE_CODE (init) == TARGET_EXPR)
                   1342:            {
                   1343:              if (TYPE_MAIN_VARIANT (init_type) == TYPE_MAIN_VARIANT (type))
                   1344:                {
                   1345:                  if (TREE_CODE (exp) == VAR_DECL
                   1346:                      || TREE_CODE (exp) == RESULT_DECL)
                   1347:                    /* Unify the initialization targets.  */
                   1348:                    DECL_RTL (TREE_OPERAND (init, 0)) = DECL_RTL (exp);
                   1349:                  else
                   1350:                    DECL_RTL (TREE_OPERAND (init, 0)) = expand_expr (exp, NULL_RTX, 0, 0);
                   1351: 
                   1352:                  expand_expr_stmt (init);
                   1353:                  return;
                   1354:                }
                   1355:              else
                   1356:                {
                   1357:                  init = TREE_OPERAND (init, 1);
                   1358:                  init = build (CALL_EXPR, init_type,
                   1359:                                TREE_OPERAND (init, 0), TREE_OPERAND (init, 1), 0);
                   1360:                  TREE_SIDE_EFFECTS (init) = 1;
                   1361:                    if (init_list)
                   1362:                      TREE_VALUE (init_list) = init;
                   1363:                }
                   1364:            }
                   1365: 
                   1366:          if (init_type == type && TREE_CODE (init) == CALL_EXPR
                   1367: #if 0
1.1.1.2 ! root     1368:              /* It is valid to directly initialize from a CALL_EXPR
1.1       root     1369:                 without going through X(X&), apparently.  */
                   1370:              && ! TYPE_GETS_INIT_REF (type)
                   1371: #endif
                   1372:              )
                   1373:            {
                   1374:              /* A CALL_EXPR is a legitimate form of initialization, so
                   1375:                 we should not print this warning message.  */
                   1376: #if 0
                   1377:              /* Should have gone away due to 5/11/89 change.  */
                   1378:              if (TREE_CODE (TREE_TYPE (init)) == REFERENCE_TYPE)
                   1379:                init = convert_from_reference (init);
                   1380: #endif
                   1381:              expand_assignment (exp, init, 0, 0);
                   1382:              if (exp == DECL_RESULT (current_function_decl))
                   1383:                {
                   1384:                  /* Failing this assertion means that the return value
                   1385:                     from receives multiple initializations.  */
                   1386:                  my_friendly_assert (DECL_INITIAL (exp) == NULL_TREE
                   1387:                                      || DECL_INITIAL (exp) == error_mark_node,
                   1388:                                      212);
                   1389:                  DECL_INITIAL (exp) = init;
                   1390:                }
                   1391:              return;
                   1392:            }
                   1393:          else if (init_type == type
                   1394:                   && TREE_CODE (init) == COND_EXPR)
                   1395:            {
                   1396:              /* Push value to be initialized into the cond, where possible.
                   1397:                 Avoid spurious warning messages when initializing the
                   1398:                 result of this function.  */
                   1399:              TREE_OPERAND (init, 1)
                   1400:                = build_modify_expr (exp, INIT_EXPR, TREE_OPERAND (init, 1));
                   1401:              if (exp == DECL_RESULT (current_function_decl))
                   1402:                DECL_INITIAL (exp) = NULL_TREE;
                   1403:              TREE_OPERAND (init, 2)
                   1404:                = build_modify_expr (exp, INIT_EXPR, TREE_OPERAND (init, 2));
                   1405:              if (exp == DECL_RESULT (current_function_decl))
                   1406:                DECL_INITIAL (exp) = init;
                   1407:              TREE_SIDE_EFFECTS (init) = 1;
                   1408:              expand_expr (init, const0_rtx, VOIDmode, 0);
                   1409:              free_temp_slots ();
                   1410:              return;
                   1411:            }
                   1412:        }
                   1413: 
                   1414:       /* We did not know what we were initializing before.  Now we do.  */
                   1415:       if (TREE_CODE (init) == TARGET_EXPR)
                   1416:        {
                   1417:          tree tmp = TREE_OPERAND (TREE_OPERAND (init, 1), 1);
                   1418: 
                   1419:          if (TREE_CODE (TREE_VALUE (tmp)) == NOP_EXPR
                   1420:              && TREE_OPERAND (TREE_VALUE (tmp), 0) == integer_zero_node)
                   1421:            {
                   1422:              /* In order for this to work for RESULT_DECLs, if their
                   1423:                 type has a constructor, then they must be BLKmode
                   1424:                 so that they will be meaningfully addressable.  */
                   1425:              tree arg = build_unary_op (ADDR_EXPR, exp, 0);
                   1426:              init = TREE_OPERAND (init, 1);
                   1427:              init = build (CALL_EXPR, build_pointer_type (TREE_TYPE (init)),
                   1428:                            TREE_OPERAND (init, 0), TREE_OPERAND (init, 1), 0);
                   1429:              TREE_SIDE_EFFECTS (init) = 1;
                   1430:              TREE_VALUE (TREE_OPERAND (init, 1))
                   1431:                = convert_pointer_to (TREE_TYPE (TREE_TYPE (TREE_VALUE (tmp))), arg);
                   1432: 
                   1433:              if (alias_this)
                   1434:                {
                   1435:                  expand_assignment (current_function_decl, init, 0, 0);
                   1436:                  return;
                   1437:                }
                   1438:              if (exp == DECL_RESULT (current_function_decl))
                   1439:                {
                   1440:                  if (DECL_INITIAL (DECL_RESULT (current_function_decl)))
                   1441:                    fatal ("return value from function receives multiple initializations");
                   1442:                  DECL_INITIAL (exp) = init;
                   1443:                }
                   1444:              expand_expr_stmt (init);
                   1445:              return;
                   1446:            }
                   1447:        }
                   1448: 
                   1449:       if (TREE_CODE (exp) == VAR_DECL
                   1450:          && TREE_CODE (init) == CONSTRUCTOR
                   1451:          && TREE_HAS_CONSTRUCTOR (init))
                   1452:        {
                   1453:          tree t = store_init_value (exp, init);
                   1454:          if (!t)
                   1455:            {
                   1456:              expand_decl_init (exp);
                   1457:              return;
                   1458:            }
                   1459:          t = build (INIT_EXPR, type, exp, init);
                   1460:          TREE_SIDE_EFFECTS (t) = 1;
                   1461:          expand_expr_stmt (t);
                   1462:          return;
                   1463:        }
                   1464: 
                   1465:       /* Handle this case: when calling a constructor: xyzzy foo(bar);
                   1466:         which really means:  xyzzy foo = bar; Ugh!
                   1467: 
                   1468:         More useful for this case: xyzzy *foo = new xyzzy (bar);  */
                   1469: 
                   1470:       if (! TYPE_NEEDS_CONSTRUCTING (type) && ! IS_AGGR_TYPE (type))
                   1471:        {
                   1472:          if (init_list && TREE_CHAIN (init_list))
                   1473:            {
                   1474:              warning ("initializer list being treated as compound expression");
                   1475:              init = convert (type, build_compound_expr (init_list));
                   1476:              if (init == error_mark_node)
                   1477:                return;
                   1478:            }
                   1479: 
                   1480:          expand_assignment (exp, init, 0, 0);
                   1481: 
                   1482:          return;
                   1483:        }
                   1484:       /* See whether we can go through a type conversion operator.
                   1485:         This wins over going through a non-existent constructor.  If
                   1486:         there is a constructor, it is ambiguous.  */
                   1487:       if (TREE_CODE (init) != TREE_LIST)
                   1488:        {
                   1489:          tree ttype = TREE_CODE (init_type) == REFERENCE_TYPE
                   1490:            ? TREE_TYPE (init_type) : init_type;
                   1491: 
                   1492:          if (ttype != type && IS_AGGR_TYPE (ttype))
                   1493:            {
                   1494:              tree rval = build_type_conversion (CONVERT_EXPR, type, init, 0);
                   1495: 
                   1496:              if (rval)
                   1497:                {
                   1498:                  /* See if there is a constructor for``type'' that takes a
                   1499:                     ``ttype''-typed object. */
                   1500:                  tree parms = build_tree_list (NULL_TREE, init);
                   1501:                  tree as_cons = NULL_TREE;
                   1502:                  if (TYPE_HAS_CONSTRUCTOR (type))
                   1503:                    as_cons = build_method_call (exp, constructor_name_full (type),
                   1504:                                                 parms, binfo,
                   1505:                                                 LOOKUP_SPECULATIVELY|LOOKUP_NO_CONVERSION);
                   1506:                  if (as_cons != NULL_TREE && as_cons != error_mark_node)
                   1507:                    /* ANSI C++ June 5 1992 WP 12.3.2.6.1 */
                   1508:                    cp_error ("ambiguity between conversion to `%T' and constructor",
                   1509:                              type);
                   1510:                  else
                   1511:                    expand_assignment (exp, rval, 0, 0);
                   1512:                  return;
                   1513:                }
                   1514:            }
                   1515:        }
                   1516:     }
                   1517: 
                   1518:   /* Handle default copy constructors here, does not matter if there is
                   1519:      a constructor or not.  */
                   1520:   if (type == init_type && IS_AGGR_TYPE (type)
                   1521:       && init && TREE_CODE (init) != TREE_LIST)
                   1522:     expand_default_init (binfo, true_exp, exp, type, init, alias_this, flags);
                   1523:   /* Not sure why this is here... */
                   1524:   else if (TYPE_HAS_CONSTRUCTOR (type))
                   1525:     expand_default_init (binfo, true_exp, exp, type, init, alias_this, flags);
                   1526:   else if (TREE_CODE (type) == ARRAY_TYPE)
                   1527:     {
                   1528:       if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (type)))
                   1529:        expand_vec_init (exp, exp, array_type_nelts (type), init, 0);
                   1530:       else if (TYPE_VIRTUAL_P (TREE_TYPE (type)))
                   1531:        sorry ("arrays of objects with virtual functions but no constructors");
                   1532:     }
                   1533:   else
                   1534:     expand_recursive_init (binfo, true_exp, exp, init,
                   1535:                           CLASSTYPE_BASE_INIT_LIST (type), alias_this);
                   1536: }
                   1537: 
                   1538: /* A pointer which holds the initializer.  First call to
                   1539:    expand_aggr_init gets this value pointed to, and sets it to init_null.  */
                   1540: static tree *init_ptr, init_null;
                   1541: 
                   1542: /* Subroutine of expand_recursive_init:
                   1543: 
                   1544:    ADDR is the address of the expression being initialized.
                   1545:    INIT_LIST is the cons-list of initializations to be performed.
                   1546:    ALIAS_THIS is its same, lovable self.  */
                   1547: static void
                   1548: expand_recursive_init_1 (binfo, true_exp, addr, init_list, alias_this)
                   1549:      tree binfo, true_exp, addr;
                   1550:      tree init_list;
                   1551:      int alias_this;
                   1552: {
                   1553:   while (init_list)
                   1554:     {
                   1555:       if (TREE_PURPOSE (init_list))
                   1556:        {
                   1557:          if (TREE_CODE (TREE_PURPOSE (init_list)) == FIELD_DECL)
                   1558:            {
                   1559:              tree member = TREE_PURPOSE (init_list);
                   1560:              tree subexp = build_indirect_ref (convert_pointer_to (TREE_VALUE (init_list), addr), NULL_PTR);
                   1561:              tree member_base = build (COMPONENT_REF, TREE_TYPE (member), subexp, member);
                   1562:              if (IS_AGGR_TYPE (TREE_TYPE (member)))
1.1.1.2 ! root     1563:                expand_aggr_init (member_base, DECL_INITIAL (member), 0, 0);
1.1       root     1564:              else if (TREE_CODE (TREE_TYPE (member)) == ARRAY_TYPE
                   1565:                       && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (member)))
                   1566:                {
                   1567:                  member_base = save_expr (default_conversion (member_base));
                   1568:                  expand_vec_init (member, member_base,
                   1569:                                   array_type_nelts (TREE_TYPE (member)),
                   1570:                                   DECL_INITIAL (member), 0);
                   1571:                }
                   1572:              else
                   1573:                expand_expr_stmt (build_modify_expr (member_base, INIT_EXPR, DECL_INITIAL (member)));
                   1574:            }
                   1575:          else if (TREE_CODE (TREE_PURPOSE (init_list)) == TREE_LIST)
                   1576:            {
                   1577:              expand_recursive_init_1 (binfo, true_exp, addr, TREE_PURPOSE (init_list), alias_this);
                   1578:              expand_recursive_init_1 (binfo, true_exp, addr, TREE_VALUE (init_list), alias_this);
                   1579:            }
                   1580:          else if (TREE_CODE (TREE_PURPOSE (init_list)) == ERROR_MARK)
                   1581:            {
                   1582:              /* Only initialize the virtual function tables if we
                   1583:                 are initializing the ultimate users of those vtables.  */
                   1584:              if (TREE_VALUE (init_list))
                   1585:                {
                   1586:                  /* We have to ensure that the first argment to
                   1587:                     expand_virtual_init is in binfo's hierarchy.  */
                   1588:                  /* Is it the case that this is exactly the right binfo? */
                   1589:                  /* If it is ok, then fixup expand_virtual_init, to make
                   1590:                     it much simpler. */
                   1591:                  expand_virtual_init (get_binfo (TREE_VALUE (init_list), binfo, 0),
                   1592:                                      addr);
                   1593:                  if (TREE_VALUE (init_list) == binfo
                   1594:                      && TYPE_USES_VIRTUAL_BASECLASSES (BINFO_TYPE (binfo)))
                   1595:                    expand_indirect_vtbls_init (binfo, true_exp, addr, 1);
                   1596:                }
                   1597:            }
                   1598:          else
                   1599:            my_friendly_abort (49);
                   1600:        }
                   1601:       else if (TREE_VALUE (init_list)
                   1602:               && TREE_CODE (TREE_VALUE (init_list)) == TREE_VEC)
                   1603:        {
                   1604:          tree subexp = build_indirect_ref (convert_pointer_to (TREE_VALUE (init_list), addr), NULL_PTR);
                   1605:          expand_aggr_init_1 (binfo, true_exp, subexp, *init_ptr,
                   1606:                              alias_this && BINFO_OFFSET_ZEROP (TREE_VALUE (init_list)),
                   1607:                              LOOKUP_COMPLAIN);
                   1608: 
                   1609:          /* INIT_PTR is used up.  */
                   1610:          init_ptr = &init_null;
                   1611:        }
                   1612:       else
                   1613:        my_friendly_abort (50);
                   1614:       init_list = TREE_CHAIN (init_list);
                   1615:     }
                   1616: }
                   1617: 
                   1618: /* Initialize EXP with INIT.  Type EXP does not have a constructor,
                   1619:    but it has a baseclass with a constructor or a virtual function
                   1620:    table which needs initializing.
                   1621: 
                   1622:    INIT_LIST is a cons-list describing what parts of EXP actually
                   1623:    need to be initialized.  INIT is given to the *unique*, first
                   1624:    constructor within INIT_LIST.  If there are multiple first
                   1625:    constructors, such as with multiple inheritance, INIT must
                   1626:    be zero or an ambiguity error is reported.
                   1627: 
                   1628:    ALIAS_THIS is passed from `expand_aggr_init'.  See comments
                   1629:    there.  */
                   1630: 
                   1631: static void
                   1632: expand_recursive_init (binfo, true_exp, exp, init, init_list, alias_this)
                   1633:      tree binfo, true_exp, exp, init;
                   1634:      tree init_list;
                   1635:      int alias_this;
                   1636: {
                   1637:   tree *old_init_ptr = init_ptr;
                   1638:   tree addr = build_unary_op (ADDR_EXPR, exp, 0);
                   1639:   init_ptr = &init;
                   1640: 
                   1641:   if (true_exp == exp && TYPE_USES_VIRTUAL_BASECLASSES (BINFO_TYPE (binfo)))
                   1642:     {
                   1643:       expand_aggr_vbase_init (binfo, exp, addr, init_list);
                   1644:       expand_indirect_vtbls_init (binfo, true_exp, addr, 1);
                   1645:     }
                   1646:   expand_recursive_init_1 (binfo, true_exp, addr, init_list, alias_this);
                   1647: 
                   1648:   if (*init_ptr)
                   1649:     {
                   1650:       tree type = TREE_TYPE (exp);
                   1651: 
                   1652:       if (TREE_CODE (type) == REFERENCE_TYPE)
                   1653:        type = TREE_TYPE (type);
                   1654:       if (IS_AGGR_TYPE (type))
                   1655:        cp_error ("unexpected argument to constructor `%T'", type);
                   1656:       else
                   1657:        error ("unexpected argument to constructor");
                   1658:     }
                   1659:   init_ptr = old_init_ptr;
                   1660: }
                   1661: 
                   1662: /* Report an error if NAME is not the name of a user-defined,
                   1663:    aggregate type.  If OR_ELSE is nonzero, give an error message.  */
                   1664: int
                   1665: is_aggr_typedef (name, or_else)
                   1666:      tree name;
                   1667:      int or_else;
                   1668: {
                   1669:   tree type;
                   1670: 
                   1671:   if (name == error_mark_node)
                   1672:     return 0;
                   1673: 
                   1674:   if (IDENTIFIER_HAS_TYPE_VALUE (name))
                   1675:     type = IDENTIFIER_TYPE_VALUE (name);
                   1676:   else
                   1677:     {
                   1678:       if (or_else)
                   1679:        cp_error ("`%T' is not an aggregate typedef", name);
                   1680:       return 0;
                   1681:     }
                   1682: 
                   1683:   if (! IS_AGGR_TYPE (type)
                   1684:       && TREE_CODE (type) != TEMPLATE_TYPE_PARM)
                   1685:     {
                   1686:       if (or_else)
                   1687:        cp_error ("`%T' is not an aggregate type", type);
                   1688:       return 0;
                   1689:     }
                   1690:   return 1;
                   1691: }
                   1692: 
                   1693: /* Like is_aggr_typedef, but returns typedef if successful.  */
                   1694: tree
                   1695: get_aggr_from_typedef (name, or_else)
                   1696:      tree name;
                   1697:      int or_else;
                   1698: {
                   1699:   tree type;
                   1700: 
                   1701:   if (name == error_mark_node)
                   1702:     return NULL_TREE;
                   1703: 
                   1704:   if (IDENTIFIER_HAS_TYPE_VALUE (name))
                   1705:     type = IDENTIFIER_TYPE_VALUE (name);
                   1706:   else
                   1707:     {
                   1708:       if (or_else)
                   1709:        cp_error ("`%T' fails to be an aggregate typedef", name);
                   1710:       return NULL_TREE;
                   1711:     }
                   1712: 
                   1713:   if (! IS_AGGR_TYPE (type)
                   1714:       && TREE_CODE (type) != TEMPLATE_TYPE_PARM)
                   1715:     {
                   1716:       if (or_else)
                   1717:        cp_error ("type `%T' is of non-aggregate type", type);
                   1718:       return NULL_TREE;
                   1719:     }
                   1720:   return type;
                   1721: }
                   1722: 
                   1723: tree
                   1724: get_type_value (name)
                   1725:      tree name;
                   1726: {
                   1727:   if (name == error_mark_node)
                   1728:     return NULL_TREE;
                   1729: 
                   1730:   if (IDENTIFIER_HAS_TYPE_VALUE (name))
                   1731:     return IDENTIFIER_TYPE_VALUE (name);
                   1732:   else
                   1733:     return NULL_TREE;
                   1734: }
                   1735:   
                   1736: 
                   1737: /* This code could just as well go in `class.c', but is placed here for
                   1738:    modularity.  */
                   1739: 
                   1740: /* For an expression of the form CNAME :: NAME (PARMLIST), build
                   1741:    the appropriate function call.  */
                   1742: tree
                   1743: build_member_call (cname, name, parmlist)
                   1744:      tree cname, name, parmlist;
                   1745: {
                   1746:   tree type, t;
                   1747:   tree method_name = name;
                   1748:   int dtor = 0;
                   1749:   int dont_use_this = 0;
                   1750:   tree basetype_path, decl;
                   1751: 
                   1752:   if (TREE_CODE (method_name) == BIT_NOT_EXPR)
                   1753:     {
                   1754:       method_name = TREE_OPERAND (method_name, 0);
                   1755:       dtor = 1;
                   1756:     }
                   1757: 
                   1758:   if (TREE_CODE (cname) == SCOPE_REF)
                   1759:     cname = resolve_scope_to_name (NULL_TREE, cname);
                   1760: 
1.1.1.2 ! root     1761:   /* This shouldn't be here, and build_member_call shouldn't appear in
        !          1762:      parse.y!  (mrs)  */
        !          1763:   if (cname && get_aggr_from_typedef (cname, 0) == 0
        !          1764:       && TREE_CODE (cname) == IDENTIFIER_NODE)
        !          1765:     {
        !          1766:       tree ns = lookup_name (cname, 0);
        !          1767:       if (ns && TREE_CODE (ns) == NAMESPACE_DECL)
        !          1768:        {
        !          1769:          return build_x_function_call (build_offset_ref (cname, name), parmlist, current_class_decl);
        !          1770:        }
        !          1771:     }
        !          1772: 
1.1       root     1773:   if (cname == NULL_TREE || ! (type = get_aggr_from_typedef (cname, 1)))
                   1774:     return error_mark_node;
                   1775: 
                   1776:   /* An operator we did not like.  */
                   1777:   if (name == NULL_TREE)
                   1778:     return error_mark_node;
                   1779: 
                   1780:   if (dtor)
                   1781:     {
                   1782: #if 0
                   1783:       /* Everything can explicitly call a destructor; see 12.4 */
                   1784:       if (! TYPE_HAS_DESTRUCTOR (type))
                   1785:        cp_error ("type `%#T' does not have a destructor", type);
                   1786:       else
                   1787: #endif
                   1788:       cp_error ("cannot call destructor `%T::~%T' without object", type,
                   1789:                method_name);
                   1790:       return error_mark_node;
                   1791:     }
                   1792: 
                   1793:   /* No object?  Then just fake one up, and let build_method_call
                   1794:      figure out what to do.  */
                   1795:   if (current_class_type == 0
                   1796:       || get_base_distance (type, current_class_type, 0, &basetype_path) == -1)
                   1797:     dont_use_this = 1;
                   1798: 
                   1799:   if (dont_use_this)
                   1800:     {
                   1801:       basetype_path = TYPE_BINFO (type);
1.1.1.2 ! root     1802:       decl = build1 (NOP_EXPR, build_pointer_type (type), error_mark_node);
1.1       root     1803:     }
                   1804:   else if (current_class_decl == 0)
                   1805:     {
                   1806:       dont_use_this = 1;
1.1.1.2 ! root     1807:       decl = build1 (NOP_EXPR, build_pointer_type (type), error_mark_node);
1.1       root     1808:     }
                   1809:   else
                   1810:     {
                   1811:       tree olddecl = current_class_decl;
                   1812:       tree oldtype = TREE_TYPE (TREE_TYPE (olddecl));
                   1813:       if (oldtype != type)
                   1814:        {
                   1815:          tree newtype = build_type_variant (type, TYPE_READONLY (oldtype),
                   1816:                                             TYPE_VOLATILE (oldtype));
1.1.1.2 ! root     1817:          decl = convert_force (build_pointer_type (newtype), olddecl, 0);
1.1       root     1818:        }
                   1819:       else
                   1820:        decl = olddecl;
                   1821:     }
                   1822: 
                   1823:   decl = build_indirect_ref (decl, NULL_PTR);
                   1824: 
1.1.1.2 ! root     1825:   if (method_name == constructor_name (type)
        !          1826:       || method_name == constructor_name_full (type))
        !          1827:     return build_functional_cast (type, parmlist);
1.1       root     1828:   if (t = lookup_fnfields (basetype_path, method_name, 0))
                   1829:     return build_method_call (decl, method_name, parmlist, basetype_path,
                   1830:                              LOOKUP_NORMAL|LOOKUP_NONVIRTUAL);
                   1831:   if (TREE_CODE (name) == IDENTIFIER_NODE
                   1832:       && ((t = lookup_field (TYPE_BINFO (type), name, 1, 0))))
                   1833:     {
                   1834:       if (t == error_mark_node)
                   1835:        return error_mark_node;
                   1836:       if (TREE_CODE (t) == FIELD_DECL)
                   1837:        {
                   1838:          if (dont_use_this)
                   1839:            {
                   1840:              cp_error ("invalid use of non-static field `%D'", t);
                   1841:              return error_mark_node;
                   1842:            }
                   1843:          decl = build (COMPONENT_REF, TREE_TYPE (t), decl, t);
                   1844:        }
                   1845:       else if (TREE_CODE (t) == VAR_DECL)
                   1846:        decl = t;
                   1847:       else
                   1848:        {
                   1849:          cp_error ("invalid use of member `%D'", t);
                   1850:          return error_mark_node;
                   1851:        }
                   1852:       if (TYPE_LANG_SPECIFIC (TREE_TYPE (decl))
                   1853:          && TYPE_OVERLOADS_CALL_EXPR (TREE_TYPE (decl)))
                   1854:        return build_opfncall (CALL_EXPR, LOOKUP_NORMAL, decl, parmlist, NULL_TREE);
                   1855:       return build_function_call (decl, parmlist);
                   1856:     }
                   1857:   else
                   1858:     {
                   1859:       cp_error ("no method `%T::%D'", type, name);
                   1860:       return error_mark_node;
                   1861:     }
                   1862: }
                   1863: 
                   1864: /* Build a reference to a member of an aggregate.  This is not a
                   1865:    C++ `&', but really something which can have its address taken,
                   1866:    and then act as a pointer to member, for example CNAME :: FIELD
                   1867:    can have its address taken by saying & CNAME :: FIELD.
                   1868: 
                   1869:    @@ Prints out lousy diagnostics for operator <typename>
                   1870:    @@ fields.
                   1871: 
                   1872:    @@ This function should be rewritten and placed in search.c.  */
                   1873: tree
                   1874: build_offset_ref (cname, name)
                   1875:      tree cname, name;
                   1876: {
                   1877:   tree decl, type, fnfields, fields, t = error_mark_node;
                   1878:   tree basetypes = NULL_TREE;
                   1879:   int dtor = 0;
                   1880: 
                   1881:   if (TREE_CODE (cname) == SCOPE_REF)
                   1882:     cname = resolve_scope_to_name (NULL_TREE, cname);
                   1883: 
1.1.1.2 ! root     1884:   /* Handle namespace names fully here.  */
        !          1885:   if (TREE_CODE (cname) == IDENTIFIER_NODE
        !          1886:       && get_aggr_from_typedef (cname, 0) == 0)
        !          1887:     {
        !          1888:       tree ns = lookup_name (cname, 0);
        !          1889:       tree val;
        !          1890:       if (ns && TREE_CODE (ns) == NAMESPACE_DECL)
        !          1891:        {
        !          1892:          val = lookup_namespace_name (ns, name);
        !          1893:          if (val)
        !          1894:            return val;
        !          1895:          cp_error ("namespace `%D' has no member named `%D'", ns, name);
        !          1896:          return error_mark_node;
        !          1897:        }
        !          1898:     }
        !          1899: 
1.1       root     1900:   if (cname == NULL_TREE || ! is_aggr_typedef (cname, 1))
                   1901:     return error_mark_node;
                   1902: 
                   1903:   type = IDENTIFIER_TYPE_VALUE (cname);
                   1904: 
                   1905:   if (TREE_CODE (name) == BIT_NOT_EXPR)
                   1906:     {
                   1907:       dtor = 1;
                   1908:       name = TREE_OPERAND (name, 0);
                   1909:     }
                   1910: 
                   1911:   if (TYPE_SIZE (type) == 0)
                   1912:     {
                   1913:       t = IDENTIFIER_CLASS_VALUE (name);
                   1914:       if (t == 0)
                   1915:        {
                   1916:          cp_error ("incomplete type `%T' does not have member `%D'", type,
                   1917:                      name);
                   1918:          return error_mark_node;
                   1919:        }
                   1920:       if (TREE_CODE (t) == TYPE_DECL || TREE_CODE (t) == VAR_DECL
                   1921:          || TREE_CODE (t) == CONST_DECL)
                   1922:        {
                   1923:          TREE_USED (t) = 1;
                   1924:          return t;
                   1925:        }
                   1926:       if (TREE_CODE (t) == FIELD_DECL)
                   1927:        sorry ("use of member in incomplete aggregate type");
                   1928:       else if (TREE_CODE (t) == FUNCTION_DECL)
                   1929:        sorry ("use of member function in incomplete aggregate type");
                   1930:       else
                   1931:        my_friendly_abort (52);
                   1932:       return error_mark_node;
                   1933:     }
                   1934: 
                   1935: #if 0
                   1936:   if (TREE_CODE (name) == TYPE_EXPR)
                   1937:     /* Pass a TYPE_DECL to build_component_type_expr.  */
                   1938:     return build_component_type_expr (TYPE_NAME (TREE_TYPE (cname)),
                   1939:                                      name, NULL_TREE, 1);
                   1940: #endif
                   1941: 
                   1942:   if (current_class_type == 0
                   1943:       || get_base_distance (type, current_class_type, 0, &basetypes) == -1)
                   1944:     {
                   1945:       basetypes = TYPE_BINFO (type);
                   1946:       decl = build1 (NOP_EXPR,
                   1947:                     IDENTIFIER_TYPE_VALUE (cname),
                   1948:                     error_mark_node);
                   1949:     }
                   1950:   else if (current_class_decl == 0)
                   1951:     decl = build1 (NOP_EXPR, IDENTIFIER_TYPE_VALUE (cname),
                   1952:                   error_mark_node);
                   1953:   else
                   1954:     decl = C_C_D;
                   1955: 
                   1956:   fnfields = lookup_fnfields (basetypes, name, 1);
                   1957:   fields = lookup_field (basetypes, name, 0, 0);
                   1958: 
                   1959:   if (fields == error_mark_node || fnfields == error_mark_node)
                   1960:     return error_mark_node;
                   1961: 
                   1962:   /* A lot of this logic is now handled in lookup_field and
                   1963:      lookup_fnfield. */
                   1964:   if (fnfields)
                   1965:     {
                   1966:       basetypes = TREE_PURPOSE (fnfields);
                   1967: 
                   1968:       /* Go from the TREE_BASELINK to the member function info.  */
                   1969:       t = TREE_VALUE (fnfields);
                   1970: 
                   1971:       if (fields)
                   1972:        {
                   1973:          if (DECL_FIELD_CONTEXT (fields) == DECL_FIELD_CONTEXT (t))
                   1974:            {
                   1975:              error ("ambiguous member reference: member `%s' defined as both field and function",
                   1976:                     IDENTIFIER_POINTER (name));
                   1977:              return error_mark_node;
                   1978:            }
                   1979:          if (UNIQUELY_DERIVED_FROM_P (DECL_FIELD_CONTEXT (fields), DECL_FIELD_CONTEXT (t)))
                   1980:            ;
                   1981:          else if (UNIQUELY_DERIVED_FROM_P (DECL_FIELD_CONTEXT (t), DECL_FIELD_CONTEXT (fields)))
                   1982:            t = fields;
                   1983:          else
                   1984:            {
                   1985:              error ("ambiguous member reference: member `%s' derives from distinct classes in multiple inheritance lattice");
                   1986:              return error_mark_node;
                   1987:            }
                   1988:        }
                   1989: 
                   1990:       if (t == TREE_VALUE (fnfields))
                   1991:        {
                   1992:          extern int flag_save_memoized_contexts;
                   1993: 
                   1994:          if (DECL_CHAIN (t) == NULL_TREE || dtor)
                   1995:            {
                   1996:              enum access_type access;
                   1997: 
                   1998:              /* unique functions are handled easily.  */
                   1999:            unique:
                   2000:              access = compute_access (basetypes, t);
                   2001:              if (access == access_protected)
                   2002:                {
                   2003:                  cp_error_at ("member function `%#D' is protected", t);
                   2004:                  error ("in this context");
                   2005:                  return error_mark_node;
                   2006:                }
                   2007:              if (access == access_private)
                   2008:                {
                   2009:                  cp_error_at ("member function `%#D' is private", t);
                   2010:                  error ("in this context");
                   2011:                  return error_mark_node;
                   2012:                }
                   2013:              assemble_external (t);
                   2014:              return build (OFFSET_REF, TREE_TYPE (t), decl, t);
                   2015:            }
                   2016: 
                   2017:          /* overloaded functions may need more work.  */
                   2018:          if (cname == name)
                   2019:            {
                   2020:              if (TYPE_HAS_DESTRUCTOR (type)
                   2021:                  && DECL_CHAIN (DECL_CHAIN (t)) == NULL_TREE)
                   2022:                {
                   2023:                  t = DECL_CHAIN (t);
                   2024:                  goto unique;
                   2025:                }
                   2026:            }
                   2027:          /* FNFIELDS is most likely allocated on the search_obstack,
                   2028:             which will go away after this class scope.  If we need
                   2029:             to save this value for later (either for memoization
                   2030:             or for use as an initializer for a static variable), then
                   2031:             do so here.
                   2032: 
                   2033:             ??? The smart thing to do for the case of saving initializers
                   2034:             is to resolve them before we're done with this scope.  */
                   2035:          if (!TREE_PERMANENT (fnfields)
                   2036:              && ((flag_save_memoized_contexts && global_bindings_p ())
                   2037:                  || ! allocation_temporary_p ()))
                   2038:            fnfields = copy_list (fnfields);
1.1.1.2 ! root     2039: 
        !          2040:          for (t = TREE_VALUE (fnfields); t; t = DECL_CHAIN (t))
        !          2041:            assemble_external (t);
        !          2042: 
1.1       root     2043:          t = build_tree_list (error_mark_node, fnfields);
                   2044:          TREE_TYPE (t) = build_offset_type (type, unknown_type_node);
                   2045:          return t;
                   2046:        }
                   2047:     }
                   2048: 
                   2049:   /* Now that we know we are looking for a field, see if we
                   2050:      have access to that field.  Lookup_field will give us the
                   2051:      error message.  */
                   2052: 
                   2053:   t = lookup_field (basetypes, name, 1, 0);
                   2054: 
                   2055:   if (t == error_mark_node)
                   2056:     return error_mark_node;
                   2057: 
                   2058:   if (t == NULL_TREE)
                   2059:     {
                   2060:       cp_error ("`%D' is not a member of type `%T'", name, type);
                   2061:       return error_mark_node;
                   2062:     }
                   2063: 
                   2064:   if (TREE_CODE (t) == TYPE_DECL)
                   2065:     {
                   2066:       TREE_USED (t) = 1;
                   2067:       return t;
                   2068:     }
                   2069:   /* static class members and class-specific enum
                   2070:      values can be returned without further ado.  */
                   2071:   if (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == CONST_DECL)
                   2072:     {
                   2073:       assemble_external (t);
                   2074:       TREE_USED (t) = 1;
                   2075:       return t;
                   2076:     }
                   2077: 
1.1.1.2 ! root     2078:   if (TREE_CODE (t) == FIELD_DECL && DECL_BIT_FIELD (t))
        !          2079:     {
        !          2080:       cp_error ("illegal pointer to bit field `%D'", t);
        !          2081:       return error_mark_node;
        !          2082:     }
        !          2083: 
1.1       root     2084:   /* static class functions too.  */
                   2085:   if (TREE_CODE (t) == FUNCTION_DECL && TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
                   2086:     my_friendly_abort (53);
                   2087: 
                   2088:   /* In member functions, the form `cname::name' is no longer
                   2089:      equivalent to `this->cname::name'.  */
                   2090:   return build (OFFSET_REF, build_offset_type (type, TREE_TYPE (t)), decl, t);
                   2091: }
                   2092: 
                   2093: /* Given an object EXP and a member function reference MEMBER,
                   2094:    return the address of the actual member function.  */
                   2095: tree
                   2096: get_member_function (exp_addr_ptr, exp, member)
                   2097:      tree *exp_addr_ptr;
                   2098:      tree exp, member;
                   2099: {
                   2100:   tree ctype = TREE_TYPE (exp);
                   2101:   tree function = save_expr (build_unary_op (ADDR_EXPR, member, 0));
                   2102: 
                   2103:   if (TYPE_VIRTUAL_P (ctype)
                   2104:       || (flag_all_virtual == 1 && TYPE_OVERLOADS_METHOD_CALL_EXPR (ctype)))
                   2105:     {
                   2106:       tree e0, e1, e3;
                   2107:       tree exp_addr;
                   2108: 
                   2109:       /* Save away the unadulterated `this' pointer.  */
                   2110:       exp_addr = save_expr (*exp_addr_ptr);
                   2111: 
                   2112:       /* Cast function to signed integer.  */
                   2113:       e0 = build1 (NOP_EXPR, integer_type_node, function);
                   2114: 
                   2115:       /* There is a hack here that takes advantage of
                   2116:         twos complement arithmetic, and the fact that
                   2117:         there are more than one UNITS to the WORD.
                   2118:         If the high bit is set for the `function',
                   2119:         then we pretend it is a virtual function,
                   2120:         and the array indexing will knock this bit
                   2121:         out the top, leaving a valid index.  */
                   2122:       if (UNITS_PER_WORD <= 1)
                   2123:        my_friendly_abort (54);
                   2124: 
1.1.1.2 ! root     2125:       e1 = build (GT_EXPR, boolean_type_node, e0, integer_zero_node);
1.1       root     2126:       e1 = build_compound_expr (tree_cons (NULL_TREE, exp_addr,
                   2127:                                           build_tree_list (NULL_TREE, e1)));
                   2128:       e1 = save_expr (e1);
                   2129: 
                   2130:       if (TREE_SIDE_EFFECTS (*exp_addr_ptr))
                   2131:        {
                   2132:          exp = build_indirect_ref (exp_addr, NULL_PTR);
                   2133:          *exp_addr_ptr = exp_addr;
                   2134:        }
                   2135: 
                   2136:       /* This is really hairy: if the function pointer is a pointer
                   2137:         to a non-virtual member function, then we can't go mucking
                   2138:         with the `this' pointer (any more than we already have to
                   2139:         this point).  If it is a pointer to a virtual member function,
                   2140:         then we have to adjust the `this' pointer according to
                   2141:         what the virtual function table tells us.  */
                   2142: 
                   2143:       e3 = build_vfn_ref (exp_addr_ptr, exp, e0);
                   2144:       my_friendly_assert (e3 != error_mark_node, 213);
                   2145: 
                   2146:       /* Change this pointer type from `void *' to the
                   2147:         type it is really supposed to be.  */
                   2148:       TREE_TYPE (e3) = TREE_TYPE (function);
                   2149: 
                   2150:       /* If non-virtual, use what we had originally.  Otherwise,
                   2151:         use the value we get from the virtual function table.  */
                   2152:       *exp_addr_ptr = build_conditional_expr (e1, exp_addr, *exp_addr_ptr);
                   2153: 
                   2154:       function = build_conditional_expr (e1, function, e3);
                   2155:     }
                   2156:   return build_indirect_ref (function, NULL_PTR);
                   2157: }
                   2158: 
                   2159: /* If a OFFSET_REF made it through to here, then it did
                   2160:    not have its address taken.  */
                   2161: 
                   2162: tree
                   2163: resolve_offset_ref (exp)
                   2164:      tree exp;
                   2165: {
                   2166:   tree type = TREE_TYPE (exp);
                   2167:   tree base = NULL_TREE;
                   2168:   tree member;
                   2169:   tree basetype, addr;
                   2170: 
                   2171:   if (TREE_CODE (exp) == TREE_LIST)
                   2172:     return build_unary_op (ADDR_EXPR, exp, 0);
                   2173: 
                   2174:   if (TREE_CODE (exp) != OFFSET_REF)
                   2175:     {
                   2176:       my_friendly_assert (TREE_CODE (type) == OFFSET_TYPE, 214);
                   2177:       if (TYPE_OFFSET_BASETYPE (type) != current_class_type)
                   2178:        {
                   2179:          error ("object missing in use of pointer-to-member construct");
                   2180:          return error_mark_node;
                   2181:        }
                   2182:       member = exp;
                   2183:       type = TREE_TYPE (type);
                   2184:       base = C_C_D;
                   2185:     }
                   2186:   else
                   2187:     {
                   2188:       member = TREE_OPERAND (exp, 1);
                   2189:       base = TREE_OPERAND (exp, 0);
                   2190:     }
                   2191: 
                   2192:   if ((TREE_CODE (member) == VAR_DECL
                   2193:        && ! TYPE_PTRMEMFUNC_P (TREE_TYPE (member)))
                   2194:       || TREE_CODE (TREE_TYPE (member)) == FUNCTION_TYPE)
                   2195:     {
                   2196:       /* These were static members.  */
                   2197:       if (mark_addressable (member) == 0)
                   2198:        return error_mark_node;
                   2199:       return member;
                   2200:     }
                   2201: 
                   2202:   /* Syntax error can cause a member which should
                   2203:      have been seen as static to be grok'd as non-static.  */
                   2204:   if (TREE_CODE (member) == FIELD_DECL && C_C_D == NULL_TREE)
                   2205:     {
                   2206:       if (TREE_ADDRESSABLE (member) == 0)
                   2207:        {
1.1.1.2 ! root     2208:          cp_error_at ("member `%D' is non-static but referenced as a static member",
        !          2209:                       member);
1.1       root     2210:          error ("at this point in file");
                   2211:          TREE_ADDRESSABLE (member) = 1;
                   2212:        }
                   2213:       return error_mark_node;
                   2214:     }
                   2215: 
                   2216:   /* The first case is really just a reference to a member of `this'.  */
                   2217:   if (TREE_CODE (member) == FIELD_DECL
                   2218:       && (base == C_C_D
                   2219:          || (TREE_CODE (base) == NOP_EXPR
                   2220:              && TREE_OPERAND (base, 0) == error_mark_node)))
                   2221:     {
                   2222:       tree basetype_path;
                   2223:       enum access_type access;
                   2224: 
                   2225:       if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE)
                   2226:        basetype = TYPE_OFFSET_BASETYPE (type);
                   2227:       else
                   2228:        basetype = DECL_CONTEXT (member);
                   2229: 
                   2230:       base = current_class_decl;
                   2231:       
                   2232:       if (get_base_distance (basetype, TREE_TYPE (TREE_TYPE (base)), 0, &basetype_path) < 0)
                   2233:        {
                   2234:          error_not_base_type (basetype, TREE_TYPE (TREE_TYPE (base)));
                   2235:          return error_mark_node;
                   2236:        }
                   2237:       addr = convert_pointer_to (basetype, base);
                   2238:       access = compute_access (basetype_path, member);
                   2239:       if (access == access_public)
                   2240:        return build (COMPONENT_REF, TREE_TYPE (member),
                   2241:                      build_indirect_ref (addr, NULL_PTR), member);
                   2242:       if (access == access_protected)
                   2243:        {
                   2244:          cp_error_at ("member `%D' is protected", member);
                   2245:          error ("in this context");
                   2246:          return error_mark_node;
                   2247:        }
                   2248:       if (access == access_private)
                   2249:        {
                   2250:          cp_error_at ("member `%D' is private", member);
                   2251:          error ("in this context");
                   2252:          return error_mark_node;
                   2253:        }
                   2254:       my_friendly_abort (55);
                   2255:     }
                   2256: 
                   2257:   /* If this is a reference to a member function, then return
                   2258:      the address of the member function (which may involve going
                   2259:      through the object's vtable), otherwise, return an expression
                   2260:      for the dereferenced pointer-to-member construct.  */
                   2261:   addr = build_unary_op (ADDR_EXPR, base, 0);
                   2262: 
                   2263:   if (TREE_CODE (TREE_TYPE (member)) == METHOD_TYPE)
                   2264:     {
                   2265:       basetype = DECL_CLASS_CONTEXT (member);
                   2266:       addr = convert_pointer_to (basetype, addr);
                   2267:       return build_unary_op (ADDR_EXPR, get_member_function (&addr, build_indirect_ref (addr, NULL_PTR), member), 0);
                   2268:     }
                   2269:   else if (TREE_CODE (TREE_TYPE (member)) == OFFSET_TYPE)
                   2270:     {
                   2271:       basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (member));
                   2272:       addr = convert_pointer_to (basetype, addr);
                   2273:       member = convert (ptrdiff_type_node,
                   2274:                        build_unary_op (ADDR_EXPR, member, 0));
                   2275:       return build1 (INDIRECT_REF, type,
                   2276:                     build (PLUS_EXPR, build_pointer_type (type),
                   2277:                            addr, member));
                   2278:     }
                   2279:   else if (TYPE_PTRMEMFUNC_P (TREE_TYPE (member)))
                   2280:     {
1.1.1.2 ! root     2281:       return get_member_function_from_ptrfunc (&addr, member);
1.1       root     2282:     }
                   2283:   my_friendly_abort (56);
                   2284:   /* NOTREACHED */
                   2285:   return NULL_TREE;
                   2286: }
                   2287: 
                   2288: /* Return either DECL or its known constant value (if it has one).  */
                   2289: 
                   2290: tree
                   2291: decl_constant_value (decl)
                   2292:      tree decl;
                   2293: {
                   2294:   if (! TREE_THIS_VOLATILE (decl)
                   2295: #if 0
                   2296:       /* These may be necessary for C, but they break C++.  */
                   2297:       ! TREE_PUBLIC (decl)
                   2298:       /* Don't change a variable array bound or initial value to a constant
                   2299:         in a place where a variable is invalid.  */
                   2300:       && ! pedantic
                   2301: #endif /* 0 */
                   2302:       && DECL_INITIAL (decl) != 0
                   2303:       && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK
                   2304:       /* This is invalid if initial value is not constant.
                   2305:         If it has either a function call, a memory reference,
                   2306:         or a variable, then re-evaluating it could give different results.  */
                   2307:       && TREE_CONSTANT (DECL_INITIAL (decl))
                   2308:       /* Check for cases where this is sub-optimal, even though valid.  */
                   2309:       && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR
                   2310: #if 0
                   2311:       /* We must allow this to work outside of functions so that
                   2312:         static constants can be used for array sizes.  */
                   2313:       && current_function_decl != 0
                   2314:       && DECL_MODE (decl) != BLKmode
                   2315: #endif
                   2316:       )
                   2317:     return DECL_INITIAL (decl);
                   2318:   return decl;
                   2319: }
                   2320: 
                   2321: /* Friend handling routines.  */
                   2322: /* Friend data structures:
                   2323: 
                   2324:    Lists of friend functions come from TYPE_DECL nodes.  Since all
                   2325:    aggregate types are automatically typedef'd, these nodes are guaranteed
                   2326:    to exist.
                   2327: 
                   2328:    The TREE_PURPOSE of a friend list is the name of the friend,
                   2329:    and its TREE_VALUE is another list.
                   2330: 
                   2331:    For each element of that list, either the TREE_VALUE or the TREE_PURPOSE
                   2332:    will be filled in, but not both.  The TREE_VALUE of that list is an
                   2333:    individual function which is a friend.  The TREE_PURPOSE of that list
                   2334:    indicates a type in which all functions by that name are friends.
                   2335: 
                   2336:    Lists of friend classes come from _TYPE nodes.  Love that consistency
                   2337:    thang.  */
                   2338: 
                   2339: int
                   2340: is_friend_type (type1, type2)
                   2341:      tree type1, type2;
                   2342: {
                   2343:   return is_friend (type1, type2);
                   2344: }
                   2345: 
                   2346: int
                   2347: is_friend (type, supplicant)
                   2348:      tree type, supplicant;
                   2349: {
                   2350:   int declp;
                   2351:   register tree list;
                   2352: 
                   2353:   if (supplicant == NULL_TREE || type == NULL_TREE)
                   2354:     return 0;
                   2355: 
                   2356:   declp = (TREE_CODE_CLASS (TREE_CODE (supplicant)) == 'd');
                   2357: 
                   2358:   if (declp)
                   2359:     /* It's a function decl.  */
                   2360:     {
                   2361:       tree list = DECL_FRIENDLIST (TYPE_NAME (type));
                   2362:       tree name = DECL_NAME (supplicant);
1.1.1.2 ! root     2363:       tree ctype;
        !          2364: 
        !          2365:       if (DECL_FUNCTION_MEMBER_P (supplicant))
        !          2366:        ctype = DECL_CLASS_CONTEXT (supplicant);
        !          2367:       else
        !          2368:        ctype = NULL_TREE;
        !          2369: 
1.1       root     2370:       for (; list ; list = TREE_CHAIN (list))
                   2371:        {
                   2372:          if (name == TREE_PURPOSE (list))
                   2373:            {
                   2374:              tree friends = TREE_VALUE (list);
                   2375:              name = DECL_ASSEMBLER_NAME (supplicant);
                   2376:              for (; friends ; friends = TREE_CHAIN (friends))
                   2377:                {
                   2378:                  if (ctype == TREE_PURPOSE (friends))
                   2379:                    return 1;
                   2380:                  if (name == DECL_ASSEMBLER_NAME (TREE_VALUE (friends)))
                   2381:                    return 1;
                   2382:                }
                   2383:              break;
                   2384:            }
                   2385:        }
                   2386:     }
                   2387:   else
                   2388:     /* It's a type. */
                   2389:     {
                   2390:       if (type == supplicant)
                   2391:        return 1;
                   2392:       
                   2393:       list = CLASSTYPE_FRIEND_CLASSES (TREE_TYPE (TYPE_NAME (type)));
                   2394:       for (; list ; list = TREE_CHAIN (list))
                   2395:        if (supplicant == TREE_VALUE (list))
                   2396:          return 1;
                   2397:     }      
                   2398: 
                   2399:   {
1.1.1.2 ! root     2400:     tree context;
        !          2401: 
        !          2402:     if (! declp)
        !          2403:       context = DECL_CONTEXT (TYPE_NAME (supplicant));
        !          2404:     else if (DECL_FUNCTION_MEMBER_P (supplicant))
        !          2405:       context = DECL_CLASS_CONTEXT (supplicant);
        !          2406:     else
        !          2407:       context = NULL_TREE;
1.1       root     2408: 
                   2409:     if (context)
                   2410:       return is_friend (type, context);
                   2411:   }
                   2412: 
                   2413:   return 0;
                   2414: }
                   2415: 
                   2416: /* Add a new friend to the friends of the aggregate type TYPE.
                   2417:    DECL is the FUNCTION_DECL of the friend being added.  */
                   2418: static void
                   2419: add_friend (type, decl)
                   2420:      tree type, decl;
                   2421: {
                   2422:   tree typedecl = TYPE_NAME (type);
                   2423:   tree list = DECL_FRIENDLIST (typedecl);
                   2424:   tree name = DECL_NAME (decl);
                   2425: 
                   2426:   while (list)
                   2427:     {
                   2428:       if (name == TREE_PURPOSE (list))
                   2429:        {
                   2430:          tree friends = TREE_VALUE (list);
                   2431:          for (; friends ; friends = TREE_CHAIN (friends))
                   2432:            {
                   2433:              if (decl == TREE_VALUE (friends))
                   2434:                {
1.1.1.2 ! root     2435:                  cp_warning ("`%D' is already a friend of class `%T'",
1.1       root     2436:                              decl, type);
1.1.1.2 ! root     2437:                  cp_warning_at ("previous friend declaration of `%D'",
1.1       root     2438:                                 TREE_VALUE (friends));
                   2439:                  return;
                   2440:                }
                   2441:            }
                   2442:          TREE_VALUE (list) = tree_cons (error_mark_node, decl,
                   2443:                                         TREE_VALUE (list));
                   2444:          return;
                   2445:        }
                   2446:       list = TREE_CHAIN (list);
                   2447:     }
                   2448:   DECL_FRIENDLIST (typedecl)
                   2449:     = tree_cons (DECL_NAME (decl), build_tree_list (error_mark_node, decl),
                   2450:                 DECL_FRIENDLIST (typedecl));
                   2451:   if (DECL_NAME (decl) == ansi_opname[(int) MODIFY_EXPR])
                   2452:     {
                   2453:       tree parmtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
                   2454:       TYPE_HAS_ASSIGNMENT (TREE_TYPE (typedecl)) = 1;
                   2455:       if (parmtypes && TREE_CHAIN (parmtypes))
                   2456:        {
                   2457:          tree parmtype = TREE_VALUE (TREE_CHAIN (parmtypes));
                   2458:          if (TREE_CODE (parmtype) == REFERENCE_TYPE
                   2459:              && TREE_TYPE (parmtypes) == TREE_TYPE (typedecl))
                   2460:            TYPE_HAS_ASSIGN_REF (TREE_TYPE (typedecl)) = 1;
                   2461:        }
                   2462:     }
                   2463: }
                   2464: 
                   2465: /* Declare that every member function NAME in FRIEND_TYPE
                   2466:    (which may be NULL_TREE) is a friend of type TYPE.  */
                   2467: static void
                   2468: add_friends (type, name, friend_type)
                   2469:      tree type, name, friend_type;
                   2470: {
                   2471:   tree typedecl = TYPE_NAME (type);
                   2472:   tree list = DECL_FRIENDLIST (typedecl);
                   2473: 
                   2474:   while (list)
                   2475:     {
                   2476:       if (name == TREE_PURPOSE (list))
                   2477:        {
                   2478:          tree friends = TREE_VALUE (list);
                   2479:          while (friends && TREE_PURPOSE (friends) != friend_type)
                   2480:            friends = TREE_CHAIN (friends);
                   2481:          if (friends)
                   2482:            if (friend_type)
                   2483:              warning ("method `%s::%s' is already a friend of class",
                   2484:                       TYPE_NAME_STRING (friend_type),
                   2485:                       IDENTIFIER_POINTER (name));
                   2486:            else
                   2487:              warning ("function `%s' is already a friend of class `%s'",
                   2488:                       IDENTIFIER_POINTER (name),
                   2489:                       IDENTIFIER_POINTER (DECL_NAME (typedecl)));
                   2490:          else
                   2491:            TREE_VALUE (list) = tree_cons (friend_type, NULL_TREE,
                   2492:                                           TREE_VALUE (list));
                   2493:          return;
                   2494:        }
                   2495:       list = TREE_CHAIN (list);
                   2496:     }
                   2497:   DECL_FRIENDLIST (typedecl) =
                   2498:     tree_cons (name,
                   2499:               build_tree_list (friend_type, NULL_TREE),
                   2500:               DECL_FRIENDLIST (typedecl));
                   2501:   if (! strncmp (IDENTIFIER_POINTER (name),
                   2502:                 IDENTIFIER_POINTER (ansi_opname[(int) MODIFY_EXPR]),
                   2503:                 strlen (IDENTIFIER_POINTER (ansi_opname[(int) MODIFY_EXPR]))))
                   2504:     {
                   2505:       TYPE_HAS_ASSIGNMENT (TREE_TYPE (typedecl)) = 1;
                   2506:       sorry ("declaring \"friend operator =\" will not find \"operator = (X&)\" if it exists");
                   2507:     }
                   2508: }
                   2509: 
                   2510: /* Set up a cross reference so that type TYPE will make member function
                   2511:    CTYPE::DECL a friend when CTYPE is finally defined.  For more than
                   2512:    one, set up a cross reference so that functions with the name DECL
                   2513:    and type CTYPE know that they are friends of TYPE.  */
                   2514: static void
                   2515: xref_friend (type, decl, ctype)
                   2516:      tree type, decl, ctype;
                   2517: {
                   2518:   tree friend_decl = TYPE_NAME (ctype);
                   2519: #if 0
                   2520:   tree typedecl = TYPE_NAME (type);
                   2521:   tree t = tree_cons (NULL_TREE, ctype, DECL_UNDEFINED_FRIENDS (typedecl));
                   2522: 
                   2523:   DECL_UNDEFINED_FRIENDS (typedecl) = t;
                   2524: #else
                   2525:   tree t = 0;
                   2526: #endif
                   2527:   SET_DECL_WAITING_FRIENDS (friend_decl,
                   2528:                            tree_cons (type, t,
                   2529:                                       DECL_WAITING_FRIENDS (friend_decl)));
                   2530:   TREE_TYPE (DECL_WAITING_FRIENDS (friend_decl)) = decl;
                   2531: }
                   2532: 
                   2533: /* Make FRIEND_TYPE a friend class to TYPE.  If FRIEND_TYPE has already
                   2534:    been defined, we make all of its member functions friends of
                   2535:    TYPE.  If not, we make it a pending friend, which can later be added
                   2536:    when its definition is seen.  If a type is defined, then its TYPE_DECL's
                   2537:    DECL_UNDEFINED_FRIENDS contains a (possibly empty) list of friend
                   2538:    classes that are not defined.  If a type has not yet been defined,
                   2539:    then the DECL_WAITING_FRIENDS contains a list of types
                   2540:    waiting to make it their friend.  Note that these two can both
                   2541:    be in use at the same time!  */
                   2542: void
                   2543: make_friend_class (type, friend_type)
                   2544:      tree type, friend_type;
                   2545: {
                   2546:   tree classes;
                   2547: 
                   2548:   if (IS_SIGNATURE (type))
                   2549:     {
                   2550:       error ("`friend' declaration in signature definition");
                   2551:       return;
                   2552:     }
                   2553:   if (IS_SIGNATURE (friend_type))
                   2554:     {
                   2555:       error ("signature type `%s' declared `friend'",
                   2556:             IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (friend_type))));
                   2557:       return;
                   2558:     }
                   2559:   if (type == friend_type)
                   2560:     {
1.1.1.2 ! root     2561:       pedwarn ("class `%s' is implicitly friends with itself",
1.1       root     2562:               TYPE_NAME_STRING (type));
                   2563:       return;
                   2564:     }
                   2565: 
                   2566:   GNU_xref_hier (TYPE_NAME_STRING (type),
                   2567:                 TYPE_NAME_STRING (friend_type), 0, 0, 1);
                   2568: 
                   2569:   classes = CLASSTYPE_FRIEND_CLASSES (type);
                   2570:   while (classes && TREE_VALUE (classes) != friend_type)
                   2571:     classes = TREE_CHAIN (classes);
                   2572:   if (classes)
                   2573:     warning ("class `%s' is already friends with class `%s'",
                   2574:             TYPE_NAME_STRING (TREE_VALUE (classes)), TYPE_NAME_STRING (type));
                   2575:   else
                   2576:     {
                   2577:       CLASSTYPE_FRIEND_CLASSES (type)
                   2578:        = tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type));
                   2579:     }
                   2580: }
                   2581: 
                   2582: /* Main friend processor.  This is large, and for modularity purposes,
                   2583:    has been removed from grokdeclarator.  It returns `void_type_node'
                   2584:    to indicate that something happened, though a FIELD_DECL is
                   2585:    not returned.
                   2586: 
                   2587:    CTYPE is the class this friend belongs to.
                   2588: 
                   2589:    DECLARATOR is the name of the friend.
                   2590: 
                   2591:    DECL is the FUNCTION_DECL that the friend is.
                   2592: 
                   2593:    In case we are parsing a friend which is part of an inline
                   2594:    definition, we will need to store PARM_DECL chain that comes
                   2595:    with it into the DECL_ARGUMENTS slot of the FUNCTION_DECL.
                   2596: 
                   2597:    FLAGS is just used for `grokclassfn'.
                   2598: 
                   2599:    QUALS say what special qualifies should apply to the object
                   2600:    pointed to by `this'.  */
                   2601: tree
                   2602: do_friend (ctype, declarator, decl, parmdecls, flags, quals)
                   2603:      tree ctype, declarator, decl, parmdecls;
                   2604:      enum overload_flags flags;
                   2605:      tree quals;
                   2606: {
                   2607:   /* Every decl that gets here is a friend of something.  */
                   2608:   DECL_FRIEND_P (decl) = 1;
                   2609: 
                   2610:   if (ctype)
                   2611:     {
                   2612:       tree cname = TYPE_NAME (ctype);
                   2613:       if (TREE_CODE (cname) == TYPE_DECL)
                   2614:        cname = DECL_NAME (cname);
                   2615: 
                   2616:       /* A method friend.  */
                   2617:       if (TREE_CODE (decl) == FUNCTION_DECL)
                   2618:        {
                   2619:          if (flags == NO_SPECIAL && ctype && declarator == cname)
                   2620:            DECL_CONSTRUCTOR_P (decl) = 1;
                   2621: 
                   2622:          /* This will set up DECL_ARGUMENTS for us.  */
                   2623:          grokclassfn (ctype, cname, decl, flags, quals);
                   2624:          if (TYPE_SIZE (ctype) != 0)
                   2625:            check_classfn (ctype, cname, decl);
                   2626: 
                   2627:          if (TREE_TYPE (decl) != error_mark_node)
                   2628:            {
                   2629:              if (TYPE_SIZE (ctype))
                   2630:                {
                   2631:                  /* We don't call pushdecl here yet, or ever on this
                   2632:                     actual FUNCTION_DECL.  We must preserve its TREE_CHAIN
                   2633:                     until the end.  */
                   2634:                  make_decl_rtl (decl, NULL_PTR, 1);
                   2635:                  add_friend (current_class_type, decl);
                   2636:                }
                   2637:              else
                   2638:                {
                   2639:                  register char *classname
                   2640:                    = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (ctype)));
                   2641: 
                   2642:                  error ("member declared as friend before type `%s' defined",
                   2643:                         classname);
                   2644:                }
                   2645:            }
                   2646:        }
                   2647:       else
                   2648:        {
                   2649:          /* Possibly a bunch of method friends.  */
                   2650: 
                   2651:          /* Get the class they belong to.  */
                   2652:          tree ctype = IDENTIFIER_TYPE_VALUE (cname);
                   2653: 
                   2654:          /* This class is defined, use its methods now.  */
                   2655:          if (TYPE_SIZE (ctype))
                   2656:            {
                   2657:              tree fields = lookup_fnfields (TYPE_BINFO (ctype), declarator, 0);
                   2658:              if (fields)
                   2659:                add_friends (current_class_type, declarator, ctype);
                   2660:              else
                   2661:                error ("method `%s' is not a member of class `%s'",
                   2662:                       IDENTIFIER_POINTER (declarator),
                   2663:                       IDENTIFIER_POINTER (cname));
                   2664:            }
                   2665:          else
                   2666:            /* Note: DECLARATOR actually has more than one; in this
                   2667:               case, we're making sure that fns with the name DECLARATOR
                   2668:               and type CTYPE know they are friends of the current
                   2669:               class type.  */
                   2670:            xref_friend (current_class_type, declarator, ctype);
                   2671:          decl = void_type_node;
                   2672:        }
                   2673:     }
                   2674:   else if (TREE_CODE (decl) == FUNCTION_DECL
                   2675:           && ((IDENTIFIER_LENGTH (declarator) == 4
                   2676:                && IDENTIFIER_POINTER (declarator)[0] == 'm'
                   2677:                && ! strcmp (IDENTIFIER_POINTER (declarator), "main"))
                   2678:               || (IDENTIFIER_LENGTH (declarator) > 10
                   2679:                   && IDENTIFIER_POINTER (declarator)[0] == '_'
                   2680:                   && IDENTIFIER_POINTER (declarator)[1] == '_'
                   2681:                   && strncmp (IDENTIFIER_POINTER (declarator)+2,
                   2682:                               "builtin_", 8) == 0)))
                   2683:     {
                   2684:       /* raw "main", and builtin functions never gets overloaded,
                   2685:         but they can become friends.  */
                   2686:       add_friend (current_class_type, decl);
                   2687:       DECL_FRIEND_P (decl) = 1;
                   2688:       decl = void_type_node;
                   2689:     }
                   2690:   /* A global friend.
                   2691:      @@ or possibly a friend from a base class ?!?  */
                   2692:   else if (TREE_CODE (decl) == FUNCTION_DECL)
                   2693:     {
                   2694:       /* Friends must all go through the overload machinery,
                   2695:         even though they may not technically be overloaded.
                   2696: 
                   2697:         Note that because classes all wind up being top-level
                   2698:         in their scope, their friend wind up in top-level scope as well.  */
                   2699:       DECL_ASSEMBLER_NAME (decl)
                   2700:        = build_decl_overload (declarator, TYPE_ARG_TYPES (TREE_TYPE (decl)),
                   2701:                               TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE);
                   2702:       DECL_ARGUMENTS (decl) = parmdecls;
                   2703:       DECL_CLASS_CONTEXT (decl) = current_class_type;
                   2704: 
                   2705:       /* We can call pushdecl here, because the TREE_CHAIN of this
                   2706:         FUNCTION_DECL is not needed for other purposes.  */
                   2707:       decl = pushdecl (decl);
                   2708: 
                   2709:       make_decl_rtl (decl, NULL_PTR, 1);
                   2710:       add_friend (current_class_type, decl);
                   2711: 
                   2712:       DECL_FRIEND_P (decl) = 1;
                   2713: #if 0
                   2714:       TREE_OVERLOADED (declarator) = 1;
                   2715: #endif
                   2716:     }
                   2717:   else
                   2718:     {
                   2719:       /* @@ Should be able to ingest later definitions of this function
                   2720:         before use.  */
                   2721:       tree decl = lookup_name_nonclass (declarator);
                   2722:       if (decl == NULL_TREE)
                   2723:        {
                   2724:          warning ("implicitly declaring `%s' as struct",
                   2725:                   IDENTIFIER_POINTER (declarator));
                   2726:          decl = xref_tag (record_type_node, declarator, NULL_TREE, 1);
                   2727:          decl = TYPE_NAME (decl);
                   2728:        }
                   2729: 
                   2730:       /* Allow abbreviated declarations of overloaded functions,
                   2731:         but not if those functions are really class names.  */
                   2732:       if (TREE_CODE (decl) == TREE_LIST && TREE_TYPE (TREE_PURPOSE (decl)))
                   2733:        {
                   2734:          warning ("`friend %s' archaic, use `friend class %s' instead",
                   2735:                   IDENTIFIER_POINTER (declarator),
                   2736:                   IDENTIFIER_POINTER (declarator));
                   2737:          decl = TREE_TYPE (TREE_PURPOSE (decl));
                   2738:        }
                   2739: 
                   2740:       if (TREE_CODE (decl) == TREE_LIST)
                   2741:        add_friends (current_class_type, TREE_PURPOSE (decl), NULL_TREE);
                   2742:       else
                   2743:        make_friend_class (current_class_type, TREE_TYPE (decl));
                   2744:       decl = void_type_node;
                   2745:     }
                   2746:   return decl;
                   2747: }
                   2748: 
                   2749: /* TYPE has now been defined.  It may, however, have a number of things
                   2750:    waiting make make it their friend.  We resolve these references
                   2751:    here.  */
                   2752: void
                   2753: embrace_waiting_friends (type)
                   2754:      tree type;
                   2755: {
                   2756:   tree decl = TYPE_NAME (type);
                   2757:   tree waiters;
                   2758: 
                   2759:   if (TREE_CODE (decl) != TYPE_DECL)
                   2760:     return;
                   2761: 
                   2762:   for (waiters = DECL_WAITING_FRIENDS (decl); waiters;
                   2763:        waiters = TREE_CHAIN (waiters))
                   2764:     {
                   2765:       tree waiter = TREE_PURPOSE (waiters);
                   2766: #if 0
                   2767:       tree waiter_prev = TREE_VALUE (waiters);
                   2768: #endif
                   2769:       tree decl = TREE_TYPE (waiters);
                   2770:       tree name = decl ? (TREE_CODE (decl) == IDENTIFIER_NODE
                   2771:                          ? decl : DECL_NAME (decl)) : NULL_TREE;
                   2772:       if (name)
                   2773:        {
                   2774:          /* @@ There may be work to be done since we have not verified
                   2775:             @@ consistency between original and friend declarations
                   2776:             @@ of the functions waiting to become friends.  */
                   2777:          tree field = lookup_fnfields (TYPE_BINFO (type), name, 0);
                   2778:          if (field)
                   2779:            if (decl == name)
                   2780:              add_friends (waiter, name, type);
                   2781:            else
                   2782:              add_friend (waiter, decl);
                   2783:          else
                   2784:            error_with_file_and_line (DECL_SOURCE_FILE (TYPE_NAME (waiter)),
                   2785:                                      DECL_SOURCE_LINE (TYPE_NAME (waiter)),
                   2786:                                      "no method `%s' defined in class `%s' to be friend",
                   2787:                                      IDENTIFIER_POINTER (DECL_NAME (TREE_TYPE (waiters))),
                   2788:                                      TYPE_NAME_STRING (type));
                   2789:        }
                   2790:       else
                   2791:        make_friend_class (type, waiter);
                   2792: 
                   2793: #if 0
                   2794:       if (TREE_CHAIN (waiter_prev))
                   2795:        TREE_CHAIN (waiter_prev) = TREE_CHAIN (TREE_CHAIN (waiter_prev));
                   2796:       else
                   2797:        DECL_UNDEFINED_FRIENDS (TYPE_NAME (waiter)) = NULL_TREE;
                   2798: #endif
                   2799:     }
                   2800: }
                   2801: 
                   2802: /* Common subroutines of build_new and build_vec_delete.  */
                   2803: 
                   2804: /* Common interface for calling "builtin" functions that are not
                   2805:    really builtin.  */
                   2806: 
                   2807: tree
                   2808: build_builtin_call (type, node, arglist)
                   2809:      tree type;
                   2810:      tree node;
                   2811:      tree arglist;
                   2812: {
                   2813:   tree rval = build (CALL_EXPR, type, node, arglist, 0);
                   2814:   TREE_SIDE_EFFECTS (rval) = 1;
                   2815:   assemble_external (TREE_OPERAND (node, 0));
                   2816:   TREE_USED (TREE_OPERAND (node, 0)) = 1;
                   2817:   return rval;
                   2818: }
                   2819: 
                   2820: /* Generate a C++ "new" expression. DECL is either a TREE_LIST
                   2821:    (which needs to go through some sort of groktypename) or it
                   2822:    is the name of the class we are newing. INIT is an initialization value.
                   2823:    It is either an EXPRLIST, an EXPR_NO_COMMAS, or something in braces.
                   2824:    If INIT is void_type_node, it means do *not* call a constructor
                   2825:    for this instance.
                   2826: 
                   2827:    For types with constructors, the data returned is initialized
                   2828:    by the appropriate constructor.
                   2829: 
                   2830:    Whether the type has a constructor or not, if it has a pointer
                   2831:    to a virtual function table, then that pointer is set up
                   2832:    here.
                   2833: 
                   2834:    Unless I am mistaken, a call to new () will return initialized
                   2835:    data regardless of whether the constructor itself is private or
                   2836:    not.  NOPE; new fails if the constructor is private (jcm).
                   2837: 
                   2838:    Note that build_new does nothing to assure that any special
                   2839:    alignment requirements of the type are met.  Rather, it leaves
                   2840:    it up to malloc to do the right thing.  Otherwise, folding to
                   2841:    the right alignment cal cause problems if the user tries to later
                   2842:    free the memory returned by `new'.
                   2843: 
                   2844:    PLACEMENT is the `placement' list for user-defined operator new ().  */
                   2845: 
1.1.1.2 ! root     2846: extern int flag_check_new;
        !          2847: 
1.1       root     2848: tree
                   2849: build_new (placement, decl, init, use_global_new)
                   2850:      tree placement;
                   2851:      tree decl, init;
                   2852:      int use_global_new;
                   2853: {
                   2854:   tree type, true_type, size, rval;
                   2855:   tree nelts;
1.1.1.2 ! root     2856:   tree alloc_expr, alloc_temp;
1.1       root     2857:   int has_array = 0;
                   2858:   enum tree_code code = NEW_EXPR;
                   2859: 
                   2860:   tree pending_sizes = NULL_TREE;
                   2861: 
                   2862:   if (decl == error_mark_node)
                   2863:     return error_mark_node;
                   2864: 
                   2865:   if (TREE_CODE (decl) == TREE_LIST)
                   2866:     {
                   2867:       tree absdcl = TREE_VALUE (decl);
                   2868:       tree last_absdcl = NULL_TREE;
                   2869:       int old_immediate_size_expand;
                   2870: 
                   2871:       if (current_function_decl
                   2872:          && DECL_CONSTRUCTOR_P (current_function_decl))
                   2873:        {
                   2874:          old_immediate_size_expand = immediate_size_expand;
                   2875:          immediate_size_expand = 0;
                   2876:        }
                   2877: 
                   2878:       nelts = integer_one_node;
                   2879: 
                   2880:       if (absdcl && TREE_CODE (absdcl) == CALL_EXPR)
                   2881:        my_friendly_abort (215);
                   2882:       while (absdcl && TREE_CODE (absdcl) == INDIRECT_REF)
                   2883:        {
                   2884:          last_absdcl = absdcl;
                   2885:          absdcl = TREE_OPERAND (absdcl, 0);
                   2886:        }
                   2887: 
                   2888:       if (absdcl && TREE_CODE (absdcl) == ARRAY_REF)
                   2889:        {
                   2890:          /* probably meant to be a vec new */
                   2891:          tree this_nelts;
                   2892: 
                   2893:          while (TREE_OPERAND (absdcl, 0)
                   2894:                 && TREE_CODE (TREE_OPERAND (absdcl, 0)) == ARRAY_REF)
                   2895:            {
                   2896:              last_absdcl = absdcl;
                   2897:              absdcl = TREE_OPERAND (absdcl, 0);
                   2898:            }
                   2899: 
                   2900:          has_array = 1;
                   2901:          this_nelts = TREE_OPERAND (absdcl, 1);
                   2902:          if (this_nelts != error_mark_node)
                   2903:            {
                   2904:              if (this_nelts == NULL_TREE)
                   2905:                error ("new of array type fails to specify size");
                   2906:              else
                   2907:                {
                   2908:                  this_nelts = save_expr (convert (sizetype, this_nelts));
                   2909:                  absdcl = TREE_OPERAND (absdcl, 0);
                   2910:                  if (this_nelts == integer_zero_node)
                   2911:                    {
                   2912:                      warning ("zero size array reserves no space");
                   2913:                      nelts = integer_zero_node;
                   2914:                    }
                   2915:                  else
                   2916:                    nelts = build_binary_op (MULT_EXPR, nelts, this_nelts, 1);
                   2917:                }
                   2918:            }
                   2919:          else
                   2920:            nelts = integer_zero_node;
                   2921:        }
                   2922: 
                   2923:       if (last_absdcl)
                   2924:        TREE_OPERAND (last_absdcl, 0) = absdcl;
                   2925:       else
                   2926:        TREE_VALUE (decl) = absdcl;
                   2927: 
                   2928:       type = true_type = groktypename (decl);
                   2929:       if (! type || type == error_mark_node)
                   2930:        {
                   2931:          immediate_size_expand = old_immediate_size_expand;
                   2932:          return error_mark_node;
                   2933:        }
                   2934: 
                   2935:       if (current_function_decl
                   2936:          && DECL_CONSTRUCTOR_P (current_function_decl))
                   2937:        {
                   2938:          pending_sizes = get_pending_sizes ();
                   2939:          immediate_size_expand = old_immediate_size_expand;
                   2940:        }
                   2941:     }
                   2942:   else if (TREE_CODE (decl) == IDENTIFIER_NODE)
                   2943:     {
                   2944:       if (IDENTIFIER_HAS_TYPE_VALUE (decl))
                   2945:        {
                   2946:          /* An aggregate type.  */
                   2947:          type = IDENTIFIER_TYPE_VALUE (decl);
                   2948:          decl = TYPE_NAME (type);
                   2949:        }
                   2950:       else
                   2951:        {
                   2952:          /* A builtin type.  */
                   2953:          decl = lookup_name (decl, 1);
                   2954:          my_friendly_assert (TREE_CODE (decl) == TYPE_DECL, 215);
                   2955:          type = TREE_TYPE (decl);
                   2956:        }
                   2957:       true_type = type;
                   2958:     }
                   2959:   else if (TREE_CODE (decl) == TYPE_DECL)
                   2960:     {
                   2961:       type = TREE_TYPE (decl);
                   2962:       true_type = type;
                   2963:     }
                   2964:   else
                   2965:     {
                   2966:       type = decl;
                   2967:       true_type = type;
                   2968:       decl = TYPE_NAME (type);
                   2969:     }
                   2970: 
                   2971:   /* ``A reference cannot be created by the new operator.  A reference
                   2972:      is not an object (8.2.2, 8.4.3), so a pointer to it could not be
                   2973:      returned by new.'' ARM 5.3.3 */
                   2974:   if (TREE_CODE (type) == REFERENCE_TYPE)
                   2975:     {
                   2976:       error ("new cannot be applied to a reference type");
                   2977:       type = true_type = TREE_TYPE (type);
                   2978:     }
                   2979: 
1.1.1.2 ! root     2980:   if (TREE_CODE (type) == FUNCTION_TYPE)
        !          2981:     {
        !          2982:       error ("new cannot be applied to a function type");
        !          2983:       return error_mark_node;
        !          2984:     }
        !          2985: 
1.1       root     2986:   /* When the object being created is an array, the new-expression yields a
                   2987:      pointer to the initial element (if any) of the array.  For example,
                   2988:      both new int and new int[10] return an int*.  5.3.4.  */
                   2989:   if (TREE_CODE (type) == ARRAY_TYPE && has_array == 0)
                   2990:     {
                   2991:       nelts = array_type_nelts_top (type);
                   2992:       has_array = 1;
                   2993:       type = true_type = TREE_TYPE (type);
                   2994:     }
                   2995: 
                   2996:   if (TYPE_READONLY (type) || TYPE_VOLATILE (type))
1.1.1.2 ! root     2997:     type = TYPE_MAIN_VARIANT (type);
        !          2998: 
1.1       root     2999:   /* If our base type is an array, then make sure we know how many elements
                   3000:      it has.  */
                   3001:   while (TREE_CODE (true_type) == ARRAY_TYPE)
                   3002:     {
                   3003:       tree this_nelts = array_type_nelts_top (true_type);
                   3004:       nelts = build_binary_op (MULT_EXPR, nelts, this_nelts, 1);
                   3005:       true_type = TREE_TYPE (true_type);
                   3006:     }
                   3007:   if (has_array)
                   3008:     size = fold (build_binary_op (MULT_EXPR, size_in_bytes (true_type),
                   3009:                                  nelts, 1));
                   3010:   else
                   3011:     size = size_in_bytes (type);
                   3012: 
1.1.1.2 ! root     3013:   if (true_type == void_type_node)
        !          3014:     {
        !          3015:       error ("invalid type `void' for new");
        !          3016:       return error_mark_node;
        !          3017:     }
        !          3018: 
1.1       root     3019:   if (TYPE_SIZE (true_type) == 0)
                   3020:     {
1.1.1.2 ! root     3021:       incomplete_type_error (0, true_type);
1.1       root     3022:       return error_mark_node;
                   3023:     }
                   3024: 
                   3025:   if (TYPE_LANG_SPECIFIC (true_type)
                   3026:       && CLASSTYPE_ABSTRACT_VIRTUALS (true_type))
                   3027:     {
                   3028:       abstract_virtuals_error (NULL_TREE, true_type);
                   3029:       return error_mark_node;
                   3030:     }
                   3031: 
                   3032:   if (TYPE_LANG_SPECIFIC (true_type) && IS_SIGNATURE (true_type))
                   3033:     {
                   3034:       signature_error (NULL_TREE, true_type);
                   3035:       return error_mark_node;
                   3036:     }
                   3037: 
                   3038:   /* Get a little extra space to store a couple of things before the new'ed
                   3039:      array. */
                   3040:   if (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type))
                   3041:     {
                   3042:       tree extra = BI_header_size;
                   3043: 
                   3044:       size = size_binop (PLUS_EXPR, size, extra);
                   3045:     }
                   3046: 
                   3047:   if (has_array)
                   3048:     code = VEC_NEW_EXPR;
                   3049: 
                   3050:   /* Allocate the object. */
                   3051:   if (! use_global_new && TYPE_LANG_SPECIFIC (true_type)
                   3052:       && (TYPE_GETS_NEW (true_type) & (1 << has_array)))
                   3053:     rval = build_opfncall (code, LOOKUP_NORMAL,
1.1.1.2 ! root     3054:                           build_pointer_type (true_type), size, placement);
1.1       root     3055:   else if (placement)
                   3056:     {
                   3057:       rval = build_opfncall (code, LOOKUP_GLOBAL|LOOKUP_COMPLAIN,
                   3058:                             ptr_type_node, size, placement);
1.1.1.2 ! root     3059:       rval = convert (build_pointer_type (true_type), rval);
1.1       root     3060:     }
                   3061:   else if (! has_array && flag_this_is_variable > 0
1.1.1.2 ! root     3062:           && TYPE_NEEDS_CONSTRUCTING (true_type) && init != void_type_node)
1.1       root     3063:     {
                   3064:       if (init == NULL_TREE || TREE_CODE (init) == TREE_LIST)
                   3065:        rval = NULL_TREE;
                   3066:       else
                   3067:        {
                   3068:          error ("constructors take parameter lists");
                   3069:          return error_mark_node;
                   3070:        }
                   3071:     }
                   3072:   else
                   3073:     {
                   3074:       rval = build_builtin_call (build_pointer_type (true_type),
                   3075:                                 has_array ? BIVN : BIN,
                   3076:                                 build_tree_list (NULL_TREE, size));
                   3077: #if 0
                   3078:       /* See comment above as to why this is disabled.  */
                   3079:       if (alignment)
                   3080:        {
1.1.1.2 ! root     3081:          rval = build (PLUS_EXPR, build_pointer_type (true_type), rval,
1.1       root     3082:                        alignment);
1.1.1.2 ! root     3083:          rval = build (BIT_AND_EXPR, build_pointer_type (true_type),
1.1       root     3084:                        rval, build1 (BIT_NOT_EXPR, integer_type_node,
                   3085:                                      alignment));
                   3086:        }
                   3087: #endif
                   3088:       TREE_CALLS_NEW (rval) = 1;
                   3089:     }
                   3090: 
1.1.1.2 ! root     3091:   if (flag_check_new && rval)
        !          3092:     {
        !          3093:       /* For array new, we need to make sure that the call to new is
        !          3094:         not expanded as part of the RTL_EXPR for the initialization,
        !          3095:         so we can't just use save_expr here.  */
        !          3096: 
        !          3097:       alloc_temp = get_temp_name (TREE_TYPE (rval), 0);
        !          3098:       alloc_expr = build (MODIFY_EXPR, TREE_TYPE (rval), alloc_temp, rval);
        !          3099:       TREE_SIDE_EFFECTS (alloc_expr) = 1;
        !          3100:       rval = alloc_temp;
        !          3101:     }
        !          3102:   else
        !          3103:     alloc_expr = NULL_TREE;
        !          3104: 
1.1       root     3105:   /* if rval is NULL_TREE I don't have to allocate it, but are we totally
                   3106:      sure we have some extra bytes in that case for the BI_header_size
                   3107:      cookies? And how does that interact with the code below? (mrs) */
                   3108:   /* Finish up some magic for new'ed arrays */
                   3109:   if (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type) && rval != NULL_TREE)
                   3110:     {
                   3111:       tree extra = BI_header_size;
                   3112:       tree cookie, exp1;
                   3113:       rval = convert (ptr_type_node, rval);    /* convert to void * first */
                   3114:       rval = convert (string_type_node, rval); /* lets not add void* and ints */
                   3115:       rval = save_expr (build_binary_op (PLUS_EXPR, rval, extra, 1));
                   3116:       /* Store header info.  */
1.1.1.2 ! root     3117:       cookie = build_indirect_ref (build (MINUS_EXPR, build_pointer_type (BI_header_type),
1.1       root     3118:                                          rval, extra), NULL_PTR);
                   3119:       exp1 = build (MODIFY_EXPR, void_type_node,
                   3120:                    build_component_ref (cookie, nc_nelts_field_id, 0, 0),
                   3121:                    nelts);
                   3122:       TREE_SIDE_EFFECTS (exp1) = 1;
                   3123:       rval = convert (build_pointer_type (true_type), rval);
                   3124:       TREE_CALLS_NEW (rval) = 1;
                   3125:       TREE_SIDE_EFFECTS (rval) = 1;
                   3126:       rval = build_compound_expr (tree_cons (NULL_TREE, exp1,
                   3127:                                             build_tree_list (NULL_TREE, rval)));
                   3128:     }
                   3129: 
                   3130:   if (rval == error_mark_node)
                   3131:     return error_mark_node;
                   3132: 
                   3133:   /* Don't call any constructors or do any initialization.  */
                   3134:   if (init == void_type_node)
                   3135:     goto done;
                   3136: 
                   3137:   if (TYPE_NEEDS_CONSTRUCTING (type) || init)
                   3138:     {
1.1.1.2 ! root     3139:       if (! TYPE_NEEDS_CONSTRUCTING (type)
        !          3140:          && ! IS_AGGR_TYPE (type) && ! has_array)
1.1       root     3141:        {
                   3142:          /* New 2.0 interpretation: `new int (10)' means
                   3143:             allocate an int, and initialize it with 10.  */
1.1.1.2 ! root     3144:          tree deref;
1.1       root     3145: 
1.1.1.2 ! root     3146:          rval = save_expr (rval);
        !          3147:          deref = build_indirect_ref (rval, NULL_PTR);
        !          3148:          TREE_READONLY (deref) = 0;
        !          3149: 
        !          3150:          if (TREE_CHAIN (init) != NULL_TREE)
        !          3151:            pedwarn ("initializer list being treated as compound expression");
        !          3152:          else if (TREE_CODE (init) == CONSTRUCTOR)
        !          3153:            {
        !          3154:              pedwarn ("initializer list appears where operand should be used");
        !          3155:              init = TREE_OPERAND (init, 1);
        !          3156:            }
        !          3157:          init = build_compound_expr (init);
        !          3158: 
        !          3159:          init = convert_for_initialization (deref, type, init, LOOKUP_NORMAL,
        !          3160:                                             "new", NULL_TREE, 0);
1.1       root     3161:          rval = build (COMPOUND_EXPR, TREE_TYPE (rval),
1.1.1.2 ! root     3162:                        build_modify_expr (deref, NOP_EXPR, init),
1.1       root     3163:                        rval);
1.1.1.2 ! root     3164:          TREE_NO_UNUSED_WARNING (rval) = 1;
1.1       root     3165:          TREE_SIDE_EFFECTS (rval) = 1;
                   3166:          TREE_CALLS_NEW (rval) = 1;
                   3167:        }
1.1.1.2 ! root     3168:       else if (! has_array)
        !          3169:        {
        !          3170:          tree newrval;
        !          3171:          /* Constructors are never virtual. If it has an initialization, we
        !          3172:             need to complain if we aren't allowed to use the ctor that took
        !          3173:             that argument.  */
        !          3174:          int flags = LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_COMPLAIN;
        !          3175: 
        !          3176:          if (rval && TYPE_USES_VIRTUAL_BASECLASSES (true_type))
        !          3177:            {
        !          3178:              init = tree_cons (NULL_TREE, integer_one_node, init);
        !          3179:              flags |= LOOKUP_HAS_IN_CHARGE;
        !          3180:            }
        !          3181: 
        !          3182:          newrval = rval;
        !          3183: 
        !          3184:          if (newrval && TREE_CODE (TREE_TYPE (newrval)) == POINTER_TYPE)
        !          3185:            newrval = build_indirect_ref (newrval, NULL_PTR);
        !          3186: 
        !          3187:          newrval = build_method_call (newrval, constructor_name_full (true_type),
        !          3188:                                       init, NULL_TREE, flags);
        !          3189: 
        !          3190:          if (newrval)
        !          3191:            {
        !          3192:              rval = newrval;
        !          3193:              TREE_HAS_CONSTRUCTOR (rval) = 1;
        !          3194:            }
        !          3195:          else
        !          3196:            rval = error_mark_node;
        !          3197:        }
1.1       root     3198:       else if (current_function_decl == NULL_TREE)
                   3199:        {
                   3200:          extern tree static_aggregates;
                   3201: 
                   3202:          /* In case of static initialization, SAVE_EXPR is good enough.  */
1.1.1.2 ! root     3203:          rval = save_expr (rval);
1.1       root     3204:          rval = copy_to_permanent (rval);
1.1.1.2 ! root     3205:          init = copy_to_permanent (init);
        !          3206:          init = expand_vec_init (decl, rval,
        !          3207:                                  build_binary_op (MINUS_EXPR, nelts,
        !          3208:                                                   integer_one_node, 1),
        !          3209:                                  init, 0);
        !          3210:          init = copy_to_permanent (init);
1.1       root     3211:          static_aggregates = perm_tree_cons (init, rval, static_aggregates);
                   3212:        }
                   3213:       else
                   3214:        {
                   3215:          /* Have to wrap this in RTL_EXPR for two cases:
                   3216:             in base or member initialization and if we
                   3217:             are a branch of a ?: operator.  Since we
                   3218:             can't easily know the latter, just do it always.  */
                   3219:          tree xval = make_node (RTL_EXPR);
                   3220: 
1.1.1.2 ! root     3221:          /* If we want to check the value of the allocation expression,
        !          3222:              and the number of elements in the array is not a constant, we
        !          3223:              *must* expand the SAVE_EXPR for nelts in alloc_expr before we
        !          3224:              expand it in the actual initialization.  So we need to build up
        !          3225:              an RTL_EXPR for alloc_expr.  Sigh.  */
        !          3226:          if (alloc_expr && ! TREE_CONSTANT (nelts))
        !          3227:            {
        !          3228:              tree xval = make_node (RTL_EXPR);
        !          3229:              rtx rtxval;
        !          3230:              TREE_TYPE (xval) = TREE_TYPE (alloc_expr);
        !          3231:              do_pending_stack_adjust ();
        !          3232:              start_sequence_for_rtl_expr (xval);
        !          3233:              emit_note (0, -1);
        !          3234:              rtxval = expand_expr (alloc_expr, NULL, VOIDmode, 0);
        !          3235:              do_pending_stack_adjust ();
        !          3236:              TREE_SIDE_EFFECTS (xval) = 1;
        !          3237:              RTL_EXPR_SEQUENCE (xval) = get_insns ();
        !          3238:              end_sequence ();
        !          3239:              RTL_EXPR_RTL (xval) = rtxval;
        !          3240:              TREE_TYPE (xval) = TREE_TYPE (alloc_expr);
        !          3241:              alloc_expr = xval;
        !          3242:            }
        !          3243: 
1.1       root     3244:          TREE_TYPE (xval) = TREE_TYPE (rval);
                   3245:          do_pending_stack_adjust ();
                   3246:          start_sequence_for_rtl_expr (xval);
                   3247: 
                   3248:          /* As a matter of principle, `start_sequence' should do this.  */
                   3249:          emit_note (0, -1);
                   3250: 
1.1.1.2 ! root     3251:          rval = save_expr (rval);
        !          3252:          rval = expand_vec_init (decl, rval,
        !          3253:                                  build_binary_op (MINUS_EXPR, nelts,
        !          3254:                                                   integer_one_node, 1),
        !          3255:                                  init, 0);
1.1       root     3256: 
                   3257:          do_pending_stack_adjust ();
                   3258: 
                   3259:          TREE_SIDE_EFFECTS (xval) = 1;
                   3260:          TREE_CALLS_NEW (xval) = 1;
                   3261:          RTL_EXPR_SEQUENCE (xval) = get_insns ();
                   3262:          end_sequence ();
                   3263: 
                   3264:          if (TREE_CODE (rval) == SAVE_EXPR)
                   3265:            {
                   3266:              /* Errors may cause this to not get evaluated.  */
                   3267:              if (SAVE_EXPR_RTL (rval) == 0)
                   3268:                SAVE_EXPR_RTL (rval) = const0_rtx;
                   3269:              RTL_EXPR_RTL (xval) = SAVE_EXPR_RTL (rval);
                   3270:            }
                   3271:          else
                   3272:            {
                   3273:              my_friendly_assert (TREE_CODE (rval) == VAR_DECL, 217);
                   3274:              RTL_EXPR_RTL (xval) = DECL_RTL (rval);
                   3275:            }
                   3276:          rval = xval;
                   3277:        }
                   3278:     }
1.1.1.2 ! root     3279:   else if (TYPE_READONLY (true_type))
        !          3280:     cp_error ("uninitialized const in `new' of `%#T'", true_type);
        !          3281: 
1.1       root     3282:  done:
1.1.1.2 ! root     3283: 
        !          3284:   if (alloc_expr)
        !          3285:     {
        !          3286:       /* Did we modify the storage?  */
        !          3287:       if (rval != alloc_temp)
        !          3288:        {
        !          3289:          tree ifexp = build_binary_op (NE_EXPR, alloc_expr,
        !          3290:                                        integer_zero_node, 1);
        !          3291:          rval = build_conditional_expr (ifexp, rval, alloc_temp);
        !          3292:        }
        !          3293:       else
        !          3294:        rval = alloc_expr;
        !          3295:     }
        !          3296: 
1.1       root     3297:   if (rval && TREE_TYPE (rval) != build_pointer_type (type))
                   3298:     {
                   3299:       /* The type of new int [3][3] is not int *, but int [3] * */
1.1.1.2 ! root     3300:       rval = build_c_cast (build_pointer_type (type), rval, 0);
1.1       root     3301:     }
                   3302: 
                   3303:   if (pending_sizes)
                   3304:     rval = build_compound_expr (chainon (pending_sizes,
                   3305:                                         build_tree_list (NULL_TREE, rval)));
                   3306: 
                   3307:   if (flag_gc)
                   3308:     {
                   3309:       extern tree gc_visible;
                   3310:       tree objbits;
                   3311:       tree update_expr;
                   3312: 
                   3313:       rval = save_expr (rval);
                   3314:       /* We don't need a `headof' operation to do this because
                   3315:         we know where the object starts.  */
                   3316:       objbits = build1 (INDIRECT_REF, unsigned_type_node,
                   3317:                        build (MINUS_EXPR, ptr_type_node,
                   3318:                               rval, c_sizeof_nowarn (unsigned_type_node)));
                   3319:       update_expr = build_modify_expr (objbits, BIT_IOR_EXPR, gc_visible);
                   3320:       rval = build_compound_expr (tree_cons (NULL_TREE, rval,
                   3321:                                             tree_cons (NULL_TREE, update_expr,
                   3322:                                                        build_tree_list (NULL_TREE, rval))));
                   3323:     }
                   3324: 
                   3325:   return rval;
                   3326: }
                   3327: 
1.1.1.2 ! root     3328: static tree
        !          3329: build_vec_delete_1 (base, maxindex, type, auto_delete_vec, auto_delete,
        !          3330:                    use_global_delete)
        !          3331:      tree base, maxindex, type;
        !          3332:      tree auto_delete_vec, auto_delete;
        !          3333:      int use_global_delete;
        !          3334: {
        !          3335:   tree virtual_size;
        !          3336:   tree ptype = build_pointer_type (type);
        !          3337:   tree size_exp = size_in_bytes (type);
        !          3338: 
        !          3339:   /* Temporary variables used by the loop.  */
        !          3340:   tree tbase, tbase_init;
        !          3341: 
        !          3342:   /* This is the body of the loop that implements the deletion of a
        !          3343:      single element, and moves temp variables to next elements.  */
        !          3344:   tree body;
        !          3345: 
        !          3346:   /* This is the LOOP_EXPR that governs the deletion of the elements.  */
        !          3347:   tree loop;
        !          3348: 
        !          3349:   /* This is the thing that governs what to do after the loop has run.  */
        !          3350:   tree deallocate_expr = 0;
        !          3351: 
        !          3352:   /* This is the BIND_EXPR which holds the outermost iterator of the
        !          3353:      loop.  It is convenient to set this variable up and test it before
        !          3354:      executing any other code in the loop.
        !          3355:      This is also the containing expression returned by this function.  */
        !          3356:   tree controller = NULL_TREE;
        !          3357: 
        !          3358:   /* This is the BLOCK to record the symbol binding for debugging.  */
        !          3359:   tree block;
        !          3360: 
        !          3361:   if (! IS_AGGR_TYPE (type) || ! TYPE_NEEDS_DESTRUCTOR (type))
        !          3362:     {
        !          3363:       loop = integer_zero_node;
        !          3364:       goto no_destructor;
        !          3365:     }
        !          3366: 
        !          3367:   /* The below is short by BI_header_size */
        !          3368:   virtual_size = fold (size_binop (MULT_EXPR, size_exp, maxindex));
        !          3369: 
        !          3370:   tbase = build_decl (VAR_DECL, NULL_TREE, ptype);
        !          3371:   tbase_init = build_modify_expr (tbase, NOP_EXPR,
        !          3372:                                  fold (build (PLUS_EXPR, ptype,
        !          3373:                                               base,
        !          3374:                                               virtual_size)));
        !          3375:   DECL_REGISTER (tbase) = 1;
        !          3376:   controller = build (BIND_EXPR, void_type_node, tbase, 0, 0);
        !          3377:   TREE_SIDE_EFFECTS (controller) = 1;
        !          3378:   block = build_block (tbase, 0, 0, 0, 0);
        !          3379:   add_block_current_level (block);
        !          3380: 
        !          3381:   if (auto_delete != integer_zero_node
        !          3382:       && auto_delete != integer_two_node)
        !          3383:     {
        !          3384:       tree base_tbd = convert (ptype,
        !          3385:                               build_binary_op (MINUS_EXPR,
        !          3386:                                                convert (ptr_type_node, base),
        !          3387:                                                BI_header_size,
        !          3388:                                                1));
        !          3389:       /* This is the real size */
        !          3390:       virtual_size = size_binop (PLUS_EXPR, virtual_size, BI_header_size);
        !          3391:       body = build_tree_list (NULL_TREE,
        !          3392:                              build_x_delete (ptype, base_tbd,
        !          3393:                                              2 | use_global_delete,
        !          3394:                                              virtual_size));
        !          3395:       body = build (COND_EXPR, void_type_node,
        !          3396:                    build (BIT_AND_EXPR, integer_type_node,
        !          3397:                           auto_delete, integer_one_node),
        !          3398:                    body, integer_zero_node);
        !          3399:     }
        !          3400:   else
        !          3401:     body = NULL_TREE;
        !          3402: 
        !          3403:   body = tree_cons (NULL_TREE,
        !          3404:                    build_delete (ptype, tbase, auto_delete,
        !          3405:                                  LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 1),
        !          3406:                    body);
        !          3407: 
        !          3408:   body = tree_cons (NULL_TREE,
        !          3409:                    build_modify_expr (tbase, NOP_EXPR, build (MINUS_EXPR, ptype, tbase, size_exp)),
        !          3410:                    body);
        !          3411: 
        !          3412:   body = tree_cons (NULL_TREE,
        !          3413:                    build (EXIT_EXPR, void_type_node,
        !          3414:                           build (EQ_EXPR, boolean_type_node, base, tbase)),
        !          3415:                    body);
        !          3416: 
        !          3417:   loop = build (LOOP_EXPR, void_type_node, build_compound_expr (body));
        !          3418: 
        !          3419:   loop = tree_cons (NULL_TREE, tbase_init,
        !          3420:                    tree_cons (NULL_TREE, loop, NULL_TREE));
        !          3421:   loop = build_compound_expr (loop);
        !          3422: 
        !          3423:  no_destructor:
        !          3424:   /* If the delete flag is one, or anything else with the low bit set,
        !          3425:      delete the storage.  */
        !          3426:   if (auto_delete_vec == integer_zero_node
        !          3427:       || auto_delete_vec == integer_two_node)
        !          3428:     deallocate_expr = integer_zero_node;
        !          3429:   else
        !          3430:     {
        !          3431:       tree base_tbd;
        !          3432: 
        !          3433:       /* The below is short by BI_header_size */
        !          3434:       virtual_size = fold (size_binop (MULT_EXPR, size_exp, maxindex));
        !          3435: 
        !          3436:       if (! TYPE_VEC_NEW_USES_COOKIE (type))
        !          3437:        /* no header */
        !          3438:        base_tbd = base;
        !          3439:       else
        !          3440:        {
        !          3441:          base_tbd = convert (ptype,
        !          3442:                              build_binary_op (MINUS_EXPR,
        !          3443:                                               convert (string_type_node, base),
        !          3444:                                               BI_header_size,
        !          3445:                                               1));
        !          3446:          /* True size with header. */
        !          3447:          virtual_size = size_binop (PLUS_EXPR, virtual_size, BI_header_size);
        !          3448:        }
        !          3449:       deallocate_expr = build_x_delete (ptype, base_tbd,
        !          3450:                                        2 | use_global_delete,
        !          3451:                                        virtual_size);
        !          3452:       if (auto_delete_vec != integer_one_node)
        !          3453:        deallocate_expr = build (COND_EXPR, void_type_node,
        !          3454:                                 build (BIT_AND_EXPR, integer_type_node,
        !          3455:                                        auto_delete_vec, integer_one_node),
        !          3456:                                 deallocate_expr, integer_zero_node);
        !          3457:     }
        !          3458: 
        !          3459:   if (loop && deallocate_expr != integer_zero_node)
        !          3460:     {
        !          3461:       body = tree_cons (NULL_TREE, loop,
        !          3462:                        tree_cons (NULL_TREE, deallocate_expr, NULL_TREE));
        !          3463:       body = build_compound_expr (body);
        !          3464:     }
        !          3465:   else
        !          3466:     body = loop;
        !          3467: 
        !          3468:   /* Outermost wrapper: If pointer is null, punt.  */
        !          3469:   body = build (COND_EXPR, void_type_node,
        !          3470:                build (NE_EXPR, boolean_type_node, base, integer_zero_node),
        !          3471:                body, integer_zero_node);
        !          3472:   body = build1 (NOP_EXPR, void_type_node, body);
        !          3473: 
        !          3474:   if (controller)
        !          3475:     {
        !          3476:       TREE_OPERAND (controller, 1) = body;
        !          3477:       return controller;
        !          3478:     }
        !          3479:   else
        !          3480:     return convert (void_type_node, body);
        !          3481: }
        !          3482: 
        !          3483: /* Build a tree to cleanup partially built arrays.
        !          3484:    BASE is that starting address of the array.
        !          3485:    COUNT is the count of objects that have been built, that need destroying.
        !          3486:    TYPE is the type of elements in the array.  */
        !          3487: static tree
        !          3488: build_array_eh_cleanup (base, count, type)
        !          3489:      tree base, count, type;
        !          3490: {
        !          3491:   tree expr = build_vec_delete_1 (base, count, type, integer_two_node,
        !          3492:                                  integer_zero_node, 0);
        !          3493:   return expr;
        !          3494: }
        !          3495: 
1.1       root     3496: /* `expand_vec_init' performs initialization of a vector of aggregate
                   3497:    types.
                   3498: 
                   3499:    DECL is passed only for error reporting, and provides line number
                   3500:    and source file name information.
                   3501:    BASE is the space where the vector will be.
                   3502:    MAXINDEX is the maximum index of the array (one less than the
                   3503:            number of elements).
                   3504:    INIT is the (possibly NULL) initializer.
                   3505: 
                   3506:    FROM_ARRAY is 0 if we should init everything with INIT
                   3507:    (i.e., every element initialized from INIT).
                   3508:    FROM_ARRAY is 1 if we should index into INIT in parallel
                   3509:    with initialization of DECL.
                   3510:    FROM_ARRAY is 2 if we should index into INIT in parallel,
                   3511:    but use assignment instead of initialization.  */
                   3512: 
                   3513: tree
                   3514: expand_vec_init (decl, base, maxindex, init, from_array)
                   3515:      tree decl, base, maxindex, init;
                   3516:      int from_array;
                   3517: {
                   3518:   tree rval;
                   3519:   tree iterator, base2 = NULL_TREE;
                   3520:   tree type = TREE_TYPE (TREE_TYPE (base));
                   3521:   tree size;
                   3522: 
                   3523:   maxindex = convert (integer_type_node, maxindex);
                   3524:   if (maxindex == error_mark_node)
                   3525:     return error_mark_node;
                   3526: 
                   3527:   if (current_function_decl == NULL_TREE)
                   3528:     {
                   3529:       rval = make_tree_vec (3);
                   3530:       TREE_VEC_ELT (rval, 0) = base;
                   3531:       TREE_VEC_ELT (rval, 1) = maxindex;
                   3532:       TREE_VEC_ELT (rval, 2) = init;
                   3533:       return rval;
                   3534:     }
                   3535: 
                   3536:   size = size_in_bytes (type);
                   3537: 
                   3538:   /* Set to zero in case size is <= 0.  Optimizer will delete this if
                   3539:      it is not needed.  */
1.1.1.2 ! root     3540:   rval = get_temp_regvar (build_pointer_type (type),
        !          3541:                          convert (build_pointer_type (type), null_pointer_node));
1.1       root     3542:   base = default_conversion (base);
1.1.1.2 ! root     3543:   base = convert (build_pointer_type (type), base);
1.1       root     3544:   expand_assignment (rval, base, 0, 0);
1.1.1.2 ! root     3545:   base = get_temp_regvar (build_pointer_type (type), base);
1.1       root     3546: 
                   3547:   if (init != NULL_TREE
                   3548:       && TREE_CODE (init) == CONSTRUCTOR
                   3549:       && TREE_TYPE (init) == TREE_TYPE (decl))
                   3550:     {
                   3551:       /* Initialization of array from {...}.  */
                   3552:       tree elts = CONSTRUCTOR_ELTS (init);
                   3553:       tree baseref = build1 (INDIRECT_REF, type, base);
1.1.1.2 ! root     3554:       tree baseinc = build (PLUS_EXPR, build_pointer_type (type), base, size);
1.1       root     3555:       int host_i = TREE_INT_CST_LOW (maxindex);
                   3556: 
                   3557:       if (IS_AGGR_TYPE (type))
                   3558:        {
                   3559:          while (elts)
                   3560:            {
                   3561:              host_i -= 1;
1.1.1.2 ! root     3562:              expand_aggr_init (baseref, TREE_VALUE (elts), 0, 0);
1.1       root     3563: 
                   3564:              expand_assignment (base, baseinc, 0, 0);
                   3565:              elts = TREE_CHAIN (elts);
                   3566:            }
                   3567:          /* Initialize any elements by default if possible.  */
                   3568:          if (host_i >= 0)
                   3569:            {
                   3570:              if (TYPE_NEEDS_CONSTRUCTING (type) == 0)
                   3571:                {
                   3572:                  if (obey_regdecls)
                   3573:                    use_variable (DECL_RTL (base));
                   3574:                  goto done_init;
                   3575:                }
                   3576: 
                   3577:              iterator = get_temp_regvar (integer_type_node,
                   3578:                                          build_int_2 (host_i, 0));
                   3579:              init = NULL_TREE;
                   3580:              goto init_by_default;
                   3581:            }
                   3582:        }
                   3583:       else
                   3584:        while (elts)
                   3585:          {
                   3586:            expand_assignment (baseref, TREE_VALUE (elts), 0, 0);
                   3587: 
                   3588:            expand_assignment (base, baseinc, 0, 0);
                   3589:            elts = TREE_CHAIN (elts);
                   3590:          }
                   3591: 
                   3592:       if (obey_regdecls)
                   3593:        use_variable (DECL_RTL (base));
                   3594:     }
                   3595:   else
                   3596:     {
                   3597:       tree itype;
                   3598: 
                   3599:       iterator = get_temp_regvar (integer_type_node, maxindex);
                   3600: 
                   3601:     init_by_default:
                   3602: 
                   3603:       /* If initializing one array from another,
                   3604:         initialize element by element.  */
                   3605:       if (from_array)
                   3606:        {
                   3607:          /* We rely upon the below calls the do argument checking */
                   3608:          if (decl == NULL_TREE)
                   3609:            {
                   3610:              sorry ("initialization of array from dissimilar array type");
                   3611:              return error_mark_node;
                   3612:            }
                   3613:          if (init)
                   3614:            {
                   3615:              base2 = default_conversion (init);
                   3616:              itype = TREE_TYPE (base2);
                   3617:              base2 = get_temp_regvar (itype, base2);
                   3618:              itype = TREE_TYPE (itype);
                   3619:            }
                   3620:          else if (TYPE_LANG_SPECIFIC (type)
                   3621:                   && TYPE_NEEDS_CONSTRUCTING (type)
                   3622:                   && ! TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
                   3623:            {
                   3624:              error ("initializer ends prematurely");
                   3625:              return error_mark_node;
                   3626:            }
                   3627:        }
                   3628: 
1.1.1.2 ! root     3629:       expand_start_cond (build (GE_EXPR, boolean_type_node,
1.1       root     3630:                                iterator, integer_zero_node), 0);
1.1.1.2 ! root     3631:       if (TYPE_NEEDS_DESTRUCTOR (type))
        !          3632:        start_protect ();
1.1       root     3633:       expand_start_loop_continue_elsewhere (1);
                   3634: 
                   3635:       if (from_array)
                   3636:        {
                   3637:          tree to = build1 (INDIRECT_REF, type, base);
                   3638:          tree from;
                   3639: 
                   3640:          if (base2)
                   3641:            from = build1 (INDIRECT_REF, itype, base2);
                   3642:          else
                   3643:            from = NULL_TREE;
                   3644: 
                   3645:          if (from_array == 2)
                   3646:            expand_expr_stmt (build_modify_expr (to, NOP_EXPR, from));
                   3647:          else if (TYPE_NEEDS_CONSTRUCTING (type))
1.1.1.2 ! root     3648:            expand_aggr_init (to, from, 0, 0);
1.1       root     3649:          else if (from)
                   3650:            expand_assignment (to, from, 0, 0);
                   3651:          else
                   3652:            my_friendly_abort (57);
                   3653:        }
                   3654:       else if (TREE_CODE (type) == ARRAY_TYPE)
                   3655:        {
                   3656:          if (init != 0)
                   3657:            sorry ("cannot initialize multi-dimensional array with initializer");
1.1.1.2 ! root     3658:          expand_vec_init (decl, build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (type)), base),
1.1       root     3659:                           array_type_nelts (type), 0, 0);
                   3660:        }
                   3661:       else
1.1.1.2 ! root     3662:        expand_aggr_init (build1 (INDIRECT_REF, type, base), init, 0, 0);
1.1       root     3663: 
                   3664:       expand_assignment (base,
1.1.1.2 ! root     3665:                         build (PLUS_EXPR, build_pointer_type (type), base, size),
1.1       root     3666:                         0, 0);
                   3667:       if (base2)
                   3668:        expand_assignment (base2,
1.1.1.2 ! root     3669:                           build (PLUS_EXPR, build_pointer_type (type), base2, size), 0, 0);
1.1       root     3670:       expand_loop_continue_here ();
1.1.1.2 ! root     3671:       expand_exit_loop_if_false (0, build (NE_EXPR, boolean_type_node,
1.1       root     3672:                                           build (PREDECREMENT_EXPR, integer_type_node, iterator, integer_one_node), minus_one));
                   3673: 
                   3674:       if (obey_regdecls)
                   3675:        {
                   3676:          use_variable (DECL_RTL (base));
                   3677:          if (base2)
                   3678:            use_variable (DECL_RTL (base2));
                   3679:        }
                   3680:       expand_end_loop ();
1.1.1.2 ! root     3681:       if (TYPE_NEEDS_DESTRUCTOR (type))
        !          3682:        end_protect (build_array_eh_cleanup (rval,
        !          3683:                                             build_binary_op (MINUS_EXPR,
        !          3684:                                                              maxindex,
        !          3685:                                                              iterator,
        !          3686:                                                              1),
        !          3687:                                             type));
1.1       root     3688:       expand_end_cond ();
                   3689:       if (obey_regdecls)
                   3690:        use_variable (DECL_RTL (iterator));
                   3691:     }
                   3692:  done_init:
                   3693: 
                   3694:   if (obey_regdecls)
                   3695:     use_variable (DECL_RTL (rval));
                   3696:   return rval;
                   3697: }
                   3698: 
                   3699: /* Free up storage of type TYPE, at address ADDR.
                   3700: 
                   3701:    TYPE is a POINTER_TYPE and can be ptr_type_node for no special type
                   3702:    of pointer.
                   3703: 
                   3704:    VIRTUAL_SIZE is the amount of storage that was allocated, and is
                   3705:    used as the second argument to operator delete.  It can include
                   3706:    things like padding and magic size cookies.  It has virtual in it,
                   3707:    because if you have a base pointer and you delete through a virtual
                   3708:    destructor, it should be the size of the dynamic object, not the
                   3709:    static object, see Free Store 12.5 ANSI C++ WP.
                   3710: 
                   3711:    This does not call any destructors.  */
                   3712: tree
                   3713: build_x_delete (type, addr, which_delete, virtual_size)
                   3714:      tree type, addr;
                   3715:      int which_delete;
                   3716:      tree virtual_size;
                   3717: {
                   3718:   int use_global_delete = which_delete & 1;
                   3719:   int use_vec_delete = !!(which_delete & 2);
                   3720:   tree rval;
                   3721:   enum tree_code code = use_vec_delete ? VEC_DELETE_EXPR : DELETE_EXPR;
                   3722: 
                   3723:   if (! use_global_delete && TYPE_LANG_SPECIFIC (TREE_TYPE (type))
                   3724:       && (TYPE_GETS_DELETE (TREE_TYPE (type)) & (1 << use_vec_delete)))
                   3725:     rval = build_opfncall (code, LOOKUP_NORMAL, addr, virtual_size, NULL_TREE);
                   3726:   else
                   3727:     rval = build_builtin_call (void_type_node, use_vec_delete ? BIVD : BID,
                   3728:                               build_tree_list (NULL_TREE, addr));
                   3729:   return rval;
                   3730: }
                   3731: 
                   3732: /* Generate a call to a destructor. TYPE is the type to cast ADDR to.
                   3733:    ADDR is an expression which yields the store to be destroyed.
                   3734:    AUTO_DELETE is nonzero if a call to DELETE should be made or not.
                   3735:    If in the program, (AUTO_DELETE & 2) is non-zero, we tear down the
                   3736:    virtual baseclasses.
                   3737:    If in the program, (AUTO_DELETE & 1) is non-zero, then we deallocate.
                   3738: 
                   3739:    FLAGS is the logical disjunction of zero or more LOOKUP_
                   3740:    flags.  See cp-tree.h for more info.
                   3741: 
                   3742:    This function does not delete an object's virtual base classes.  */
                   3743: tree
                   3744: build_delete (type, addr, auto_delete, flags, use_global_delete)
                   3745:      tree type, addr;
                   3746:      tree auto_delete;
                   3747:      int flags;
                   3748:      int use_global_delete;
                   3749: {
                   3750:   tree function, parms;
                   3751:   tree member;
                   3752:   tree expr;
                   3753:   tree ref;
                   3754:   int ptr;
                   3755: 
                   3756:   if (addr == error_mark_node)
                   3757:     return error_mark_node;
                   3758: 
                   3759:   /* Can happen when CURRENT_EXCEPTION_OBJECT gets its type
                   3760:      set to `error_mark_node' before it gets properly cleaned up.  */
                   3761:   if (type == error_mark_node)
                   3762:     return error_mark_node;
                   3763: 
                   3764:   type = TYPE_MAIN_VARIANT (type);
                   3765: 
                   3766:   if (TREE_CODE (type) == POINTER_TYPE)
                   3767:     {
                   3768:       type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
                   3769:       if (TYPE_SIZE (type) == 0)
                   3770:        {
                   3771:          incomplete_type_error (0, type);
                   3772:          return error_mark_node;
                   3773:        }
                   3774:       if (TREE_CODE (type) == ARRAY_TYPE)
                   3775:        goto handle_array;
                   3776:       if (! IS_AGGR_TYPE (type))
                   3777:        {
                   3778:          /* Call the builtin operator delete.  */
                   3779:          return build_builtin_call (void_type_node, BID,
                   3780:                                     build_tree_list (NULL_TREE, addr));
                   3781:        }
                   3782:       if (TREE_SIDE_EFFECTS (addr))
                   3783:        addr = save_expr (addr);
                   3784: 
                   3785:       /* throw away const and volatile on target type of addr */
1.1.1.2 ! root     3786:       addr = convert_force (build_pointer_type (type), addr, 0);
1.1       root     3787:       ref = build_indirect_ref (addr, NULL_PTR);
                   3788:       ptr = 1;
                   3789:     }
                   3790:   else if (TREE_CODE (type) == ARRAY_TYPE)
                   3791:     {
                   3792:     handle_array:
                   3793:       if (TREE_SIDE_EFFECTS (addr))
                   3794:        addr = save_expr (addr);
1.1.1.2 ! root     3795:       if (TYPE_DOMAIN (type) == NULL_TREE)
        !          3796:        {
        !          3797:          error ("unknown array size in delete");
        !          3798:          return error_mark_node;
        !          3799:        }
1.1       root     3800:       return build_vec_delete (addr, array_type_nelts (type),
                   3801:                               c_sizeof_nowarn (TREE_TYPE (type)),
                   3802:                               auto_delete, integer_two_node,
                   3803:                               use_global_delete);
                   3804:     }
                   3805:   else
                   3806:     {
                   3807:       /* Don't check PROTECT here; leave that decision to the
                   3808:         destructor.  If the destructor is accessible, call it,
                   3809:         else report error.  */
                   3810:       addr = build_unary_op (ADDR_EXPR, addr, 0);
                   3811:       if (TREE_SIDE_EFFECTS (addr))
                   3812:        addr = save_expr (addr);
                   3813: 
                   3814:       if (TREE_CONSTANT (addr))
                   3815:        addr = convert_pointer_to (type, addr);
                   3816:       else
1.1.1.2 ! root     3817:        addr = convert_force (build_pointer_type (type), addr, 0);
1.1       root     3818: 
                   3819:       if (TREE_CODE (addr) == NOP_EXPR
                   3820:          && TREE_OPERAND (addr, 0) == current_class_decl)
                   3821:        ref = C_C_D;
                   3822:       else
                   3823:        ref = build_indirect_ref (addr, NULL_PTR);
                   3824:       ptr = 0;
                   3825:     }
                   3826: 
                   3827:   my_friendly_assert (IS_AGGR_TYPE (type), 220);
                   3828: 
                   3829:   if (! TYPE_NEEDS_DESTRUCTOR (type))
                   3830:     {
                   3831:       if (auto_delete == integer_zero_node)
                   3832:        return void_zero_node;
                   3833: 
                   3834:       /* Pass the size of the object down to the operator delete() in
                   3835:         addition to the ADDR.  */
                   3836:       if (TYPE_GETS_REG_DELETE (type) && !use_global_delete)
                   3837:        {
                   3838:          tree virtual_size = c_sizeof_nowarn (type);
                   3839:          return build_opfncall (DELETE_EXPR, LOOKUP_NORMAL, addr,
                   3840:                                 virtual_size, NULL_TREE);
                   3841:        }
                   3842: 
                   3843:       /* Call the builtin operator delete.  */
                   3844:       return build_builtin_call (void_type_node, BID,
                   3845:                                 build_tree_list (NULL_TREE, addr));
                   3846:     }
                   3847:   parms = build_tree_list (NULL_TREE, addr);
                   3848: 
                   3849:   /* Below, we will reverse the order in which these calls are made.
                   3850:      If we have a destructor, then that destructor will take care
                   3851:      of the base classes; otherwise, we must do that here.  */
                   3852:   if (TYPE_HAS_DESTRUCTOR (type))
                   3853:     {
                   3854:       tree dtor = DECL_MAIN_VARIANT (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 0));
                   3855:       tree basetypes = TYPE_BINFO (type);
                   3856:       tree passed_auto_delete;
                   3857:       tree do_delete = NULL_TREE;
                   3858: 
                   3859:       if (use_global_delete)
                   3860:        {
                   3861:          tree cond = fold (build (BIT_AND_EXPR, integer_type_node,
                   3862:                                   auto_delete, integer_one_node));
                   3863:          tree call = build_builtin_call
                   3864:            (void_type_node, BID, build_tree_list (NULL_TREE, addr));
                   3865: 
                   3866:          cond = fold (build (COND_EXPR, void_type_node, cond,
                   3867:                              call, void_zero_node));
                   3868:          if (cond != void_zero_node)
                   3869:            do_delete = cond;
                   3870: 
                   3871:          passed_auto_delete = fold (build (BIT_AND_EXPR, integer_type_node,
                   3872:                                            auto_delete, integer_two_node));
                   3873:        }
                   3874:       else
                   3875:        passed_auto_delete = auto_delete;
                   3876: 
                   3877:       if (flags & LOOKUP_PROTECT)
                   3878:        {
                   3879:          enum access_type access = compute_access (basetypes, dtor);
                   3880: 
                   3881:          if (access == access_private)
                   3882:            {
                   3883:              if (flags & LOOKUP_COMPLAIN)
                   3884:                cp_error ("destructor for type `%T' is private in this scope", type);
                   3885:              return error_mark_node;
                   3886:            }
                   3887:          else if (access == access_protected)
                   3888:            {
                   3889:              if (flags & LOOKUP_COMPLAIN)
                   3890:                cp_error ("destructor for type `%T' is protected in this scope", type);
                   3891:              return error_mark_node;
                   3892:            }
                   3893:        }
                   3894: 
                   3895:       /* Once we are in a destructor, try not going through
                   3896:         the virtual function table to find the next destructor.  */
                   3897:       if (DECL_VINDEX (dtor)
                   3898:          && ! (flags & LOOKUP_NONVIRTUAL)
                   3899:          && TREE_CODE (auto_delete) != PARM_DECL
                   3900:          && (ptr == 1 || ! resolves_to_fixed_type_p (ref, 0)))
                   3901:        {
                   3902:          tree binfo, basetype;
                   3903:          /* The code below is probably all broken.  See call.c for the
                   3904:             complete right way to do this. this offsets may not be right
                   3905:             in the below.  (mrs) */
                   3906:          /* This destructor must be called via virtual function table.  */
                   3907:          dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (DECL_CONTEXT (dtor)), 0);
                   3908:          basetype = DECL_CLASS_CONTEXT (dtor);
                   3909:          binfo = get_binfo (basetype,
                   3910:                             TREE_TYPE (TREE_TYPE (TREE_VALUE (parms))),
                   3911:                             0);
                   3912:          expr = convert_pointer_to_real (binfo, TREE_VALUE (parms));
                   3913:          if (expr != TREE_VALUE (parms))
                   3914:            {
                   3915:              expr = fold (expr);
                   3916:              ref = build_indirect_ref (expr, NULL_PTR);
                   3917:              TREE_VALUE (parms) = expr;
                   3918:            }
                   3919:          function = build_vfn_ref (&TREE_VALUE (parms), ref, DECL_VINDEX (dtor));
                   3920:          if (function == error_mark_node)
                   3921:            return error_mark_node;
                   3922:          TREE_TYPE (function) = build_pointer_type (TREE_TYPE (dtor));
                   3923:          TREE_CHAIN (parms) = build_tree_list (NULL_TREE, passed_auto_delete);
                   3924:          expr = build_function_call (function, parms);
                   3925:          if (do_delete)
                   3926:            expr = build (COMPOUND_EXPR, void_type_node, expr, do_delete);
                   3927:          if (ptr && (flags & LOOKUP_DESTRUCTOR) == 0)
                   3928:            {
                   3929:              /* Handle the case where a virtual destructor is
                   3930:                 being called on an item that is 0.
                   3931: 
                   3932:                 @@ Does this really need to be done?  */
                   3933:              tree ifexp = build_binary_op(NE_EXPR, addr, integer_zero_node,1);
                   3934: #if 0
                   3935:              if (TREE_CODE (ref) == VAR_DECL
                   3936:                  || TREE_CODE (ref) == COMPONENT_REF)
                   3937:                warning ("losing in build_delete");
                   3938: #endif
                   3939:              expr = build (COND_EXPR, void_type_node,
                   3940:                            ifexp, expr, void_zero_node);
                   3941:            }
                   3942:        }
                   3943:       else
                   3944:        {
                   3945:          tree ifexp;
                   3946: 
                   3947:          if ((flags & LOOKUP_DESTRUCTOR)
                   3948:              || TREE_CODE (ref) == VAR_DECL
                   3949:              || TREE_CODE (ref) == PARM_DECL
                   3950:              || TREE_CODE (ref) == COMPONENT_REF
                   3951:              || TREE_CODE (ref) == ARRAY_REF)
                   3952:            /* These can't be 0.  */
                   3953:            ifexp = integer_one_node;
                   3954:          else
                   3955:            /* Handle the case where a non-virtual destructor is
                   3956:               being called on an item that is 0.  */
                   3957:            ifexp = build_binary_op (NE_EXPR, addr, integer_zero_node, 1);
                   3958: 
                   3959:          /* Used to mean that this destructor was known to be empty,
                   3960:             but that's now obsolete.  */
                   3961:          my_friendly_assert (DECL_INITIAL (dtor) != void_type_node, 221);
                   3962: 
                   3963:          TREE_CHAIN (parms) = build_tree_list (NULL_TREE, passed_auto_delete);
                   3964:          expr = build_function_call (dtor, parms);
                   3965:          if (do_delete)
                   3966:            expr = build (COMPOUND_EXPR, void_type_node, expr, do_delete);
                   3967: 
                   3968:          if (ifexp != integer_one_node)
                   3969:            expr = build (COND_EXPR, void_type_node,
                   3970:                          ifexp, expr, void_zero_node);
                   3971:        }
                   3972:       return expr;
                   3973:     }
                   3974:   else
                   3975:     {
                   3976:       /* This can get visibilities wrong.  */
                   3977:       tree binfos = BINFO_BASETYPES (TYPE_BINFO (type));
                   3978:       int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
                   3979:       tree base_binfo = n_baseclasses > 0 ? TREE_VEC_ELT (binfos, 0) : NULL_TREE;
                   3980:       tree exprstmt = NULL_TREE;
                   3981:       tree parent_auto_delete = auto_delete;
                   3982:       tree cond;
                   3983: 
                   3984:       /* If this type does not have a destructor, but does have
                   3985:         operator delete, call the parent parent destructor (if any),
                   3986:         but let this node do the deleting.  Otherwise, it is ok
                   3987:         to let the parent destructor do the deleting.  */
                   3988:       if (TYPE_GETS_REG_DELETE (type) && !use_global_delete)
                   3989:        {
                   3990:          parent_auto_delete = integer_zero_node;
                   3991:          if (auto_delete == integer_zero_node)
                   3992:            cond = NULL_TREE;
                   3993:          else
                   3994:            {
                   3995:              tree virtual_size;
                   3996: 
                   3997:                /* This is probably wrong. It should be the size of the
                   3998:                   virtual object being deleted.  */
                   3999:              virtual_size = c_sizeof_nowarn (type);
                   4000: 
                   4001:              expr = build_opfncall (DELETE_EXPR, LOOKUP_NORMAL, addr,
                   4002:                                     virtual_size, NULL_TREE);
                   4003:              if (expr == error_mark_node)
                   4004:                return error_mark_node;
                   4005:              if (auto_delete != integer_one_node)
                   4006:                cond = build (COND_EXPR, void_type_node,
                   4007:                              build (BIT_AND_EXPR, integer_type_node,
                   4008:                                     auto_delete, integer_one_node),
                   4009:                              expr, void_zero_node);
                   4010:              else
                   4011:                cond = expr;
                   4012:            }
                   4013:        }
                   4014:       else if (base_binfo == NULL_TREE
                   4015:               || (TREE_VIA_VIRTUAL (base_binfo) == 0
                   4016:                   && ! TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo))))
                   4017:        {
                   4018:          tree virtual_size;
                   4019: 
                   4020:          /* This is probably wrong. It should be the size of the virtual
                   4021:             object being deleted.  */
                   4022:          virtual_size = c_sizeof_nowarn (type);
                   4023: 
                   4024:          cond = build (COND_EXPR, void_type_node,
                   4025:                        build (BIT_AND_EXPR, integer_type_node, auto_delete, integer_one_node),
                   4026:                        build_builtin_call (void_type_node, BID,
                   4027:                                            build_tree_list (NULL_TREE, addr)),
                   4028:                        void_zero_node);
                   4029:        }
                   4030:       else
                   4031:        cond = NULL_TREE;
                   4032: 
                   4033:       if (cond)
                   4034:        exprstmt = build_tree_list (NULL_TREE, cond);
                   4035: 
                   4036:       if (base_binfo
                   4037:          && ! TREE_VIA_VIRTUAL (base_binfo)
                   4038:          && TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo)))
                   4039:        {
                   4040:          tree this_auto_delete;
                   4041: 
                   4042:          if (BINFO_OFFSET_ZEROP (base_binfo))
                   4043:            this_auto_delete = parent_auto_delete;
                   4044:          else
                   4045:            this_auto_delete = integer_zero_node;
                   4046: 
1.1.1.2 ! root     4047:          expr = build_delete (build_pointer_type (BINFO_TYPE (base_binfo)), addr,
1.1       root     4048:                               this_auto_delete, flags, 0);
                   4049:          exprstmt = tree_cons (NULL_TREE, expr, exprstmt);
                   4050:        }
                   4051: 
                   4052:       /* Take care of the remaining baseclasses.  */
                   4053:       for (i = 1; i < n_baseclasses; i++)
                   4054:        {
                   4055:          base_binfo = TREE_VEC_ELT (binfos, i);
                   4056:          if (! TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo))
                   4057:              || TREE_VIA_VIRTUAL (base_binfo))
                   4058:            continue;
                   4059: 
                   4060:          /* May be zero offset if other baseclasses are virtual.  */
1.1.1.2 ! root     4061:          expr = fold (build (PLUS_EXPR, build_pointer_type (BINFO_TYPE (base_binfo)),
1.1       root     4062:                              addr, BINFO_OFFSET (base_binfo)));
                   4063: 
1.1.1.2 ! root     4064:          expr = build_delete (build_pointer_type (BINFO_TYPE (base_binfo)), expr,
1.1       root     4065:                               integer_zero_node,
                   4066:                               flags, 0);
                   4067: 
                   4068:          exprstmt = tree_cons (NULL_TREE, expr, exprstmt);
                   4069:        }
                   4070: 
                   4071:       for (member = TYPE_FIELDS (type); member; member = TREE_CHAIN (member))
                   4072:        {
                   4073:          if (TREE_CODE (member) != FIELD_DECL)
                   4074:            continue;
                   4075:          if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (member)))
                   4076:            {
                   4077:              tree this_member = build_component_ref (ref, DECL_NAME (member), 0, 0);
                   4078:              tree this_type = TREE_TYPE (member);
                   4079:              expr = build_delete (this_type, this_member, integer_two_node, flags, 0);
                   4080:              exprstmt = tree_cons (NULL_TREE, expr, exprstmt);
                   4081:            }
                   4082:        }
                   4083: 
                   4084:       if (exprstmt)
                   4085:        return build_compound_expr (exprstmt);
                   4086:       /* Virtual base classes make this function do nothing.  */
                   4087:       return void_zero_node;
                   4088:     }
                   4089: }
                   4090: 
                   4091: /* For type TYPE, delete the virtual baseclass objects of DECL.  */
                   4092: 
                   4093: tree
                   4094: build_vbase_delete (type, decl)
                   4095:      tree type, decl;
                   4096: {
                   4097:   tree vbases = CLASSTYPE_VBASECLASSES (type);
                   4098:   tree result = NULL_TREE;
                   4099:   tree addr = build_unary_op (ADDR_EXPR, decl, 0);
                   4100: 
                   4101:   my_friendly_assert (addr != error_mark_node, 222);
                   4102: 
                   4103:   while (vbases)
                   4104:     {
1.1.1.2 ! root     4105:       tree this_addr = convert_force (build_pointer_type (BINFO_TYPE (vbases)),
        !          4106:                                      addr, 0);
1.1       root     4107:       result = tree_cons (NULL_TREE,
                   4108:                          build_delete (TREE_TYPE (this_addr), this_addr,
                   4109:                                        integer_zero_node,
                   4110:                                        LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0),
                   4111:                          result);
                   4112:       vbases = TREE_CHAIN (vbases);
                   4113:     }
                   4114:   return build_compound_expr (nreverse (result));
                   4115: }
                   4116: 
                   4117: /* Build a C++ vector delete expression.
                   4118:    MAXINDEX is the number of elements to be deleted.
                   4119:    ELT_SIZE is the nominal size of each element in the vector.
                   4120:    BASE is the expression that should yield the store to be deleted.
                   4121:    This function expands (or synthesizes) these calls itself.
                   4122:    AUTO_DELETE_VEC says whether the container (vector) should be deallocated.
                   4123:    AUTO_DELETE say whether each item in the container should be deallocated.
                   4124: 
                   4125:    This also calls delete for virtual baseclasses of elements of the vector.
                   4126: 
                   4127:    Update: MAXINDEX is no longer needed.  The size can be extracted from the
                   4128:    start of the vector for pointers, and from the type for arrays.  We still
                   4129:    use MAXINDEX for arrays because it happens to already have one of the
                   4130:    values we'd have to extract.  (We could use MAXINDEX with pointers to
                   4131:    confirm the size, and trap if the numbers differ; not clear that it'd
                   4132:    be worth bothering.)  */
                   4133: tree
                   4134: build_vec_delete (base, maxindex, elt_size, auto_delete_vec, auto_delete,
                   4135:                  use_global_delete)
                   4136:      tree base, maxindex, elt_size;
                   4137:      tree auto_delete_vec, auto_delete;
                   4138:      int use_global_delete;
                   4139: {
                   4140:   tree type;
                   4141: 
1.1.1.2 ! root     4142:   if (TREE_CODE (base) == OFFSET_REF)
        !          4143:     base = resolve_offset_ref (base);
1.1       root     4144: 
1.1.1.2 ! root     4145:   type = TREE_TYPE (base);
1.1       root     4146: 
                   4147:   base = stabilize_reference (base);
                   4148: 
                   4149:   /* Since we can use base many times, save_expr it. */
                   4150:   if (TREE_SIDE_EFFECTS (base))
                   4151:     base = save_expr (base);
                   4152: 
1.1.1.2 ! root     4153:   if (TREE_CODE (type) == POINTER_TYPE)
1.1       root     4154:     {
                   4155:       /* Step back one from start of vector, and read dimension.  */
1.1.1.2 ! root     4156:       tree cookie_addr = build (MINUS_EXPR, build_pointer_type (BI_header_type),
1.1       root     4157:                                base, BI_header_size);
                   4158:       tree cookie = build_indirect_ref (cookie_addr, NULL_PTR);
                   4159:       maxindex = build_component_ref (cookie, nc_nelts_field_id, 0, 0);
                   4160:       do
1.1.1.2 ! root     4161:        type = TREE_TYPE (type);
        !          4162:       while (TREE_CODE (type) == ARRAY_TYPE);
1.1       root     4163:     }
1.1.1.2 ! root     4164:   else if (TREE_CODE (type) == ARRAY_TYPE)
1.1       root     4165:     {
                   4166:       /* get the total number of things in the array, maxindex is a bad name */
1.1.1.2 ! root     4167:       maxindex = array_type_nelts_total (type);
        !          4168:       while (TREE_CODE (type) == ARRAY_TYPE)
        !          4169:        type = TREE_TYPE (type);
1.1       root     4170:       base = build_unary_op (ADDR_EXPR, base, 1);
                   4171:     }
                   4172:   else
                   4173:     {
                   4174:       error ("type to vector delete is neither pointer or array type");
                   4175:       return error_mark_node;
                   4176:     }
                   4177: 
1.1.1.2 ! root     4178:   return build_vec_delete_1 (base, maxindex, type, auto_delete_vec, auto_delete,
        !          4179:                             use_global_delete);
1.1       root     4180: }

unix.superglobalmegacorp.com

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