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

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

unix.superglobalmegacorp.com

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