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