Annotation of GNUtools/cc/cp-cvt.c, revision 1.1.1.1

1.1       root        1: /* Language-level data type conversion for GNU C++.
                      2:    Copyright (C) 1987, 1988, 1992, 1993 Free Software Foundation, Inc.
                      3:    Hacked by Michael Tiemann ([email protected])
                      4: 
                      5: This file is part of GNU CC.
                      6: 
                      7: GNU CC is free software; you can redistribute it and/or modify
                      8: it under the terms of the GNU General Public License as published by
                      9: the Free Software Foundation; either version 2, or (at your option)
                     10: any later version.
                     11: 
                     12: GNU CC is distributed in the hope that it will be useful,
                     13: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     15: GNU General Public License for more details.
                     16: 
                     17: You should have received a copy of the GNU General Public License
                     18: along with GNU CC; see the file COPYING.  If not, write to
                     19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
                     20: 
                     21: 
                     22: /* This file contains the functions for converting C expressions
                     23:    to different data types.  The only entry point is `convert'.
                     24:    Every language front end must have a `convert' function
                     25:    but what kind of conversions it does will depend on the language.  */
                     26: 
                     27: #include "config.h"
                     28: #include "tree.h"
                     29: #include "flags.h"
                     30: #include "cp-tree.h"
                     31: #include "cp-class.h"
                     32: #include "convert.h"
                     33: 
                     34: #undef NULL
                     35: #define NULL (char *)0
                     36: 
                     37: /* Change of width--truncation and extension of integers or reals--
                     38:    is represented with NOP_EXPR.  Proper functioning of many things
                     39:    assumes that no other conversions can be NOP_EXPRs.
                     40: 
                     41:    Conversion between integer and pointer is represented with CONVERT_EXPR.
                     42:    Converting integer to real uses FLOAT_EXPR
                     43:    and real to integer uses FIX_TRUNC_EXPR.
                     44: 
                     45:    Here is a list of all the functions that assume that widening and
                     46:    narrowing is always done with a NOP_EXPR:
                     47:      In convert.c, convert_to_integer.
                     48:      In c-typeck.c, build_binary_op_nodefault (boolean ops),
                     49:         and truthvalue_conversion.
                     50:      In expr.c: expand_expr, for operands of a MULT_EXPR.
                     51:      In fold-const.c: fold.
                     52:      In tree.c: get_narrower and get_unwidened.
                     53: 
                     54:    C++: in multiple-inheritance, converting between pointers may involve
                     55:    adjusting them by a delta stored within the class definition.  */
                     56: 
                     57: /* Subroutines of `convert'.  */
                     58: 
                     59: /* Build a thunk.  What it is, is an entry point that when called will
                     60:    adjust the this pointer (the first argument) by offset, and then
                     61:    goto the real address of the function given by REAL_ADDR that we
                     62:    would like called.  What we return is the address of the thunk.  */
                     63: static tree
                     64: build_thunk (offset, real_addr)
                     65:      tree offset, real_addr;
                     66: {
                     67:   if (TREE_CODE (real_addr) != ADDR_EXPR
                     68:       || TREE_CODE (TREE_OPERAND (real_addr, 0)) != FUNCTION_DECL)
                     69:     {
                     70:       sorry ("MI pointer to member conversion too complex");
                     71:       return error_mark_node;
                     72:     }
                     73:   sorry ("MI pointer to member conversion too complex");
                     74:   return error_mark_node;
                     75: }
                     76: 
                     77: /* Convert a `pointer to member' (POINTER_TYPE to METHOD_TYPE) into
                     78:    another `pointer to method'.  This may involved the creation of
                     79:    a thunk to handle the this offset calculation.  */
                     80: static tree
                     81: convert_fn_ptr (type, expr)
                     82:      tree type, expr;
                     83: {
                     84:   tree binfo = get_binfo (TYPE_METHOD_BASETYPE (TREE_TYPE (TREE_TYPE (expr))),
                     85:                          TYPE_METHOD_BASETYPE (TREE_TYPE (type)),
                     86:                          1);
                     87:   if (binfo == error_mark_node)
                     88:     {
                     89:       error ("  in pointer to member conversion");
                     90:       return error_mark_node;
                     91:     }
                     92:   if (binfo == NULL_TREE)
                     93:     {
                     94:       /* ARM 4.8 restriction. */
                     95:       error ("invalid pointer to member conversion");
                     96:       return error_mark_node;
                     97:     }
                     98:   if (BINFO_OFFSET_ZEROP (binfo))
                     99:     return build1 (NOP_EXPR, type, expr);
                    100:   return build1 (NOP_EXPR, type, build_thunk (BINFO_OFFSET (binfo), expr));
                    101: }
                    102: 
                    103: /* if converting pointer to pointer
                    104:      if dealing with classes, check for derived->base or vice versa
                    105:      else if dealing with method pointers, delegate
                    106:      else convert blindly
                    107:    else if converting class, pass off to build_type_conversion
                    108:    else try C-style pointer conversion  */
                    109: static tree
                    110: cp_convert_to_pointer (type, expr)
                    111:      tree type, expr;
                    112: {
                    113:   register tree intype = TREE_TYPE (expr);
                    114:   register enum tree_code form = TREE_CODE (intype);
                    115:   
                    116:   if (form == POINTER_TYPE)
                    117:     {
                    118:       intype = TYPE_MAIN_VARIANT (intype);
                    119: 
                    120:       if (TYPE_MAIN_VARIANT (type) != intype
                    121:          && TREE_CODE (TREE_TYPE (type)) == RECORD_TYPE
                    122:          && TREE_CODE (TREE_TYPE (intype)) == RECORD_TYPE)
                    123:        {
                    124:          enum tree_code code = PLUS_EXPR;
                    125:          tree binfo = get_binfo (TREE_TYPE (type), TREE_TYPE (intype), 1);
                    126:          if (binfo == error_mark_node)
                    127:            return error_mark_node;
                    128:          if (binfo == NULL_TREE)
                    129:            {
                    130:              binfo = get_binfo (TREE_TYPE (intype), TREE_TYPE (type), 1);
                    131:              if (binfo == error_mark_node)
                    132:                return error_mark_node;
                    133:              code = MINUS_EXPR;
                    134:            }
                    135:          if (binfo && TREE_CODE (binfo) == TREE_VEC)
                    136:            {
                    137:              if (TYPE_USES_VIRTUAL_BASECLASSES (TREE_TYPE (type))
                    138:                  || TYPE_USES_VIRTUAL_BASECLASSES (TREE_TYPE (intype))
                    139:                  || ! BINFO_OFFSET_ZEROP (binfo))
                    140:                {
                    141:                  /* Need to get the path we took.  */
                    142:                  tree path;
                    143: 
                    144:                  if (code == PLUS_EXPR)
                    145:                    get_base_distance (TREE_TYPE (type), TREE_TYPE (intype), 0, &path);
                    146:                  else
                    147:                    get_base_distance (TREE_TYPE (intype), TREE_TYPE (type), 0, &path);
                    148:                  return build_vbase_path (code, type, expr, path, 0);
                    149:                }
                    150:            }
                    151:        }
                    152:       if (TYPE_MAIN_VARIANT (type) != intype
                    153:          && TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE
                    154:          && TREE_CODE (type) == POINTER_TYPE
                    155:          && TREE_CODE (TREE_TYPE (intype)) == METHOD_TYPE)
                    156:        return convert_fn_ptr (type, expr);
                    157: 
                    158:       return build1 (NOP_EXPR, type, expr);
                    159:     }
                    160: 
                    161:   my_friendly_assert (form != OFFSET_TYPE, 186);
                    162: 
                    163:   if (IS_AGGR_TYPE (intype))
                    164:     {
                    165:       /* If we cannot convert to the specific pointer type,
                    166:         try to convert to the type `void *'.  */
                    167:       tree rval;
                    168:       rval = build_type_conversion (CONVERT_EXPR, type, expr, 1);
                    169:       if (rval)
                    170:        {
                    171:          if (rval == error_mark_node)
                    172:            error ("ambiguous pointer conversion");
                    173:          return rval;
                    174:        }
                    175:     }
                    176: 
                    177:   return convert_to_pointer (type, expr);
                    178: }
                    179: 
                    180: /* Like convert, except permit conversions to take place which
                    181:    are not normally allowed due to visibility restrictions
                    182:    (such as conversion from sub-type to private super-type).  */
                    183: static tree
                    184: convert_to_pointer_force (type, expr)
                    185:      tree type, expr;
                    186: {
                    187:   register tree intype = TREE_TYPE (expr);
                    188:   register enum tree_code form = TREE_CODE (intype);
                    189:   
                    190:   if (integer_zerop (expr))
                    191:     {
                    192:       if (type == TREE_TYPE (null_pointer_node))
                    193:        return null_pointer_node;
                    194:       expr = build_int_2 (0, 0);
                    195:       TREE_TYPE (expr) = type;
                    196:       return expr;
                    197:     }
                    198: 
                    199:   if (form == POINTER_TYPE)
                    200:     {
                    201:       intype = TYPE_MAIN_VARIANT (intype);
                    202: 
                    203:       if (TYPE_MAIN_VARIANT (type) != intype
                    204:          && TREE_CODE (TREE_TYPE (type)) == RECORD_TYPE
                    205:          && TREE_CODE (TREE_TYPE (intype)) == RECORD_TYPE)
                    206:        {
                    207:          enum tree_code code = PLUS_EXPR;
                    208:          tree path;
                    209:          int distance = get_base_distance (TREE_TYPE (type),
                    210:                                            TREE_TYPE (intype), 0, &path);
                    211:          if (distance == -2)
                    212:            {
                    213:            ambig:
                    214:              cp_error ("type `%T' is ambiguous baseclass of `%s'", TREE_TYPE (type),
                    215:                                    TYPE_NAME_STRING (TREE_TYPE (intype)));
                    216:              return error_mark_node;
                    217:            }
                    218:          if (distance == -1)
                    219:            {
                    220:              distance = get_base_distance (TREE_TYPE (intype),
                    221:                                            TREE_TYPE (type), 0, &path);
                    222:              if (distance == -2)
                    223:                goto ambig;
                    224:              if (distance < 0)
                    225:                /* Doesn't need any special help from us.  */
                    226:                return build1 (NOP_EXPR, type, expr);
                    227: 
                    228:              code = MINUS_EXPR;
                    229:            }
                    230:          return build_vbase_path (code, type, expr, path, 0);
                    231:        }
                    232:       return build1 (NOP_EXPR, type, expr);
                    233:     }
                    234: 
                    235:   return cp_convert_to_pointer (type, expr);
                    236: }
                    237: 
                    238: /* We are passing something to a function which requires a reference.
                    239:    The type we are interested in is in TYPE. The initial
                    240:    value we have to begin with is in ARG.
                    241: 
                    242:    FLAGS controls how we manage visibility checking.
                    243:    CHECKCONST controls if we report error messages on const subversion.  */
                    244: static tree
                    245: build_up_reference (type, arg, flags, checkconst)
                    246:      tree type, arg;
                    247:      int flags, checkconst;
                    248: {
                    249:   tree rval, targ;
                    250:   int literal_flag = 0;
                    251:   tree argtype = TREE_TYPE (arg), basetype = argtype;
                    252:   tree target_type = TREE_TYPE (type);
                    253:   tree binfo = NULL_TREE;
                    254: 
                    255:   my_friendly_assert (TREE_CODE (type) == REFERENCE_TYPE, 187);
                    256:   if (flags != 0
                    257:       && TYPE_MAIN_VARIANT (argtype) != TYPE_MAIN_VARIANT (target_type)
                    258:       && IS_AGGR_TYPE (argtype)
                    259:       && IS_AGGR_TYPE (target_type))
                    260:     {
                    261:       binfo = get_binfo (target_type, argtype,
                    262:                              (flags & LOOKUP_PROTECTED_OK) ? 3 : 2);
                    263:       if ((flags & LOOKUP_PROTECT) && binfo == error_mark_node)
                    264:        return error_mark_node;
                    265:       if (binfo == NULL_TREE)
                    266:        return error_not_base_type (target_type, argtype);
                    267:       basetype = BINFO_TYPE (binfo);
                    268:     }
                    269: 
                    270:   /* Pass along const and volatile down into the type. */
                    271:   if (TYPE_READONLY (type) || TYPE_VOLATILE (type))
                    272:     target_type = build_type_variant (target_type, TYPE_READONLY (type),
                    273:                                      TYPE_VOLATILE (type));
                    274:   targ = arg;
                    275:   if (TREE_CODE (targ) == SAVE_EXPR)
                    276:     targ = TREE_OPERAND (targ, 0);
                    277: 
                    278:   switch (TREE_CODE (targ))
                    279:     {
                    280:     case INDIRECT_REF:
                    281:       /* This is a call to a constructor which did not know what it was
                    282:         initializing until now: it needs to initialize a temporary.  */
                    283:       if (TREE_HAS_CONSTRUCTOR (targ))
                    284:        {
                    285:          tree temp = build_cplus_new (argtype, TREE_OPERAND (targ, 0), 1);
                    286:          TREE_HAS_CONSTRUCTOR (targ) = 0;
                    287:          return build_up_reference (type, temp, flags, 1);
                    288:        }
                    289:       /* Let &* cancel out to simplify resulting code.
                    290:          Also, throw away intervening NOP_EXPRs.  */
                    291:       arg = TREE_OPERAND (targ, 0);
                    292:       if (TREE_CODE (arg) == NOP_EXPR || TREE_CODE (arg) == NON_LVALUE_EXPR
                    293:          || (TREE_CODE (arg) == CONVERT_EXPR && TREE_REFERENCE_EXPR (arg)))
                    294:        arg = TREE_OPERAND (arg, 0);
                    295: 
                    296:       /* in doing a &*, we have to get rid of the const'ness on the pointer
                    297:         value.  Haven't thought about volatile here.  Pointers come to mind
                    298:         here.  */
                    299:       if (TREE_READONLY (arg))
                    300:        {
                    301:          arg = copy_node (arg);
                    302:          TREE_READONLY (arg) = 0;
                    303:        }
                    304: 
                    305:       rval = build1 (CONVERT_EXPR, type, arg);
                    306:       TREE_REFERENCE_EXPR (rval) = 1;
                    307: 
                    308:       /* propagate the const flag on something like:
                    309: 
                    310:         class Base {
                    311:         public:
                    312:           int foo;
                    313:         };
                    314: 
                    315:       class Derived : public Base {
                    316:       public:
                    317:        int bar;
                    318:       };
                    319: 
                    320:       void func(Base&);
                    321: 
                    322:       void func2(const Derived& d) {
                    323:        func(d);
                    324:       }
                    325: 
                    326:         on the d parameter.  The below could have been avoided, if the flags
                    327:         were down in the tree, not sure why they are not.  (mrs) */
                    328:       /* The below code may have to be propagated to other parts of this
                    329:         switch.  */
                    330:       if (TREE_READONLY (targ) && !TREE_READONLY (arg)
                    331:          && (TREE_CODE (arg) == PARM_DECL || TREE_CODE (arg) == VAR_DECL)
                    332:          && TREE_CODE (TREE_TYPE (arg)) == REFERENCE_TYPE
                    333:          && (TYPE_READONLY (target_type) && checkconst))
                    334:        {
                    335:          arg = copy_node (arg);
                    336:          TREE_READONLY (arg) = TREE_READONLY (targ);
                    337:        }
                    338:       literal_flag = TREE_CONSTANT (arg);
                    339: 
                    340:       goto done_but_maybe_warn;
                    341: 
                    342:       /* Get this out of a register if we happened to be in one by accident.
                    343:         Also, build up references to non-lvalues it we must.  */
                    344:       /* For &x[y], return (&) x+y */
                    345:     case ARRAY_REF:
                    346:       if (mark_addressable (TREE_OPERAND (targ, 0)) == 0)
                    347:        return error_mark_node;
                    348:       rval = build_binary_op (PLUS_EXPR, TREE_OPERAND (targ, 0),
                    349:                              TREE_OPERAND (targ, 1), 1);
                    350:       TREE_TYPE (rval) = type;
                    351:       if (TREE_CONSTANT (TREE_OPERAND (targ, 1))
                    352:          && staticp (TREE_OPERAND (targ, 0)))
                    353:        TREE_CONSTANT (rval) = 1;
                    354:       goto done;
                    355: 
                    356:     case SCOPE_REF:
                    357:       /* Could be a reference to a static member.  */
                    358:       {
                    359:        tree field = TREE_OPERAND (targ, 1);
                    360:        if (TREE_STATIC (field))
                    361:          {
                    362:            rval = build1 (ADDR_EXPR, type, field);
                    363:            literal_flag = 1;
                    364:            goto done;
                    365:          }
                    366:       }
                    367: 
                    368:       /* We should have farmed out member pointers above.  */
                    369:       my_friendly_abort (188);
                    370: 
                    371:     case COMPONENT_REF:
                    372:       rval = build_component_addr (targ, build_pointer_type (argtype),
                    373:                                   "attempt to make a reference to bit-field structure member `%s'");
                    374:       TREE_TYPE (rval) = type;
                    375:       literal_flag = staticp (TREE_OPERAND (targ, 0));
                    376: 
                    377:       goto done_but_maybe_warn;
                    378: 
                    379:       /* Anything not already handled and not a true memory reference
                    380:         needs to have a reference built up.  Do so silently for
                    381:         things like integers and return values from function,
                    382:         but complain if we need a reference to something declared
                    383:         as `register'.  */
                    384: 
                    385:     case RESULT_DECL:
                    386:       if (staticp (targ))
                    387:        literal_flag = 1;
                    388:       TREE_ADDRESSABLE (targ) = 1;
                    389:       put_var_into_stack (targ);
                    390:       break;
                    391: 
                    392:     case PARM_DECL:
                    393:       if (targ == current_class_decl)
                    394:        {
                    395:          error ("address of `this' not available");
                    396: #if 0
                    397:          /* This code makes the following core dump the compiler on a sun4,
                    398:             if the code below is used.
                    399: 
                    400:             class e_decl;
                    401:             class a_decl;
                    402:             typedef a_decl* a_ref;
                    403: 
                    404:             class a_s {
                    405:             public:
                    406:               a_s();
                    407:               void* append(a_ref& item);
                    408:             };
                    409:             class a_decl {
                    410:             public:
                    411:               a_decl (e_decl *parent);
                    412:               a_s  generic_s;
                    413:               a_s  decls;
                    414:               e_decl* parent;
                    415:             };
                    416: 
                    417:             class e_decl {
                    418:             public:
                    419:               e_decl();
                    420:               a_s implementations;
                    421:             };
                    422: 
                    423:             void foobar(void *);
                    424: 
                    425:             a_decl::a_decl(e_decl *parent) {
                    426:               parent->implementations.append(this);
                    427:             }
                    428:           */
                    429: 
                    430:          TREE_ADDRESSABLE (targ) = 1; /* so compiler doesn't die later */
                    431:          put_var_into_stack (targ);
                    432:          break;
                    433: #else
                    434:          return error_mark_node;
                    435: #endif
                    436:        }
                    437:       /* Fall through.  */
                    438:     case VAR_DECL:
                    439:     case CONST_DECL:
                    440:       if (DECL_REGISTER (targ) && !TREE_ADDRESSABLE (targ))
                    441:        warning ("address needed to build reference for `%s', which is declared `register'",
                    442:                 IDENTIFIER_POINTER (DECL_NAME (targ)));
                    443:       else if (staticp (targ))
                    444:        literal_flag = 1;
                    445: 
                    446:       TREE_ADDRESSABLE (targ) = 1;
                    447:       put_var_into_stack (targ);
                    448:       break;
                    449: 
                    450:     case COMPOUND_EXPR:
                    451:       {
                    452:        tree real_reference = build_up_reference (type, TREE_OPERAND (targ, 1),
                    453:                                                  LOOKUP_PROTECT, checkconst);
                    454:        rval = build (COMPOUND_EXPR, type, TREE_OPERAND (targ, 0), real_reference);
                    455:        TREE_CONSTANT (rval) = staticp (TREE_OPERAND (targ, 1));
                    456:        return rval;
                    457:       }
                    458: 
                    459:     case MODIFY_EXPR:
                    460:     case INIT_EXPR:
                    461:       {
                    462:        tree real_reference = build_up_reference (type, TREE_OPERAND (targ, 0),
                    463:                                                  LOOKUP_PROTECT, checkconst);
                    464:        rval = build (COMPOUND_EXPR, type, arg, real_reference);
                    465:        TREE_CONSTANT (rval) = staticp (TREE_OPERAND (targ, 0));
                    466:        return rval;
                    467:       }
                    468: 
                    469:     case COND_EXPR:
                    470:       return build (COND_EXPR, type,
                    471:                    TREE_OPERAND (targ, 0),
                    472:                    build_up_reference (type, TREE_OPERAND (targ, 1),
                    473:                                        LOOKUP_PROTECT, checkconst),
                    474:                    build_up_reference (type, TREE_OPERAND (targ, 2),
                    475:                                        LOOKUP_PROTECT, checkconst));
                    476: 
                    477:     case WITH_CLEANUP_EXPR:
                    478:       return build (WITH_CLEANUP_EXPR, type,
                    479:                    build_up_reference (type, TREE_OPERAND (targ, 0),
                    480:                                        LOOKUP_PROTECT, checkconst),
                    481:                    0, TREE_OPERAND (targ, 2));
                    482: 
                    483:     case BIND_EXPR:
                    484:       arg = TREE_OPERAND (targ, 1);
                    485:       if (arg == NULL_TREE)
                    486:        {
                    487:          compiler_error ("({ ... }) expression not expanded when needed for reference");
                    488:          return error_mark_node;
                    489:        }
                    490:       rval = build1 (ADDR_EXPR, type, arg);
                    491:       TREE_REFERENCE_EXPR (rval) = 1;
                    492:       return rval;
                    493: 
                    494:     default:
                    495:       break;
                    496:     }
                    497: 
                    498:   if (TREE_ADDRESSABLE (targ) == 0)
                    499:     {
                    500:       tree temp;
                    501: 
                    502:       if (TREE_CODE (targ) == CALL_EXPR && IS_AGGR_TYPE (argtype))
                    503:        {
                    504:          temp = build_cplus_new (argtype, targ, 1);
                    505:          rval = build1 (ADDR_EXPR, type, temp);
                    506:          goto done;
                    507:        }
                    508:       else
                    509:        {
                    510:          temp = get_temp_name (argtype, 0);
                    511:          if (global_bindings_p ())
                    512:            {
                    513:              /* Give this new temp some rtl and initialize it.  */
                    514:              DECL_INITIAL (temp) = targ;
                    515:              TREE_STATIC (temp) = 1;
                    516:              finish_decl (temp, targ, NULL_TREE, 0);
                    517:              /* Do this after declaring it static.  */
                    518:              rval = build_unary_op (ADDR_EXPR, temp, 0);
                    519:              literal_flag = TREE_CONSTANT (rval);
                    520:              goto done;
                    521:            }
                    522:          else
                    523:            {
                    524:              rval = build_unary_op (ADDR_EXPR, temp, 0);
                    525:              /* Put a value into the rtl.  */
                    526:              if (IS_AGGR_TYPE (argtype))
                    527:                {
                    528:                  /* This may produce surprising results,
                    529:                     since we commit to initializing the temp
                    530:                     when the temp may not actually get used.  */
                    531:                  expand_aggr_init (temp, targ, 0);
                    532:                  TREE_TYPE (rval) = type;
                    533:                  literal_flag = TREE_CONSTANT (rval);
                    534:                  goto done;
                    535:                }
                    536:              else
                    537:                {
                    538:                  if (binfo && !BINFO_OFFSET_ZEROP (binfo))
                    539:                    rval = convert_pointer_to (target_type, rval);
                    540:                  else
                    541:                    TREE_TYPE (rval) = type;
                    542: 
                    543:                  temp = build (MODIFY_EXPR, argtype, temp, arg);
                    544:                  TREE_SIDE_EFFECTS (temp) = 1;
                    545:                  return build (COMPOUND_EXPR, type, temp, rval);
                    546:                }
                    547:            }
                    548:        }
                    549:     }
                    550:   else
                    551:     {
                    552:       if (TREE_CODE (arg) == SAVE_EXPR)
                    553:        my_friendly_abort (5);
                    554:       rval = build1 (ADDR_EXPR, type, arg);
                    555:     }
                    556: 
                    557:  done_but_maybe_warn:
                    558:   if (checkconst && TREE_READONLY (arg) && ! TYPE_READONLY (target_type))
                    559:     readonly_error (arg, "conversion to reference", 1);
                    560: 
                    561:  done:
                    562:   if (TYPE_USES_COMPLEX_INHERITANCE (argtype))
                    563:     {
                    564:       TREE_TYPE (rval) = TYPE_POINTER_TO (argtype);
                    565:       rval = convert_pointer_to (target_type, rval);
                    566:       TREE_TYPE (rval) = type;
                    567:     }
                    568:   TREE_CONSTANT (rval) = literal_flag;
                    569:   return rval;
                    570: }
                    571: 
                    572: /* For C++: Only need to do one-level references, but cannot
                    573:    get tripped up on signed/unsigned differences.
                    574: 
                    575:    If DECL is NULL_TREE it means convert as though casting (by force).
                    576:    If it is ERROR_MARK_NODE, it means the conversion is implicit,
                    577:    and that temporaries may be created.
                    578:    Make sure the use of user-defined conversion operators is un-ambiguous.
                    579:    Otherwise, DECL is a _DECL node which can be used in error reporting.
                    580: 
                    581:    FNDECL, PARMNUM, and ERRTYPE are only used when checking for use of
                    582:    volatile or const references where they aren't desired.  */
                    583: 
                    584: tree
                    585: convert_to_reference (decl, reftype, expr, fndecl, parmnum,
                    586:                      errtype, strict, flags)
                    587: 
                    588:      tree decl;
                    589:      tree reftype, expr;
                    590:      tree fndecl;
                    591:      int parmnum;
                    592:      char *errtype;
                    593:      int strict, flags;
                    594: {
                    595:   register tree type = TYPE_MAIN_VARIANT (TREE_TYPE (reftype));
                    596:   register tree intype = TREE_TYPE (expr);
                    597:   register enum tree_code form = TREE_CODE (intype);
                    598:   tree rval = NULL_TREE;
                    599: 
                    600:   if (TREE_CODE(type) == ARRAY_TYPE)
                    601:     type = build_pointer_type (TREE_TYPE(type));
                    602:   if (form == REFERENCE_TYPE)
                    603:     intype = TREE_TYPE (intype);
                    604:   intype = TYPE_MAIN_VARIANT (intype);
                    605: 
                    606:   /* @@ Probably need to have a check for X(X&) here.  */
                    607: 
                    608:   if (IS_AGGR_TYPE (intype))
                    609:     {
                    610:       rval = build_type_conversion (CONVERT_EXPR, reftype, expr, 1);
                    611:       if (rval)
                    612:        {
                    613:          if (rval == error_mark_node)
                    614:            error ("ambiguous pointer conversion");
                    615:          return rval;
                    616:        }
                    617:       else if (type != intype
                    618:               && (rval = build_type_conversion (CONVERT_EXPR, type, expr, 1)))
                    619:        {
                    620:          if (rval == error_mark_node)
                    621:            return rval;
                    622:          if (TYPE_NEEDS_DESTRUCTOR (type))
                    623:            {
                    624:              rval = convert_to_reference (NULL_TREE, reftype, rval, NULL_TREE,
                    625: -1, (char *)NULL, strict, flags);
                    626:            }
                    627:          else
                    628:            {
                    629:              decl = get_temp_name (type, 0);
                    630:              rval = build (INIT_EXPR, type, decl, rval);
                    631:              rval = build (COMPOUND_EXPR, reftype, rval,
                    632:                            convert_to_reference (NULL_TREE, reftype, decl,
                    633:                                                  NULL_TREE, -1, (char*)NULL,
                    634:                                                  strict, flags));
                    635:            }
                    636:        }
                    637: 
                    638:       if (form == REFERENCE_TYPE
                    639:          && type != intype
                    640:          && TYPE_USES_COMPLEX_INHERITANCE (intype))
                    641:        {
                    642:          /* If it may move around, build a fresh reference.  */
                    643:          expr = convert_from_reference (expr);
                    644:          form = TREE_CODE (TREE_TYPE (expr));
                    645:        }
                    646:     }
                    647: 
                    648:   /* @@ Perhaps this should try to go through a constructor first
                    649:      @@ for proper initialization, but I am not sure when that
                    650:      @@ is needed or desirable.  */
                    651: 
                    652:   if (((IS_AGGR_TYPE (type) || IS_AGGR_TYPE (intype))
                    653:        && comptypes (type, intype, strict))
                    654:       || (!IS_AGGR_TYPE (type)
                    655: #if 1
                    656:          && ((TREE_CODE (type) == TREE_CODE (intype)
                    657:               && int_size_in_bytes (type) == int_size_in_bytes (intype))
                    658:              || TREE_READONLY (TREE_TYPE (reftype)))))
                    659: #else
                    660:          && (comptypes (type, intype, 1)
                    661:              || TREE_READONLY (TREE_TYPE (reftype)))))
                    662: #endif
                    663: 
                    664:     {
                    665:       /* Section 13.  */
                    666:       /* Since convert_for_initialization didn't call convert_for_assignment,
                    667:         we have to do this checking here.  FIXME: We should have a common
                    668:         routine between here and convert_for_assignment.  */
                    669:       if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE)
                    670:        {
                    671:          register tree ttl = TREE_TYPE (reftype);
                    672:          register tree ttr = TREE_TYPE (TREE_TYPE (expr));
                    673: 
                    674:          if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
                    675:            warn_for_assignment ("%s of non-`const &' reference from `const &'",
                    676:                                 "reference to const given for argument %d of `%s'",
                    677:                                 errtype, fndecl, parmnum, pedantic);
                    678:          if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
                    679:            warn_for_assignment ("%s of non-`volatile &' reference from `volatile &'",
                    680:                                 "reference to volatile given for argument %d of `%s'", 
                    681:                                 errtype, fndecl, parmnum, pedantic);
                    682:        }
                    683: 
                    684:       /* If EXPR is of aggregate type, and is really a CALL_EXPR,
                    685:         then we don't need to convert it to reference type if
                    686:         it is only being used to initialize DECL which is also
                    687:         of the same aggregate type.  */
                    688:       if (form == REFERENCE_TYPE
                    689:          || (decl != NULL_TREE && decl != error_mark_node
                    690:              && IS_AGGR_TYPE (type)
                    691:              && TREE_CODE (expr) == CALL_EXPR
                    692:              && TYPE_MAIN_VARIANT (type) == intype))
                    693:        {
                    694:          if (decl && decl != error_mark_node)
                    695:            {
                    696:              tree e1 = build (INIT_EXPR, void_type_node, decl, expr);
                    697:              tree e2;
                    698: 
                    699:              TREE_SIDE_EFFECTS (e1) = 1;
                    700:              if (form == REFERENCE_TYPE)
                    701:                e2 = build1 (NOP_EXPR, reftype, decl);
                    702:              else
                    703:                {
                    704:                  e2 = build_unary_op (ADDR_EXPR, decl, 0);
                    705:                  TREE_TYPE (e2) = reftype;
                    706:                  TREE_REFERENCE_EXPR (e2) = 1;
                    707:                }
                    708:              return build_compound_expr (tree_cons (NULL_TREE, e1,
                    709:                                                     build_tree_list (NULL_TREE, e2)));
                    710:            }
                    711:          expr = copy_node (expr);
                    712:          TREE_TYPE (expr) = reftype;
                    713:          return expr;
                    714:        }
                    715:       if (decl == error_mark_node)
                    716:        flags |= LOOKUP_PROTECTED_OK;
                    717:       return build_up_reference (reftype, expr, flags, decl!=NULL_TREE);
                    718:     }
                    719: 
                    720:   /* Definitely need to go through a constructor here.  */
                    721:   if (TYPE_HAS_CONSTRUCTOR (type))
                    722:     {
                    723:       tree init = build_method_call (NULL_TREE, constructor_name_full (type),
                    724:                                     build_tree_list (NULL_TREE, expr),
                    725:                                     TYPE_BINFO (type), LOOKUP_NO_CONVERSION);
                    726: 
                    727:       if (init != error_mark_node)
                    728:        {
                    729:          if (rval)
                    730:            {
                    731:              error ("both constructor and type conversion operator apply");
                    732:              return error_mark_node;
                    733:            }
                    734:        }
                    735:       else
                    736:        {
                    737:          /* If a type conversion operator works, then pass that along
                    738:             to the ctor.  */
                    739:          if (rval != NULL_TREE)
                    740:            expr = rval;
                    741:        }
                    742: 
                    743:       init = build_method_call (NULL_TREE, constructor_name_full (type),
                    744:                                build_tree_list (NULL_TREE, expr),
                    745:                                TYPE_BINFO (type), LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
                    746: 
                    747:       if (init == error_mark_node)
                    748:        return error_mark_node;
                    749:       rval = build_cplus_new (type, init, 1);
                    750:       if (decl == error_mark_node)
                    751:        flags |= LOOKUP_PROTECTED_OK;
                    752:       return build_up_reference (reftype, rval, flags, decl!=NULL_TREE);
                    753:     }
                    754: 
                    755:   if (rval)
                    756:     {
                    757:       /* If we found a way to convert earlier, then use it. */
                    758:       return rval;
                    759:     }
                    760: 
                    761:   my_friendly_assert (form != OFFSET_TYPE, 189);
                    762: 
                    763:   cp_error ("cannot convert type `%T' to type `%T'", intype, reftype);
                    764: 
                    765:   return error_mark_node;
                    766: }
                    767: 
                    768: /* We are using a reference VAL for its value. Bash that reference all the
                    769:    way down to its lowest form. */
                    770: tree
                    771: convert_from_reference (val)
                    772:      tree val;
                    773: {
                    774:   tree type = TREE_TYPE (val);
                    775: 
                    776:   if (TREE_CODE (type) == OFFSET_TYPE)
                    777:     type = TREE_TYPE (type);
                    778:  if (TREE_CODE (type) == REFERENCE_TYPE)
                    779:     {
                    780:       tree target_type = TREE_TYPE (type);
                    781:       tree nval;
                    782: 
                    783:       /* This can happen if we cast to a reference type.  */
                    784:       if (TREE_CODE (val) == ADDR_EXPR)
                    785:        {
                    786:          nval = build1 (NOP_EXPR, build_pointer_type (target_type), val);
                    787:          nval = build_indirect_ref (nval, NULL_PTR);
                    788:          /* The below was missing, are other important flags missing too? */
                    789:          TREE_SIDE_EFFECTS (nval) = TREE_SIDE_EFFECTS (val);
                    790:          return nval;
                    791:        }
                    792: 
                    793:       nval = build1 (INDIRECT_REF, TYPE_MAIN_VARIANT (target_type), val);
                    794: 
                    795:       TREE_THIS_VOLATILE (nval) = TYPE_VOLATILE (target_type);
                    796:       TREE_SIDE_EFFECTS (nval) = TYPE_VOLATILE (target_type);
                    797:       TREE_READONLY (nval) = TYPE_READONLY (target_type);
                    798:       /* The below was missing, are other important flags missing too? */
                    799:       TREE_SIDE_EFFECTS (nval) |= TREE_SIDE_EFFECTS (val);
                    800:       return nval;
                    801:     }
                    802:   return val;
                    803: }
                    804: 
                    805: /* See if there is a constructor of type TYPE which will convert
                    806:    EXPR.  The reference manual seems to suggest (8.5.6) that we need
                    807:    not worry about finding constructors for base classes, then converting
                    808:    to the derived class.
                    809: 
                    810:    MSGP is a pointer to a message that would be an appropriate error
                    811:    string.  If MSGP is NULL, then we are not interested in reporting
                    812:    errors.  */
                    813: tree
                    814: convert_to_aggr (type, expr, msgp, protect)
                    815:      tree type, expr;
                    816:      char **msgp;
                    817:      int protect;
                    818: {
                    819:   tree basetype = type;
                    820:   tree name = TYPE_IDENTIFIER (basetype);
                    821:   tree function, fndecl, fntype, parmtypes, parmlist, result;
                    822:   tree method_name;
                    823:   enum visibility_type visibility;
                    824:   int can_be_private, can_be_protected;
                    825: 
                    826:   if (! TYPE_HAS_CONSTRUCTOR (basetype))
                    827:     {
                    828:       if (msgp)
                    829:        *msgp = "type `%s' does not have a constructor";
                    830:       return error_mark_node;
                    831:     }
                    832: 
                    833:   visibility = visibility_public;
                    834:   can_be_private = 0;
                    835:   can_be_protected = IDENTIFIER_CLASS_VALUE (name) || name == current_class_name;
                    836: 
                    837:   parmlist = build_tree_list (NULL_TREE, expr);
                    838:   parmtypes = tree_cons (NULL_TREE, TREE_TYPE (expr), void_list_node);
                    839: 
                    840:   if (TYPE_USES_VIRTUAL_BASECLASSES (basetype))
                    841:     {
                    842:       parmtypes = tree_cons (NULL_TREE, integer_type_node, parmtypes);
                    843:       parmlist = tree_cons (NULL_TREE, integer_one_node, parmlist);
                    844:     }
                    845: 
                    846:   /* The type of the first argument will be filled in inside the loop.  */
                    847:   parmlist = tree_cons (NULL_TREE, integer_zero_node, parmlist);
                    848:   parmtypes = tree_cons (NULL_TREE, TYPE_POINTER_TO (basetype), parmtypes);
                    849: 
                    850:   method_name = build_decl_overload (name, parmtypes, 1);
                    851: 
                    852:   /* constructors are up front.  */
                    853:   fndecl = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0);
                    854:   if (TYPE_HAS_DESTRUCTOR (basetype))
                    855:     fndecl = DECL_CHAIN (fndecl);
                    856: 
                    857:   while (fndecl)
                    858:     {
                    859:       if (DECL_ASSEMBLER_NAME (fndecl) == method_name)
                    860:        {
                    861:          function = fndecl;
                    862:          if (protect)
                    863:            {
                    864:              if (TREE_PRIVATE (fndecl))
                    865:                {
                    866:                  can_be_private =
                    867:                    (basetype == current_class_type
                    868:                     || is_friend (basetype, current_function_decl)
                    869:                     || purpose_member (basetype, DECL_VISIBILITY (fndecl)));
                    870:                  if (! can_be_private)
                    871:                    goto found;
                    872:                }
                    873:              else if (TREE_PROTECTED (fndecl))
                    874:                {
                    875:                  if (! can_be_protected)
                    876:                    goto found;
                    877:                }
                    878:            }
                    879:          goto found_and_ok;
                    880:        }
                    881:       fndecl = DECL_CHAIN (fndecl);
                    882:     }
                    883: 
                    884:   /* No exact conversion was found.  See if an approximate
                    885:      one will do.  */
                    886:   fndecl = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0);
                    887:   if (TYPE_HAS_DESTRUCTOR (basetype))
                    888:     fndecl = DECL_CHAIN (fndecl);
                    889: 
                    890:   {
                    891:     int saw_private = 0;
                    892:     int saw_protected = 0;
                    893:     struct candidate *candidates =
                    894:       (struct candidate *) alloca ((decl_list_length (fndecl)+1) * sizeof (struct candidate));
                    895:     struct candidate *cp = candidates;
                    896: 
                    897:     while (fndecl)
                    898:       {
                    899:        function = fndecl;
                    900:        if (flag_ansi_overloading)
                    901:          {
                    902:            cp->v.ansi_harshness = (struct harshness_code *)alloca (3 * sizeof (struct harshness_code));
                    903:            cp->h_len = 2;
                    904:          }
                    905:        else
                    906:          cp->v.old_harshness = (unsigned short *)alloca (3 * sizeof (short));
                    907: 
                    908:        compute_conversion_costs (fndecl, parmlist, cp, 2);
                    909:        if ((flag_ansi_overloading && (cp->h.code & EVIL_CODE) == 0)
                    910:            || (!flag_ansi_overloading && cp->evil == 0))
                    911:          {
                    912:            cp->u.field = fndecl;
                    913:            if (protect)
                    914:              {
                    915:                if (TREE_PRIVATE (fndecl))
                    916:                  visibility = visibility_private;
                    917:                else if (TREE_PROTECTED (fndecl))
                    918:                  visibility = visibility_protected;
                    919:                else
                    920:                  visibility = visibility_public;
                    921:              }
                    922:            else
                    923:              visibility = visibility_public;
                    924: 
                    925:            if (visibility == visibility_private
                    926:                ? (basetype == current_class_type
                    927:                   || is_friend (basetype, cp->function)
                    928:                   || purpose_member (basetype, DECL_VISIBILITY (fndecl)))
                    929:                : visibility == visibility_protected
                    930:                ? (can_be_protected
                    931:                   || purpose_member (basetype, DECL_VISIBILITY (fndecl)))
                    932:                : 1)
                    933:              {
                    934:                if ((flag_ansi_overloading && cp->h.code <= TRIVIAL_CODE)
                    935:                    || (!flag_ansi_overloading
                    936:                        && cp->user == 0 && cp->b_or_d == 0
                    937:                        && cp->easy <= 1))
                    938:                  goto found_and_ok;
                    939:                cp++;
                    940:              }
                    941:            else
                    942:              {
                    943:                if (visibility == visibility_private)
                    944:                  saw_private = 1;
                    945:                else
                    946:                  saw_protected = 1;
                    947:              }
                    948:          }
                    949:        fndecl = DECL_CHAIN (fndecl);
                    950:       }
                    951:     if (cp - candidates)
                    952:       {
                    953:        /* Rank from worst to best.  Then cp will point to best one.
                    954:           Private fields have their bits flipped.  For unsigned
                    955:           numbers, this should make them look very large.
                    956:           If the best alternate has a (signed) negative value,
                    957:           then all we ever saw were private members.  */
                    958:        if (cp - candidates > 1)
                    959:          qsort (candidates,    /* char *base */
                    960:                 cp - candidates, /* int nel */
                    961:                 sizeof (struct candidate), /* int width */
                    962:                 rank_for_overload); /* int (*compar)() */
                    963: 
                    964:        --cp;
                    965:        if ((flag_ansi_overloading && (cp->h.code & EVIL_CODE))
                    966:            || (!flag_ansi_overloading && cp->evil > 1))
                    967:          {
                    968:            if (msgp)
                    969:              *msgp = "ambiguous type conversion possible for `%s'";
                    970:            return error_mark_node;
                    971:          }
                    972: 
                    973:        function = cp->function;
                    974:        fndecl = cp->u.field;
                    975:        goto found_and_ok;
                    976:       }
                    977:     else if (msgp)
                    978:       {
                    979:        if (saw_private)
                    980:          if (saw_protected)
                    981:            *msgp = "only private and protected conversions apply";
                    982:          else
                    983:            *msgp = "only private conversions apply";
                    984:        else if (saw_protected)
                    985:          *msgp = "only protected conversions apply";
                    986:       }
                    987:     return error_mark_node;
                    988:   }
                    989:   /* NOTREACHED */
                    990: 
                    991:  not_found:
                    992:   if (msgp) *msgp = "no appropriate conversion to type `%s'";
                    993:   return error_mark_node;
                    994:  found:
                    995:   if (visibility == visibility_private)
                    996:     if (! can_be_private)
                    997:       {
                    998:        if (msgp)
                    999:          *msgp = TREE_PRIVATE (fndecl)
                   1000:            ? "conversion to type `%s' is private"
                   1001:            : "conversion to type `%s' is from private base class";
                   1002:        return error_mark_node;
                   1003:       }
                   1004:   if (visibility == visibility_protected)
                   1005:     if (! can_be_protected)
                   1006:       {
                   1007:        if (msgp)
                   1008:          *msgp = TREE_PRIVATE (fndecl)
                   1009:            ? "conversion to type `%s' is protected"
                   1010:            : "conversion to type `%s' is from protected base class";
                   1011:        return error_mark_node;
                   1012:       }
                   1013:   function = fndecl;
                   1014:  found_and_ok:
                   1015: 
                   1016:   /* It will convert, but we don't do anything about it yet.  */
                   1017:   if (msgp == 0)
                   1018:     return NULL_TREE;
                   1019: 
                   1020:   fntype = TREE_TYPE (function);
                   1021:   if (DECL_INLINE (function) && TREE_CODE (function) == FUNCTION_DECL)
                   1022:     function = build1 (ADDR_EXPR, build_pointer_type (fntype), function);
                   1023:   else
                   1024:     function = default_conversion (function);
                   1025: 
                   1026:   result = build_nt (CALL_EXPR, function,
                   1027:                     convert_arguments (NULL_TREE, TYPE_ARG_TYPES (fntype),
                   1028:                                        parmlist, NULL_TREE, LOOKUP_NORMAL),
                   1029:                     NULL_TREE);
                   1030:   TREE_TYPE (result) = TREE_TYPE (fntype);
                   1031:   TREE_SIDE_EFFECTS (result) = 1;
                   1032:   TREE_RAISES (result) = !! TYPE_RAISES_EXCEPTIONS (fntype);
                   1033:   return result;
                   1034: }
                   1035: 
                   1036: /* Call this when we know (for any reason) that expr is not, in fact,
                   1037:    zero.  This routine is like convert_pointer_to, but it pays
                   1038:    attention to which specific instance of what type we want to
                   1039:    convert to.  This routine should eventually become
                   1040:    convert_to_pointer after all references to convert_to_pointer
                   1041:    are removed.  */
                   1042: tree
                   1043: convert_pointer_to_real (binfo, expr)
                   1044:      tree binfo, expr;
                   1045: {
                   1046:   register tree intype = TREE_TYPE (expr);
                   1047:   tree ptr_type;
                   1048:   tree type, rval;
                   1049: 
                   1050:   if (TREE_CODE (binfo) == TREE_VEC)
                   1051:     type = BINFO_TYPE (binfo);
                   1052:   else if (IS_AGGR_TYPE (binfo))
                   1053:     {
                   1054:       type = binfo;
                   1055:     }
                   1056:   else
                   1057:     {
                   1058:       type = binfo;
                   1059:       binfo = NULL_TREE;
                   1060:     }
                   1061: 
                   1062:   ptr_type = build_pointer_type (type);
                   1063:   if (ptr_type == TYPE_MAIN_VARIANT (intype))
                   1064:     return expr;
                   1065: 
                   1066:   if (intype == error_mark_node)
                   1067:     return error_mark_node;
                   1068: 
                   1069:   my_friendly_assert (!integer_zerop (expr), 191);
                   1070: 
                   1071:   if (TREE_CODE (type) == RECORD_TYPE
                   1072:       && TREE_CODE (TREE_TYPE (intype)) == RECORD_TYPE
                   1073:       && type != TYPE_MAIN_VARIANT (TREE_TYPE (intype)))
                   1074:     {
                   1075:       tree path;
                   1076:       int distance
                   1077:        = get_base_distance (binfo, TYPE_MAIN_VARIANT (TREE_TYPE (intype)),
                   1078:                             0, &path);
                   1079: 
                   1080:       /* This function shouldn't be called with unqualified arguments
                   1081:         but if it is, give them an error message that they can read.
                   1082:         */
                   1083:       if (distance < 0)
                   1084:        {
                   1085:          error ("cannot convert a pointer of type `%s'",
                   1086:                 TYPE_NAME_STRING (TREE_TYPE (intype)));
                   1087:          cp_error ("to a pointer of type `%T'", type);
                   1088: 
                   1089:          if (distance == -2)
                   1090:            cp_error ("because `%T' is an ambiguous base class", type);
                   1091:          return error_mark_node;
                   1092:        }
                   1093: 
                   1094:       return build_vbase_path (PLUS_EXPR, ptr_type, expr, path, 1);
                   1095:     }
                   1096:   rval = build1 (NOP_EXPR, ptr_type,
                   1097:                 TREE_CODE (expr) == NOP_EXPR ? TREE_OPERAND (expr, 0) : expr);
                   1098:   TREE_CONSTANT (rval) = TREE_CONSTANT (expr);
                   1099:   return rval;
                   1100: }
                   1101: 
                   1102: /* Call this when we know (for any reason) that expr is
                   1103:    not, in fact, zero.  This routine gets a type out of the first
                   1104:    argument and uses it to search for the type to convert to.  If there
                   1105:    is more than one instance of that type in the expr, the conversion is
                   1106:    ambiguous.  This routine should eventually go away, and all
                   1107:    callers should use convert_to_pointer_real.  */
                   1108: tree
                   1109: convert_pointer_to (binfo, expr)
                   1110:      tree binfo, expr;
                   1111: {
                   1112:   tree type;
                   1113: 
                   1114:   if (TREE_CODE (binfo) == TREE_VEC)
                   1115:     type = BINFO_TYPE (binfo);
                   1116:   else if (IS_AGGR_TYPE (binfo))
                   1117:       type = binfo;
                   1118:   else
                   1119:       type = binfo;
                   1120:   return convert_pointer_to_real (type, expr);
                   1121: }
                   1122: 
                   1123: /* Same as above, but don't abort if we get an "ambiguous" baseclass.
                   1124:    There's only one virtual baseclass we are looking for, and once
                   1125:    we find one such virtual baseclass, we have found them all.  */
                   1126: 
                   1127: tree
                   1128: convert_pointer_to_vbase (binfo, expr)
                   1129:      tree binfo;
                   1130:      tree expr;
                   1131: {
                   1132:   tree intype = TREE_TYPE (TREE_TYPE (expr));
                   1133:   tree binfos = TYPE_BINFO_BASETYPES (intype);
                   1134:   int i;
                   1135: 
                   1136:   for (i = TREE_VEC_LENGTH (binfos)-1; i >= 0; i--)
                   1137:     {
                   1138:       tree basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, i));
                   1139:       if (BINFO_TYPE (binfo) == basetype)
                   1140:        return convert_pointer_to (binfo, expr);
                   1141:       if (binfo_member (BINFO_TYPE (binfo), CLASSTYPE_VBASECLASSES (basetype)))
                   1142:        return convert_pointer_to_vbase (binfo, convert_pointer_to (basetype, expr));
                   1143:     }
                   1144:   my_friendly_abort (6);
                   1145:   /* NOTREACHED */
                   1146:   return NULL_TREE;
                   1147: }
                   1148: 
                   1149: /* Create an expression whose value is that of EXPR,
                   1150:    converted to type TYPE.  The TREE_TYPE of the value
                   1151:    is always TYPE.  This function implements all reasonable
                   1152:    conversions; callers should filter out those that are
                   1153:    not permitted by the language being compiled.  */
                   1154: 
                   1155: tree
                   1156: convert (type, expr)
                   1157:      tree type, expr;
                   1158: {
                   1159:   register tree e = expr;
                   1160:   register enum tree_code code = TREE_CODE (type);
                   1161: 
                   1162:   if (type == TREE_TYPE (expr)
                   1163:       || TREE_CODE (expr) == ERROR_MARK)
                   1164:     return expr;
                   1165:   if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))
                   1166:     return fold (build1 (NOP_EXPR, type, expr));
                   1167:   if (TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK)
                   1168:     return error_mark_node;
                   1169:   if (TREE_CODE (TREE_TYPE (expr)) == VOID_TYPE)
                   1170:     {
                   1171:       error ("void value not ignored as it ought to be");
                   1172:       return error_mark_node;
                   1173:     }
                   1174:   if (code == VOID_TYPE)
                   1175:     {
                   1176:       /* We're converting to a void type; see if they have an
                   1177:         `operator void'.  */
                   1178:       tree rval = build_type_conversion (NOP_EXPR, type, e, 0);
                   1179:       /* If we can convert to void type via a type conversion, do so.  */
                   1180:       if (rval)
                   1181:        return rval;
                   1182:       return build1 (CONVERT_EXPR, type, e);
                   1183:     }
                   1184: #if 0
                   1185:   /* This is incorrect.  A truncation can't be stripped this way.
                   1186:      Extensions will be stripped by the use of get_unwidened.  */
                   1187:   if (TREE_CODE (expr) == NOP_EXPR)
                   1188:     return convert (type, TREE_OPERAND (expr, 0));
                   1189: #endif
                   1190: 
                   1191:   /* Just convert to the type of the member.  */
                   1192:   if (code == OFFSET_TYPE)
                   1193:     {
                   1194:       type = TREE_TYPE (type);
                   1195:       code = TREE_CODE (type);
                   1196:     }
                   1197: 
                   1198:   /* C++ */
                   1199:   if (code == REFERENCE_TYPE)
                   1200:     return fold (convert_to_reference (error_mark_node,
                   1201:                                       type, e,
                   1202:                                       NULL_TREE, -1, (char *)NULL,
                   1203:                                       -1, LOOKUP_NORMAL));
                   1204:   else if (TREE_CODE (TREE_TYPE (e)) == REFERENCE_TYPE)
                   1205:     e = convert_from_reference (e);
                   1206: 
                   1207:   if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
                   1208:     {
                   1209:       tree intype = TREE_TYPE (expr);
                   1210:       enum tree_code form = TREE_CODE (intype);
                   1211:       if (flag_int_enum_equivalence == 0
                   1212:          && TREE_CODE (type) == ENUMERAL_TYPE
                   1213:          && form == INTEGER_TYPE)
                   1214:        {
                   1215:          cp_pedwarn ("anachronistic conversion from `int' to `%#T'", type);
                   1216: 
                   1217:          if (flag_pedantic_errors)
                   1218:            return error_mark_node;
                   1219:        }
                   1220:       if (form == OFFSET_TYPE)
                   1221:        cp_error_at ("pointer-to-member expression object not composed with type `%D' object",
                   1222:                     TYPE_NAME (TYPE_OFFSET_BASETYPE (intype)));
                   1223:       else if (IS_AGGR_TYPE (intype))
                   1224:        {
                   1225:          tree rval;
                   1226:          rval = build_type_conversion (CONVERT_EXPR, type, expr, 1);
                   1227:          if (rval) return rval;
                   1228:          cp_error ("`%#T' used where an `int' was expected", intype);
                   1229:          return error_mark_node;
                   1230:        }
                   1231:       return fold (convert_to_integer (type, e));
                   1232:     }
                   1233:   if (code == POINTER_TYPE)
                   1234:     return fold (cp_convert_to_pointer (type, e));
                   1235:   if (code == REAL_TYPE)
                   1236:     {
                   1237:       if (IS_AGGR_TYPE (TREE_TYPE (e)))
                   1238:        {
                   1239:          tree rval;
                   1240:          rval = build_type_conversion (CONVERT_EXPR, type, e, 1);
                   1241:          if (rval)
                   1242:            return rval;
                   1243:          else
                   1244:            cp_error ("`%#T' used where a floating point value was expected",
                   1245:                      TREE_TYPE (e));
                   1246:        }
                   1247:       return fold (convert_to_real (type, e));
                   1248:     }
                   1249: 
                   1250:   /* New C++ semantics:  since assignment is now based on
                   1251:      memberwise copying,  if the rhs type is derived from the
                   1252:      lhs type, then we may still do a conversion.  */
                   1253:   if (IS_AGGR_TYPE_CODE (code))
                   1254:     {
                   1255:       tree dtype = TREE_TYPE (e);
                   1256: 
                   1257:       if (TREE_CODE (dtype) == REFERENCE_TYPE)
                   1258:        {
                   1259:          e = convert_from_reference (e);
                   1260:          dtype = TREE_TYPE (e);
                   1261:        }
                   1262:       dtype = TYPE_MAIN_VARIANT (dtype);
                   1263: 
                   1264:       /* Conversion between aggregate types.  New C++ semantics allow
                   1265:         objects of derived type to be cast to objects of base type.
                   1266:         Old semantics only allowed this between pointers.
                   1267: 
                   1268:         There may be some ambiguity between using a constructor
                   1269:         vs. using a type conversion operator when both apply.  */
                   1270: 
                   1271:       if (IS_AGGR_TYPE (dtype))
                   1272:        {
                   1273:          tree binfo;
                   1274: 
                   1275:          tree conversion = TYPE_HAS_CONVERSION (dtype)
                   1276:            ? build_type_conversion (CONVERT_EXPR, type, e, 1) : NULL_TREE;
                   1277: 
                   1278:          if (TYPE_HAS_CONSTRUCTOR (type))
                   1279:            {
                   1280:              tree rval = build_method_call (NULL_TREE, constructor_name_full (type),
                   1281:                                             build_tree_list (NULL_TREE, e),
                   1282:                                             TYPE_BINFO (type),
                   1283:                                             conversion ? LOOKUP_NO_CONVERSION : 0);
                   1284: 
                   1285:              if (rval != error_mark_node)
                   1286:                {
                   1287:                  if (conversion)
                   1288:                    {
                   1289:                      error ("both constructor and type conversion operator apply");
                   1290:                      return error_mark_node;
                   1291:                    }
                   1292:                  /* call to constructor successful.  */
                   1293:                  rval = build_cplus_new (type, rval, 0);
                   1294:                  return rval;
                   1295:                }
                   1296:            }
                   1297:          /* Type conversion successful/applies.  */
                   1298:          if (conversion)
                   1299:            {
                   1300:              if (conversion == error_mark_node)
                   1301:                error ("ambiguous pointer conversion");
                   1302:              return conversion;
                   1303:            }
                   1304: 
                   1305:          /* now try normal C++ assignment semantics.  */
                   1306:          binfo = TYPE_BINFO (dtype);
                   1307:          if (BINFO_TYPE (binfo) == type
                   1308:              || (binfo = get_binfo (type, dtype, 1)))
                   1309:            {
                   1310:              if (binfo == error_mark_node)
                   1311:                return error_mark_node;
                   1312:            }
                   1313:          if (binfo != NULL_TREE)
                   1314:            {
                   1315:              if (lvalue_p (e))
                   1316:                {
                   1317:                  e = build_unary_op (ADDR_EXPR, e, 0);
                   1318: 
                   1319:                  if (! BINFO_OFFSET_ZEROP (binfo))
                   1320:                    e = build (PLUS_EXPR, TYPE_POINTER_TO (type),
                   1321:                               e, BINFO_OFFSET (binfo));
                   1322:                  return build1 (INDIRECT_REF, type, e);
                   1323:                }
                   1324: 
                   1325:              sorry ("addressable aggregates");
                   1326:              return error_mark_node;
                   1327:            }
                   1328:          error ("conversion between incompatible aggregate types requested");
                   1329:          return error_mark_node;
                   1330:        }
                   1331:       /* conversion from non-aggregate to aggregate type requires constructor.  */
                   1332:       else if (TYPE_HAS_CONSTRUCTOR (type))
                   1333:        {
                   1334:          tree rval;
                   1335:          tree init = build_method_call (NULL_TREE, constructor_name_full (type),
                   1336:                                         build_tree_list (NULL_TREE, e),
                   1337:                                         TYPE_BINFO (type), LOOKUP_NORMAL);
                   1338:          if (init == error_mark_node)
                   1339:            {
                   1340:              cp_error ("in conversion to type `%T'", type);
                   1341:              return error_mark_node;
                   1342:            }
                   1343:          rval = build_cplus_new (type, init, 0);
                   1344:          return rval;
                   1345:        }
                   1346:     }
                   1347: 
                   1348:   /* If TYPE or TREE_TYPE (EXPR) is not on the permanent_obstack,
                   1349:      then the it won't be hashed and hence compare as not equal,
                   1350:      even when it is.  */
                   1351:   if (code == ARRAY_TYPE
                   1352:       && TREE_TYPE (TREE_TYPE (expr)) == TREE_TYPE (type)
                   1353:       && index_type_equal (TYPE_DOMAIN (TREE_TYPE (expr)), TYPE_DOMAIN (type)))
                   1354:     return expr;
                   1355: 
                   1356:   error ("conversion to non-scalar type requested");
                   1357:   return error_mark_node;
                   1358: }
                   1359: 
                   1360: /* Like convert, except permit conversions to take place which
                   1361:    are not normally allowed due to visibility restrictions
                   1362:    (such as conversion from sub-type to private super-type).  */
                   1363: tree
                   1364: convert_force (type, expr)
                   1365:      tree type;
                   1366:      tree expr;
                   1367: {
                   1368:   register tree e = expr;
                   1369:   register enum tree_code code = TREE_CODE (type);
                   1370: 
                   1371:   if (code == REFERENCE_TYPE)
                   1372:     return fold (convert_to_reference (0, type, e,
                   1373:                                       NULL_TREE, -1, (char *)NULL,
                   1374:                                       -1, 0));
                   1375:   else if (TREE_CODE (TREE_TYPE (e)) == REFERENCE_TYPE)
                   1376:     e = convert_from_reference (e);
                   1377: 
                   1378:   if (code == POINTER_TYPE)
                   1379:     return fold (convert_to_pointer_force (type, e));
                   1380: 
                   1381:   {
                   1382:     int old_equiv = flag_int_enum_equivalence;
                   1383:     flag_int_enum_equivalence = 1;
                   1384:     e = convert (type, e);
                   1385:     flag_int_enum_equivalence = old_equiv;
                   1386:   }
                   1387:   return e;
                   1388: }
                   1389: 
                   1390: /* Subroutine of build_type_conversion.  */
                   1391: static tree
                   1392: build_type_conversion_1 (xtype, basetype, expr, typename, for_sure)
                   1393:      tree xtype, basetype;
                   1394:      tree expr;
                   1395:      tree typename;
                   1396:      int for_sure;
                   1397: {
                   1398:   tree first_arg = expr;
                   1399:   tree rval;
                   1400:   int flags;
                   1401: 
                   1402:   if (for_sure == 0)
                   1403:     {
                   1404:       if (! lvalue_p (expr))
                   1405:        first_arg = build1 (NOP_EXPR, TYPE_POINTER_TO (basetype), integer_zero_node);
                   1406:       flags = LOOKUP_PROTECT;
                   1407:     }
                   1408:   else
                   1409:     flags = LOOKUP_NORMAL;
                   1410: 
                   1411:   rval = build_method_call (first_arg, constructor_name_full (typename),
                   1412:                            NULL_TREE, NULL_TREE, flags);
                   1413:   if (rval == error_mark_node)
                   1414:     {
                   1415:       if (for_sure == 0)
                   1416:        return NULL_TREE;
                   1417:       return error_mark_node;
                   1418:     }
                   1419:   if (first_arg != expr)
                   1420:     {
                   1421:       expr = build_up_reference (build_reference_type (TREE_TYPE (expr)), expr,
                   1422:                                 LOOKUP_COMPLAIN, 1);
                   1423:       TREE_VALUE (TREE_OPERAND (rval, 1)) = build_unary_op (ADDR_EXPR, expr, 0);
                   1424:     }
                   1425:   if (TREE_CODE (TREE_TYPE (rval)) == REFERENCE_TYPE
                   1426:       && TREE_CODE (xtype) != REFERENCE_TYPE)
                   1427:     rval = default_conversion (rval);
                   1428: 
                   1429:   if (pedantic
                   1430:       && TREE_TYPE (xtype)
                   1431:       && (TREE_READONLY (TREE_TYPE (TREE_TYPE (rval)))
                   1432:          > TREE_READONLY (TREE_TYPE (xtype))))
                   1433:     pedwarn ("user-defined conversion casting away `const'");
                   1434:   return convert (xtype, rval);
                   1435: }
                   1436: 
                   1437: /* Convert an aggregate EXPR to type XTYPE.  If a conversion
                   1438:    exists, return the attempted conversion.  This may
                   1439:    return ERROR_MARK_NODE if the conversion is not
                   1440:    allowed (references private members, etc).
                   1441:    If no conversion exists, NULL_TREE is returned.
                   1442: 
                   1443:    If (FOR_SURE & 1) is non-zero, then we allow this type conversion
                   1444:    to take place immediately.  Otherwise, we build a SAVE_EXPR
                   1445:    which can be evaluated if the results are ever needed.
                   1446: 
                   1447:    If FOR_SURE >= 2, then we only look for exact conversions.
                   1448: 
                   1449:    TYPE may be a reference type, in which case we first look
                   1450:    for something that will convert to a reference type.  If
                   1451:    that fails, we will try to look for something of the
                   1452:    reference's target type, and then return a reference to that.  */
                   1453: tree
                   1454: build_type_conversion (code, xtype, expr, for_sure)
                   1455:      enum tree_code code;
                   1456:      tree xtype, expr;
                   1457:      int for_sure;
                   1458: {
                   1459:   /* C++: check to see if we can convert this aggregate type
                   1460:      into the required scalar type.  */
                   1461:   tree type, type_default;
                   1462:   tree typename = build_typename_overload (xtype), *typenames;
                   1463:   int n_variants = 0;
                   1464:   tree basetype, save_basetype;
                   1465:   tree rval;
                   1466:   int exact_conversion = for_sure >= 2;
                   1467:   for_sure &= 1;
                   1468: 
                   1469:   if (expr == error_mark_node)
                   1470:     return error_mark_node;
                   1471: 
                   1472:   basetype = TREE_TYPE (expr);
                   1473:   if (TREE_CODE (basetype) == REFERENCE_TYPE)
                   1474:     basetype = TREE_TYPE (basetype);
                   1475: 
                   1476:   basetype = TYPE_MAIN_VARIANT (basetype);
                   1477:   if (! TYPE_LANG_SPECIFIC (basetype) || ! TYPE_HAS_CONVERSION (basetype))
                   1478:     return NULL_TREE;
                   1479: 
                   1480:   if (TREE_CODE (xtype) == POINTER_TYPE
                   1481:       || TREE_CODE (xtype) == REFERENCE_TYPE)
                   1482:     {
                   1483:       /* Prepare to match a variant of this type.  */
                   1484:       type = TYPE_MAIN_VARIANT (TREE_TYPE (xtype));
                   1485:       for (n_variants = 0; type; type = TYPE_NEXT_VARIANT (type))
                   1486:        n_variants++;
                   1487:       typenames = (tree *)alloca (n_variants * sizeof (tree));
                   1488:       for (n_variants = 0, type = TYPE_MAIN_VARIANT (TREE_TYPE (xtype));
                   1489:           type; n_variants++, type = TYPE_NEXT_VARIANT (type))
                   1490:        {
                   1491:          if (type == TREE_TYPE (xtype))
                   1492:            typenames[n_variants] = typename;
                   1493:          else if (TREE_CODE (xtype) == POINTER_TYPE)
                   1494:            typenames[n_variants] = build_typename_overload (build_pointer_type (type));
                   1495:          else
                   1496:            typenames[n_variants] = build_typename_overload (build_reference_type (type));
                   1497:        }
                   1498:     }
                   1499: 
                   1500:   save_basetype = basetype;
                   1501:   type = xtype;
                   1502: 
                   1503:   while (TYPE_HAS_CONVERSION (basetype))
                   1504:     {
                   1505:       int i;
                   1506:       if (lookup_fnfields (TYPE_BINFO (basetype), typename, 0))
                   1507:        return build_type_conversion_1 (xtype, basetype, expr, typename, for_sure);
                   1508:       for (i = 0; i < n_variants; i++)
                   1509:        if (typenames[i] != typename
                   1510:            && lookup_fnfields (TYPE_BINFO (basetype), typenames[i], 0))
                   1511:          return build_type_conversion_1 (xtype, basetype, expr, typenames[i], for_sure);
                   1512: 
                   1513:       if (TYPE_BINFO_BASETYPES (basetype))
                   1514:        basetype = TYPE_BINFO_BASETYPE (basetype, 0);
                   1515:       else
                   1516:        break;
                   1517:     }
                   1518: 
                   1519:   if (TREE_CODE (type) == REFERENCE_TYPE)
                   1520:     {
                   1521:       tree first_arg = expr;
                   1522:       type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
                   1523:       basetype = save_basetype;
                   1524: 
                   1525:       /* May need to build a temporary for this.  */
                   1526:       while (TYPE_HAS_CONVERSION (basetype))
                   1527:        {
                   1528:          if (lookup_fnfields (TYPE_BINFO (basetype), typename, 0))
                   1529:            {
                   1530:              int flags;
                   1531: 
                   1532:              if (for_sure == 0)
                   1533:                {
                   1534:                  if (! lvalue_p (expr))
                   1535:                    first_arg = build1 (NOP_EXPR, TYPE_POINTER_TO (basetype), integer_zero_node);
                   1536:                  flags = LOOKUP_PROTECT;
                   1537:                }
                   1538:              else
                   1539:                flags = LOOKUP_NORMAL;
                   1540:              rval = build_method_call (first_arg, constructor_name_full (typename),
                   1541:                                        NULL_TREE, NULL_TREE, flags);
                   1542:              if (rval == error_mark_node)
                   1543:                {
                   1544:                  if (for_sure == 0)
                   1545:                    return NULL_TREE;
                   1546:                  return error_mark_node;
                   1547:                }
                   1548:              TREE_VALUE (TREE_OPERAND (rval, 1)) = expr;
                   1549: 
                   1550:              if (IS_AGGR_TYPE (type))
                   1551:                {
                   1552:                  tree init = build_method_call (NULL_TREE,
                   1553:                                                 constructor_name_full (type),
                   1554:                                                 build_tree_list (NULL_TREE, rval), NULL_TREE, LOOKUP_NORMAL);
                   1555:                  tree temp = build_cplus_new (type, init, 1);
                   1556:                  return build_up_reference (TYPE_REFERENCE_TO (type), temp,
                   1557:                                             LOOKUP_COMPLAIN, 1);
                   1558:                }
                   1559:              return convert (xtype, rval);
                   1560:            }
                   1561:          if (TYPE_BINFO_BASETYPES (basetype))
                   1562:            basetype = TYPE_BINFO_BASETYPE (basetype, 0);
                   1563:          else
                   1564:            break;
                   1565:        }
                   1566:       /* No free conversions for reference types, right?.  */
                   1567:       return NULL_TREE;
                   1568:     }
                   1569: 
                   1570:   if (exact_conversion)
                   1571:     return NULL_TREE;
                   1572: 
                   1573:   /* No perfect match found, try default.  */
                   1574:   if (code == CONVERT_EXPR && TREE_CODE (type) == POINTER_TYPE)
                   1575:     type_default = ptr_type_node;
                   1576:   else if (type == void_type_node)
                   1577:     return NULL_TREE;
                   1578:   else
                   1579:     {
                   1580:       tree tmp = default_conversion (build1 (NOP_EXPR, type, integer_zero_node));
                   1581:       if (tmp == error_mark_node)
                   1582:        return NULL_TREE;
                   1583:       type_default = TREE_TYPE (tmp);
                   1584:     }
                   1585: 
                   1586:   basetype = save_basetype;
                   1587: 
                   1588:   if (type_default != type)
                   1589:     {
                   1590:       type = type_default;
                   1591:       typename = build_typename_overload (type);
                   1592: 
                   1593:       while (TYPE_HAS_CONVERSION (basetype))
                   1594:        {
                   1595:          if (lookup_fnfields (TYPE_BINFO (basetype), typename, 0))
                   1596:            return build_type_conversion_1 (xtype, basetype, expr, typename, for_sure);
                   1597:          if (TYPE_BINFO_BASETYPES (basetype))
                   1598:            basetype = TYPE_BINFO_BASETYPE (basetype, 0);
                   1599:          else
                   1600:            break;
                   1601:        }
                   1602:     }
                   1603: 
                   1604:  try_pointer:
                   1605: 
                   1606:   if (type == ptr_type_node)
                   1607:     {
                   1608:       /* Try converting to some other pointer type
                   1609:         with which void* is compatible, or in situations
                   1610:         in which void* is appropriate (such as &&,||, and !).  */
                   1611: 
                   1612:       while (TYPE_HAS_CONVERSION (basetype))
                   1613:        {
                   1614:          if (CLASSTYPE_CONVERSION (basetype, ptr_conv) != 0)
                   1615:            {
                   1616:              if (CLASSTYPE_CONVERSION (basetype, ptr_conv) == error_mark_node)
                   1617:                return error_mark_node;
                   1618:              typename = DECL_NAME (CLASSTYPE_CONVERSION (basetype, ptr_conv));
                   1619:              return build_type_conversion_1 (xtype, basetype, expr, typename, for_sure);
                   1620:            }
                   1621:          if (TYPE_BINFO_BASETYPES (basetype))
                   1622:            basetype = TYPE_BINFO_BASETYPE (basetype, 0);
                   1623:          else
                   1624:            break;
                   1625:        }
                   1626:     }
                   1627:   if (TREE_CODE (type) == POINTER_TYPE
                   1628:       && TYPE_READONLY (TREE_TYPE (type))
                   1629:       && TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node)
                   1630:     {
                   1631:       /* Try converting to some other pointer type
                   1632:         with which const void* is compatible.  */
                   1633: 
                   1634:       while (TYPE_HAS_CONVERSION (basetype))
                   1635:        {
                   1636:          if (CLASSTYPE_CONVERSION (basetype, constptr_conv) != 0)
                   1637:            {
                   1638:              if (CLASSTYPE_CONVERSION (basetype, constptr_conv) == error_mark_node)
                   1639:                return error_mark_node;
                   1640:              typename = DECL_NAME (CLASSTYPE_CONVERSION (basetype, constptr_conv));
                   1641:              return build_type_conversion_1 (xtype, basetype, expr, typename, for_sure);
                   1642:            }
                   1643:          if (TYPE_BINFO_BASETYPES (basetype))
                   1644:            basetype = TYPE_BINFO_BASETYPE (basetype, 0);
                   1645:          else
                   1646:            break;
                   1647:        }
                   1648:     }
                   1649:   /* Use the longer or shorter conversion that is appropriate.  Have
                   1650:      to check against 0 because the conversion may come from a baseclass.  */
                   1651:   if (TREE_CODE (type) == INTEGER_TYPE
                   1652:       && TYPE_HAS_INT_CONVERSION (basetype)
                   1653:       && CLASSTYPE_CONVERSION (basetype, int_conv) != 0
                   1654:       && CLASSTYPE_CONVERSION (basetype, int_conv) != error_mark_node)
                   1655:     {
                   1656:       typename = DECL_NAME (CLASSTYPE_CONVERSION (basetype, int_conv));
                   1657:       return build_type_conversion_1 (xtype, basetype, expr, typename, for_sure);
                   1658:     }
                   1659: 
                   1660:   if (TREE_CODE (type) == REAL_TYPE
                   1661:       && TYPE_HAS_REAL_CONVERSION (basetype)
                   1662:       && CLASSTYPE_CONVERSION (basetype, real_conv) != 0
                   1663:       && CLASSTYPE_CONVERSION (basetype, real_conv) != error_mark_node)
                   1664:     {
                   1665:       /* Only accept using an operator double() if there isn't a conflicting
                   1666:         operator int().  */
                   1667:       if (flag_ansi_overloading && TYPE_HAS_INT_CONVERSION (basetype))
                   1668:        {
                   1669:          error ("two possible conversions for type `%s'",
                   1670:                 TYPE_NAME_STRING (type));
                   1671:          return error_mark_node;
                   1672:        }
                   1673: 
                   1674:       typename = DECL_NAME (CLASSTYPE_CONVERSION (basetype, real_conv));
                   1675:       return build_type_conversion_1 (xtype, basetype, expr, typename, for_sure);
                   1676:     }
                   1677: 
                   1678:   /* THIS IS A KLUDGE.  */
                   1679:   if (TREE_CODE (type) != POINTER_TYPE
                   1680:       && (code == TRUTH_ANDIF_EXPR
                   1681:          || code == TRUTH_ORIF_EXPR
                   1682:          || code == TRUTH_NOT_EXPR))
                   1683:     {
                   1684:       /* Here's when we can convert to a pointer.  */
                   1685:       type = ptr_type_node;
                   1686:       goto try_pointer;
                   1687:     }
                   1688: 
                   1689:   /* THESE ARE TOTAL KLUDGES.  */
                   1690:   /* Default promotion yields no new alternatives, try
                   1691:      conversions which are anti-default, such as
                   1692: 
                   1693:      double -> float or int -> unsigned or unsigned -> long
                   1694: 
                   1695:      */
                   1696:   if (type_default == type
                   1697:       && (TREE_CODE (type) == INTEGER_TYPE || TREE_CODE (type) == REAL_TYPE))
                   1698:     {
                   1699:       int not_again = 0;
                   1700: 
                   1701:       if (type == double_type_node)
                   1702:        typename = build_typename_overload (float_type_node);
                   1703:       else if (type == integer_type_node)
                   1704:        typename = build_typename_overload (unsigned_type_node);
                   1705:       else if (type == unsigned_type_node)
                   1706:        typename = build_typename_overload (long_integer_type_node);
                   1707: 
                   1708:     again:
                   1709:       basetype = save_basetype;
                   1710:       while (TYPE_HAS_CONVERSION (basetype))
                   1711:        {
                   1712:          if (lookup_fnfields (TYPE_BINFO (basetype), typename, 0))
                   1713:            return build_type_conversion_1 (xtype, basetype, expr, typename, for_sure);
                   1714:          if (TYPE_BINFO_BASETYPES (basetype))
                   1715:            basetype = TYPE_BINFO_BASETYPE (basetype, 0);
                   1716:          else
                   1717:            break;
                   1718:        }
                   1719:       if (! not_again)
                   1720:        {
                   1721:          if (type == integer_type_node)
                   1722:            {
                   1723:              typename = build_typename_overload (long_integer_type_node);
                   1724:              not_again = 1;
                   1725:              goto again;
                   1726:            }
                   1727:          else
                   1728:            {
                   1729:              typename = build_typename_overload (integer_type_node);
                   1730:              not_again = 1;
                   1731:              goto again;
                   1732:            }
                   1733:        }
                   1734:     }
                   1735: 
                   1736:   /* Now, try C promotions...
                   1737: 
                   1738:      float -> int
                   1739:      int -> float, void *
                   1740:      void * -> int
                   1741: 
                   1742:      Truthvalue conversions let us try to convert
                   1743:      to pointer if we were going for int, and to int
                   1744:      if we were looking for pointer.  */
                   1745: 
                   1746:     basetype = save_basetype;
                   1747:     if (TREE_CODE (type) == REAL_TYPE
                   1748:        || (TREE_CODE (type) == POINTER_TYPE
                   1749:            && (code == TRUTH_ANDIF_EXPR
                   1750:                || code == TRUTH_ORIF_EXPR
                   1751:                || code == TRUTH_NOT_EXPR)))
                   1752:       type = integer_type_node;
                   1753:     else if (TREE_CODE (type) == INTEGER_TYPE)
                   1754:       if (TYPE_HAS_REAL_CONVERSION (basetype))
                   1755:        type = double_type_node;
                   1756:       else
                   1757:        return NULL_TREE;
                   1758:     else
                   1759:       return NULL_TREE;
                   1760: 
                   1761:     typename = build_typename_overload (type);
                   1762:     while (TYPE_HAS_CONVERSION (basetype))
                   1763:       {
                   1764:        if (lookup_fnfields (TYPE_BINFO (basetype), typename, 0))
                   1765:          {
                   1766:            rval = build_type_conversion_1 (xtype, basetype, expr, typename, for_sure);
                   1767:            return rval;
                   1768:          }
                   1769:        if (TYPE_BINFO_BASETYPES (basetype))
                   1770:          basetype = TYPE_BINFO_BASETYPE (basetype, 0);
                   1771:        else
                   1772:          break;
                   1773:       }
                   1774: 
                   1775:   return NULL_TREE;
                   1776: }
                   1777: 
                   1778: /* Must convert two aggregate types to non-aggregate type.
                   1779:    Attempts to find a non-ambiguous, "best" type conversion.
                   1780: 
                   1781:    Return 1 on success, 0 on failure.
                   1782: 
                   1783:    @@ What are the real semantics of this supposed to be??? */
                   1784: int
                   1785: build_default_binary_type_conversion (code, arg1, arg2)
                   1786:      enum tree_code code;
                   1787:      tree *arg1, *arg2;
                   1788: {
                   1789:   tree type1 = TREE_TYPE (*arg1);
                   1790:   tree type2 = TREE_TYPE (*arg2);
                   1791:   char *name1, *name2;
                   1792: 
                   1793:   if (TREE_CODE (type1) == REFERENCE_TYPE
                   1794:       || TREE_CODE (type1) == POINTER_TYPE)
                   1795:     type1 = TREE_TYPE (type1);
                   1796:   if (TREE_CODE (type2) == REFERENCE_TYPE
                   1797:       || TREE_CODE (type2) == POINTER_TYPE)
                   1798:     type2 = TREE_TYPE (type2);
                   1799: 
                   1800:   if (TREE_CODE (TYPE_NAME (type1)) != TYPE_DECL)
                   1801:     {
                   1802:       tree decl = typedecl_for_tag (type1);
                   1803:       if (decl)
                   1804:        error ("type conversion nonexistent for type `%s'",
                   1805:               IDENTIFIER_POINTER (DECL_NAME (decl)));
                   1806:       else
                   1807:        error ("type conversion nonexistent for non-C++ type");
                   1808:       return 0;
                   1809:     }
                   1810:   if (TREE_CODE (TYPE_NAME (type2)) != TYPE_DECL)
                   1811:     {
                   1812:       tree decl = typedecl_for_tag (type2);
                   1813:       if (decl)
                   1814:        error ("type conversion nonexistent for type `%s'",
                   1815:               IDENTIFIER_POINTER (decl));
                   1816:       else
                   1817:        error ("type conversion nonexistent for non-C++ type");
                   1818:       return 0;
                   1819:     }
                   1820: 
                   1821:   name1 = TYPE_NAME_STRING (type1);
                   1822:   name2 = TYPE_NAME_STRING (type2);
                   1823: 
                   1824:   if (!IS_AGGR_TYPE (type1) || !TYPE_HAS_CONVERSION (type1))
                   1825:     {
                   1826:       if (!IS_AGGR_TYPE (type2) || !TYPE_HAS_CONVERSION (type2))
                   1827:        error ("type conversion required for binary operation on types `%s' and `%s'",
                   1828:               name1, name2);
                   1829:       else
                   1830:        error ("type conversion required for type `%s'", name1);
                   1831:       return 0;
                   1832:     }
                   1833:   else if (!IS_AGGR_TYPE (type2) || !TYPE_HAS_CONVERSION (type2))
                   1834:     {
                   1835:       error ("type conversion required for type `%s'", name2);
                   1836:       return 0;
                   1837:     }
                   1838: 
                   1839:   if (TYPE_HAS_INT_CONVERSION (type1) && TYPE_HAS_REAL_CONVERSION (type1))
                   1840:     warning ("ambiguous type conversion for type `%s', defaulting to int", name1);
                   1841:   if (TYPE_HAS_INT_CONVERSION (type1))
                   1842:     {
                   1843:       *arg1 = build_type_conversion (code, integer_type_node, *arg1, 1);
                   1844:       *arg2 = build_type_conversion (code, integer_type_node, *arg2, 1);
                   1845:     }
                   1846:   else if (TYPE_HAS_REAL_CONVERSION (type1))
                   1847:     {
                   1848:       *arg1 = build_type_conversion (code, double_type_node, *arg1, 1);
                   1849:       *arg2 = build_type_conversion (code, double_type_node, *arg2, 1);
                   1850:     }
                   1851:   else
                   1852:     {
                   1853:       *arg1 = build_type_conversion (code, ptr_type_node, *arg1, 1);
                   1854:       if (*arg1 == error_mark_node)
                   1855:        error ("ambiguous pointer conversion");
                   1856:       *arg2 = build_type_conversion (code, ptr_type_node, *arg2, 1);
                   1857:       if (*arg1 != error_mark_node && *arg2 == error_mark_node)
                   1858:        error ("ambiguous pointer conversion");
                   1859:     }
                   1860:   if (*arg1 == 0)
                   1861:     {
                   1862:       if (*arg2 == 0 && type1 != type2)
                   1863:        error ("default type conversion for types `%s' and `%s' failed",
                   1864:               name1, name2);
                   1865:       else
                   1866:        error ("default type conversion for type `%s' failed", name1);
                   1867:       return 0;
                   1868:     }
                   1869:   else if (*arg2 == 0)
                   1870:     {
                   1871:       error ("default type conversion for type `%s' failed", name2);
                   1872:       return 0;
                   1873:     }
                   1874:   return 1;
                   1875: }
                   1876: 
                   1877: /* Must convert two aggregate types to non-aggregate type.
                   1878:    Attempts to find a non-ambiguous, "best" type conversion.
                   1879: 
                   1880:    Return 1 on success, 0 on failure.
                   1881: 
                   1882:    The type of the argument is expected to be of aggregate type here.
                   1883: 
                   1884:    @@ What are the real semantics of this supposed to be??? */
                   1885: int
                   1886: build_default_unary_type_conversion (code, arg)
                   1887:      enum tree_code code;
                   1888:      tree *arg;
                   1889: {
                   1890:   tree type = TREE_TYPE (*arg);
                   1891:   tree id = TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
                   1892:     ? TYPE_IDENTIFIER (type) : TYPE_NAME (type);
                   1893:   char *name = IDENTIFIER_POINTER (id);
                   1894: 
                   1895:   if (! TYPE_HAS_CONVERSION (type))
                   1896:     {
                   1897:       error ("type conversion required for type `%s'", name);
                   1898:       return 0;
                   1899:     }
                   1900: 
                   1901:   if (TYPE_HAS_INT_CONVERSION (type) && TYPE_HAS_REAL_CONVERSION (type))
                   1902:     warning ("ambiguous type conversion for type `%s', defaulting to int",
                   1903:             name);
                   1904:   if (TYPE_HAS_INT_CONVERSION (type))
                   1905:     *arg = build_type_conversion (code, integer_type_node, *arg, 1);
                   1906:   else if (TYPE_HAS_REAL_CONVERSION (type))
                   1907:     *arg = build_type_conversion (code, double_type_node, *arg, 1);
                   1908:   else
                   1909:     {
                   1910:       *arg = build_type_conversion (code, ptr_type_node, *arg, 1);
                   1911:       if (*arg == error_mark_node)
                   1912:        error ("ambiguous pointer conversion");
                   1913:     }
                   1914:   if (*arg == NULL_TREE)
                   1915:     {
                   1916:       error ("default type conversion for type `%s' failed", name);
                   1917:       return 0;
                   1918:     }
                   1919:   return 1;
                   1920: }

unix.superglobalmegacorp.com

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