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

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

unix.superglobalmegacorp.com

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