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

unix.superglobalmegacorp.com

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