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