Annotation of gcc/cp-init.c, revision 1.1.1.4

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

unix.superglobalmegacorp.com

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