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

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

unix.superglobalmegacorp.com

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