|
|
1.1 ! root 1: /* Handle the hair of processing (but not expanding) inline functions. ! 2: Also manage function and variable name overloading. ! 3: Copyright (C) 1987, 1989, 1992, 1993 Free Software Foundation, Inc. ! 4: Contributed by Michael Tiemann ([email protected]) ! 5: ! 6: This file is part of GNU CC. ! 7: ! 8: GNU CC is free software; you can redistribute it and/or modify ! 9: it under the terms of the GNU General Public License as published by ! 10: the Free Software Foundation; either version 2, or (at your option) ! 11: any later version. ! 12: ! 13: GNU CC is distributed in the hope that it will be useful, ! 14: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 15: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 16: GNU General Public License for more details. ! 17: ! 18: You should have received a copy of the GNU General Public License ! 19: along with GNU CC; see the file COPYING. If not, write to ! 20: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 21: ! 22: ! 23: #ifndef PARM_CAN_BE_ARRAY_TYPE ! 24: #define PARM_CAN_BE_ARRAY_TYPE 1 ! 25: #endif ! 26: ! 27: /* Handle method declarations. */ ! 28: #include <stdio.h> ! 29: #include "config.h" ! 30: #include "tree.h" ! 31: #include "cp-tree.h" ! 32: #include "class.h" ! 33: #include "obstack.h" ! 34: #include <ctype.h> ! 35: #include "rtl.h" ! 36: #include "expr.h" ! 37: #include "output.h" ! 38: #include "hard-reg-set.h" ! 39: #include "flags.h" ! 40: ! 41: /* TREE_LIST of the current inline functions that need to be ! 42: processed. */ ! 43: struct pending_inline *pending_inlines; ! 44: ! 45: #define obstack_chunk_alloc xmalloc ! 46: #define obstack_chunk_free free ! 47: ! 48: /* Obstack where we build text strings for overloading, etc. */ ! 49: static struct obstack scratch_obstack; ! 50: static char *scratch_firstobj; ! 51: ! 52: # define OB_INIT() (scratch_firstobj ? (obstack_free (&scratch_obstack, scratch_firstobj), 0) : 0) ! 53: # define OB_PUTC(C) (obstack_1grow (&scratch_obstack, (C))) ! 54: # define OB_PUTC2(C1,C2) \ ! 55: (obstack_1grow (&scratch_obstack, (C1)), obstack_1grow (&scratch_obstack, (C2))) ! 56: # define OB_PUTS(S) (obstack_grow (&scratch_obstack, (S), sizeof (S) - 1)) ! 57: # define OB_PUTID(ID) \ ! 58: (obstack_grow (&scratch_obstack, IDENTIFIER_POINTER (ID), \ ! 59: IDENTIFIER_LENGTH (ID))) ! 60: # define OB_PUTCP(S) (obstack_grow (&scratch_obstack, (S), strlen (S))) ! 61: # define OB_FINISH() (obstack_1grow (&scratch_obstack, '\0')) ! 62: ! 63: #ifdef NO_AUTO_OVERLOAD ! 64: int is_overloaded (); ! 65: #endif ! 66: ! 67: void ! 68: init_method () ! 69: { ! 70: gcc_obstack_init (&scratch_obstack); ! 71: scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0); ! 72: } ! 73: ! 74: /* This must be large enough to hold any printed integer or floating-point ! 75: value. */ ! 76: static char digit_buffer[128]; ! 77: ! 78: /* Move inline function definitions out of structure so that they ! 79: can be processed normally. CNAME is the name of the class ! 80: we are working from, METHOD_LIST is the list of method lists ! 81: of the structure. We delete friend methods here, after ! 82: saving away their inline function definitions (if any). */ ! 83: ! 84: void ! 85: do_inline_function_hair (type, friend_list) ! 86: tree type, friend_list; ! 87: { ! 88: tree method = TYPE_METHODS (type); ! 89: ! 90: if (method && TREE_CODE (method) == TREE_VEC) ! 91: { ! 92: if (TREE_VEC_ELT (method, 0)) ! 93: method = TREE_VEC_ELT (method, 0); ! 94: else ! 95: method = TREE_VEC_ELT (method, 1); ! 96: } ! 97: ! 98: while (method) ! 99: { ! 100: /* Do inline member functions. */ ! 101: struct pending_inline *info = DECL_PENDING_INLINE_INFO (method); ! 102: if (info) ! 103: { ! 104: tree args; ! 105: ! 106: my_friendly_assert (info->fndecl == method, 238); ! 107: args = DECL_ARGUMENTS (method); ! 108: while (args) ! 109: { ! 110: DECL_CONTEXT (args) = method; ! 111: args = TREE_CHAIN (args); ! 112: } ! 113: ! 114: /* Allow this decl to be seen in global scope. Don't do this for ! 115: local class methods, though. */ ! 116: if (! current_function_decl) ! 117: IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (method)) = method; ! 118: } ! 119: method = TREE_CHAIN (method); ! 120: } ! 121: while (friend_list) ! 122: { ! 123: tree fndecl = TREE_VALUE (friend_list); ! 124: struct pending_inline *info = DECL_PENDING_INLINE_INFO (fndecl); ! 125: if (info) ! 126: { ! 127: tree args; ! 128: ! 129: my_friendly_assert (info->fndecl == fndecl, 239); ! 130: args = DECL_ARGUMENTS (fndecl); ! 131: while (args) ! 132: { ! 133: DECL_CONTEXT (args) = fndecl; ! 134: args = TREE_CHAIN (args); ! 135: } ! 136: ! 137: /* Allow this decl to be seen in global scope */ ! 138: if (! current_function_decl) ! 139: IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (fndecl)) = fndecl; ! 140: } ! 141: ! 142: friend_list = TREE_CHAIN (friend_list); ! 143: } ! 144: } ! 145: ! 146: /* Report an argument type mismatch between the best declared function ! 147: we could find and the current argument list that we have. */ ! 148: void ! 149: report_type_mismatch (cp, parmtypes, name_kind) ! 150: struct candidate *cp; ! 151: tree parmtypes; ! 152: char *name_kind; ! 153: { ! 154: int i = cp->u.bad_arg; ! 155: tree ttf, tta; ! 156: char *tmp_firstobj; ! 157: ! 158: switch (i) ! 159: { ! 160: case -4: ! 161: my_friendly_assert (TREE_CODE (cp->function) == TEMPLATE_DECL, 240); ! 162: cp_error ("type unification failed for function template `%#D'", ! 163: cp->function); ! 164: return; ! 165: ! 166: case -3: ! 167: if (TYPE_READONLY (TREE_TYPE (TREE_VALUE (parmtypes)))) ! 168: cp_error ("call to const %s `%#D' with non-const object", name_kind, ! 169: cp->function); ! 170: else ! 171: cp_error ("call to non-const %s `%#D' with const object", name_kind, ! 172: cp->function); ! 173: return; ! 174: case -2: ! 175: cp_error ("too few arguments for %s `%#D'", name_kind, cp->function); ! 176: return; ! 177: case -1: ! 178: cp_error ("too many arguments for %s `%#D'", name_kind, cp->function); ! 179: return; ! 180: case 0: ! 181: if (TREE_CODE (TREE_TYPE (cp->function)) == METHOD_TYPE) ! 182: { ! 183: /* Happens when we have an ambiguous base class. */ ! 184: my_friendly_assert (get_binfo (DECL_CLASS_CONTEXT (cp->function), ! 185: TREE_TYPE (TREE_TYPE (TREE_VALUE (parmtypes))), 1) == error_mark_node, ! 186: 241); ! 187: return; ! 188: } ! 189: } ! 190: ! 191: ttf = TYPE_ARG_TYPES (TREE_TYPE (cp->function)); ! 192: tta = parmtypes; ! 193: ! 194: while (i-- > 0) ! 195: { ! 196: ttf = TREE_CHAIN (ttf); ! 197: tta = TREE_CHAIN (tta); ! 198: } ! 199: ! 200: OB_INIT (); ! 201: OB_PUTS ("bad argument "); ! 202: sprintf (digit_buffer, "%d", cp->u.bad_arg ! 203: - (TREE_CODE (TREE_TYPE (cp->function)) == METHOD_TYPE) ! 204: + 1); ! 205: OB_PUTCP (digit_buffer); ! 206: ! 207: OB_PUTS (" for function `"); ! 208: OB_PUTCP (decl_as_string (cp->function, 1)); ! 209: OB_PUTS ("' (type was "); ! 210: ! 211: /* Reset `i' so that type printing routines do the right thing. */ ! 212: if (tta) ! 213: { ! 214: enum tree_code code = TREE_CODE (TREE_TYPE (TREE_VALUE (tta))); ! 215: if (code == ERROR_MARK) ! 216: OB_PUTS ("(failed type instantiation)"); ! 217: else ! 218: { ! 219: i = (code == FUNCTION_TYPE || code == METHOD_TYPE); ! 220: OB_PUTCP (type_as_string (TREE_TYPE (TREE_VALUE (tta)), 1)); ! 221: } ! 222: } ! 223: else OB_PUTS ("void"); ! 224: OB_PUTC (')'); ! 225: OB_FINISH (); ! 226: ! 227: tmp_firstobj = (char *)alloca (obstack_object_size (&scratch_obstack)); ! 228: bcopy (obstack_base (&scratch_obstack), tmp_firstobj, ! 229: obstack_object_size (&scratch_obstack)); ! 230: error (tmp_firstobj); ! 231: } ! 232: ! 233: /* Here is where overload code starts. */ ! 234: ! 235: /* Array of types seen so far in top-level call to `build_overload_name'. ! 236: Allocated and deallocated by caller. */ ! 237: static tree *typevec; ! 238: ! 239: /* Number of types interned by `build_overload_name' so far. */ ! 240: static int maxtype; ! 241: ! 242: /* Number of occurrences of last type seen. */ ! 243: static int nrepeats; ! 244: ! 245: /* Nonzero if we should not try folding parameter types. */ ! 246: static int nofold; ! 247: ! 248: #define ALLOCATE_TYPEVEC(PARMTYPES) \ ! 249: do { maxtype = 0, nrepeats = 0; \ ! 250: typevec = (tree *)alloca (list_length (PARMTYPES) * sizeof (tree)); } while (0) ! 251: ! 252: #define DEALLOCATE_TYPEVEC(PARMTYPES) \ ! 253: do { tree t = (PARMTYPES); \ ! 254: while (t) { TREE_USED (TREE_VALUE (t)) = 0; t = TREE_CHAIN (t); } \ ! 255: } while (0) ! 256: ! 257: /* Code to concatenate an asciified integer to a string. */ ! 258: static ! 259: #ifdef __GNUC__ ! 260: __inline ! 261: #endif ! 262: void ! 263: icat (i) ! 264: int i; ! 265: { ! 266: /* Handle this case first, to go really quickly. For many common values, ! 267: the result of i/10 below is 1. */ ! 268: if (i == 1) ! 269: { ! 270: OB_PUTC ('1'); ! 271: return; ! 272: } ! 273: ! 274: if (i < 0) ! 275: { ! 276: OB_PUTC ('m'); ! 277: i = -i; ! 278: } ! 279: if (i < 10) ! 280: OB_PUTC ('0' + i); ! 281: else ! 282: { ! 283: icat (i / 10); ! 284: OB_PUTC ('0' + (i % 10)); ! 285: } ! 286: } ! 287: ! 288: static ! 289: #ifdef __GNUC__ ! 290: __inline ! 291: #endif ! 292: void ! 293: flush_repeats (type) ! 294: tree type; ! 295: { ! 296: int tindex = 0; ! 297: ! 298: while (typevec[tindex] != type) ! 299: tindex++; ! 300: ! 301: if (nrepeats > 1) ! 302: { ! 303: OB_PUTC ('N'); ! 304: icat (nrepeats); ! 305: if (nrepeats > 9) ! 306: OB_PUTC ('_'); ! 307: } ! 308: else ! 309: OB_PUTC ('T'); ! 310: nrepeats = 0; ! 311: icat (tindex); ! 312: if (tindex > 9) ! 313: OB_PUTC ('_'); ! 314: } ! 315: ! 316: static int numeric_outputed_need_bar; ! 317: static void build_overload_identifier (); ! 318: ! 319: static void ! 320: build_overload_nested_name (context) ! 321: tree context; ! 322: { ! 323: /* We use DECL_NAME here, because pushtag now sets the DECL_ASSEMBLER_NAME. */ ! 324: tree name = DECL_NAME (context); ! 325: if (DECL_CONTEXT (context)) ! 326: { ! 327: context = DECL_CONTEXT (context); ! 328: if (TREE_CODE_CLASS (TREE_CODE (context)) == 't') ! 329: context = TYPE_NAME (context); ! 330: build_overload_nested_name (context); ! 331: } ! 332: build_overload_identifier (name); ! 333: } ! 334: ! 335: static void ! 336: build_overload_value (type, value) ! 337: tree type, value; ! 338: { ! 339: while (TREE_CODE (value) == NON_LVALUE_EXPR ! 340: || TREE_CODE (value) == NOP_EXPR) ! 341: value = TREE_OPERAND (value, 0); ! 342: my_friendly_assert (TREE_CODE (type) == PARM_DECL, 242); ! 343: type = TREE_TYPE (type); ! 344: switch (TREE_CODE (type)) ! 345: { ! 346: case INTEGER_TYPE: ! 347: case ENUMERAL_TYPE: ! 348: { ! 349: my_friendly_assert (TREE_CODE (value) == INTEGER_CST, 243); ! 350: if (TYPE_PRECISION (value) == 2 * HOST_BITS_PER_WIDE_INT) ! 351: { ! 352: if (tree_int_cst_lt (value, integer_zero_node)) ! 353: { ! 354: OB_PUTC ('m'); ! 355: value = build_int_2 (~ TREE_INT_CST_LOW (value), ! 356: - TREE_INT_CST_HIGH (value)); ! 357: } ! 358: if (TREE_INT_CST_HIGH (value) ! 359: != (TREE_INT_CST_LOW (value) >> (HOST_BITS_PER_WIDE_INT - 1))) ! 360: { ! 361: /* need to print a DImode value in decimal */ ! 362: sorry ("conversion of long long as PT parameter"); ! 363: } ! 364: /* else fall through to print in smaller mode */ ! 365: } ! 366: /* Wordsize or smaller */ ! 367: icat (TREE_INT_CST_LOW (value)); ! 368: return; ! 369: } ! 370: case BOOLEAN_TYPE: ! 371: { ! 372: icat (TREE_INT_CST_LOW (value)); ! 373: return; ! 374: } ! 375: #ifndef REAL_IS_NOT_DOUBLE ! 376: case REAL_TYPE: ! 377: { ! 378: REAL_VALUE_TYPE val; ! 379: char *bufp = digit_buffer; ! 380: extern char *index (); ! 381: ! 382: my_friendly_assert (TREE_CODE (value) == REAL_CST, 244); ! 383: val = TREE_REAL_CST (value); ! 384: if (val < 0) ! 385: { ! 386: val = -val; ! 387: *bufp++ = 'm'; ! 388: } ! 389: sprintf (bufp, "%e", val); ! 390: bufp = (char *) index (bufp, 'e'); ! 391: if (!bufp) ! 392: strcat (digit_buffer, "e0"); ! 393: else ! 394: { ! 395: char *p; ! 396: bufp++; ! 397: if (*bufp == '-') ! 398: { ! 399: *bufp++ = 'm'; ! 400: } ! 401: p = bufp; ! 402: if (*p == '+') ! 403: p++; ! 404: while (*p == '0') ! 405: p++; ! 406: if (*p == 0) ! 407: { ! 408: *bufp++ = '0'; ! 409: *bufp = 0; ! 410: } ! 411: else if (p != bufp) ! 412: { ! 413: while (*p) ! 414: *bufp++ = *p++; ! 415: *bufp = 0; ! 416: } ! 417: } ! 418: OB_PUTCP (digit_buffer); ! 419: return; ! 420: } ! 421: #endif ! 422: case POINTER_TYPE: ! 423: value = TREE_OPERAND (value, 0); ! 424: if (TREE_CODE (value) == VAR_DECL) ! 425: { ! 426: my_friendly_assert (DECL_NAME (value) != 0, 245); ! 427: build_overload_identifier (DECL_NAME (value)); ! 428: return; ! 429: } ! 430: else if (TREE_CODE (value) == FUNCTION_DECL) ! 431: { ! 432: my_friendly_assert (DECL_NAME (value) != 0, 246); ! 433: build_overload_identifier (DECL_NAME (value)); ! 434: return; ! 435: } ! 436: else ! 437: my_friendly_abort (71); ! 438: break; /* not really needed */ ! 439: ! 440: default: ! 441: sorry ("conversion of %s as template parameter", ! 442: tree_code_name [(int) TREE_CODE (type)]); ! 443: my_friendly_abort (72); ! 444: } ! 445: } ! 446: ! 447: static void ! 448: build_overload_identifier (name) ! 449: tree name; ! 450: { ! 451: if (IDENTIFIER_TEMPLATE (name)) ! 452: { ! 453: tree template, parmlist, arglist, tname; ! 454: int i, nparms; ! 455: template = IDENTIFIER_TEMPLATE (name); ! 456: arglist = TREE_VALUE (template); ! 457: template = TREE_PURPOSE (template); ! 458: tname = DECL_NAME (template); ! 459: parmlist = DECL_ARGUMENTS (template); ! 460: nparms = TREE_VEC_LENGTH (parmlist); ! 461: OB_PUTC ('t'); ! 462: icat (IDENTIFIER_LENGTH (tname)); ! 463: OB_PUTID (tname); ! 464: icat (nparms); ! 465: for (i = 0; i < nparms; i++) ! 466: { ! 467: tree parm = TREE_VALUE (TREE_VEC_ELT (parmlist, i)); ! 468: tree arg = TREE_VEC_ELT (arglist, i); ! 469: if (TREE_CODE (parm) == TYPE_DECL) ! 470: { ! 471: /* This parameter is a type. */ ! 472: OB_PUTC ('Z'); ! 473: build_overload_name (arg, 0, 0); ! 474: } ! 475: else ! 476: { ! 477: /* It's a PARM_DECL. */ ! 478: build_overload_name (TREE_TYPE (parm), 0, 0); ! 479: build_overload_value (parm, arg); ! 480: numeric_outputed_need_bar = 1; ! 481: } ! 482: } ! 483: } ! 484: else ! 485: { ! 486: if (numeric_outputed_need_bar) ! 487: { ! 488: OB_PUTC ('_'); ! 489: numeric_outputed_need_bar = 0; ! 490: } ! 491: icat (IDENTIFIER_LENGTH (name)); ! 492: OB_PUTID (name); ! 493: } ! 494: } ! 495: ! 496: /* Given a list of parameters in PARMTYPES, create an unambiguous ! 497: overload string. Should distinguish any type that C (or C++) can ! 498: distinguish. I.e., pointers to functions are treated correctly. ! 499: ! 500: Caller must deal with whether a final `e' goes on the end or not. ! 501: ! 502: Any default conversions must take place before this function ! 503: is called. ! 504: ! 505: BEGIN and END control initialization and finalization of the ! 506: obstack where we build the string. */ ! 507: ! 508: char * ! 509: build_overload_name (parmtypes, begin, end) ! 510: tree parmtypes; ! 511: int begin, end; ! 512: { ! 513: int just_one; ! 514: tree parmtype; ! 515: ! 516: if (begin) OB_INIT (); ! 517: numeric_outputed_need_bar = 0; ! 518: ! 519: if ((just_one = (TREE_CODE (parmtypes) != TREE_LIST))) ! 520: { ! 521: parmtype = parmtypes; ! 522: goto only_one; ! 523: } ! 524: ! 525: while (parmtypes) ! 526: { ! 527: parmtype = TREE_VALUE (parmtypes); ! 528: ! 529: only_one: ! 530: ! 531: if (! nofold) ! 532: { ! 533: if (! just_one) ! 534: /* Every argument gets counted. */ ! 535: typevec[maxtype++] = parmtype; ! 536: ! 537: if (TREE_USED (parmtype)) ! 538: { ! 539: if (! just_one && parmtype == typevec[maxtype-2]) ! 540: nrepeats++; ! 541: else ! 542: { ! 543: if (nrepeats) ! 544: flush_repeats (parmtype); ! 545: if (! just_one && TREE_CHAIN (parmtypes) ! 546: && parmtype == TREE_VALUE (TREE_CHAIN (parmtypes))) ! 547: nrepeats++; ! 548: else ! 549: { ! 550: int tindex = 0; ! 551: ! 552: while (typevec[tindex] != parmtype) ! 553: tindex++; ! 554: OB_PUTC ('T'); ! 555: icat (tindex); ! 556: if (tindex > 9) ! 557: OB_PUTC ('_'); ! 558: } ! 559: } ! 560: goto next; ! 561: } ! 562: if (nrepeats) ! 563: flush_repeats (typevec[maxtype-2]); ! 564: if (! just_one ! 565: /* Only cache types which take more than one character. */ ! 566: && (parmtype != TYPE_MAIN_VARIANT (parmtype) ! 567: || (TREE_CODE (parmtype) != INTEGER_TYPE ! 568: && TREE_CODE (parmtype) != REAL_TYPE))) ! 569: TREE_USED (parmtype) = 1; ! 570: } ! 571: ! 572: if (TYPE_PTRMEMFUNC_P (parmtype)) ! 573: parmtype = TYPE_PTRMEMFUNC_FN_TYPE (parmtype); ! 574: ! 575: if (TREE_READONLY (parmtype)) ! 576: OB_PUTC ('C'); ! 577: if (TREE_CODE (parmtype) == INTEGER_TYPE ! 578: && TYPE_MAIN_VARIANT (parmtype) == unsigned_type (TYPE_MAIN_VARIANT (parmtype))) ! 579: OB_PUTC ('U'); ! 580: if (TYPE_VOLATILE (parmtype)) ! 581: OB_PUTC ('V'); ! 582: ! 583: switch (TREE_CODE (parmtype)) ! 584: { ! 585: case OFFSET_TYPE: ! 586: OB_PUTC ('O'); ! 587: build_overload_name (TYPE_OFFSET_BASETYPE (parmtype), 0, 0); ! 588: OB_PUTC ('_'); ! 589: build_overload_name (TREE_TYPE (parmtype), 0, 0); ! 590: break; ! 591: ! 592: case REFERENCE_TYPE: ! 593: OB_PUTC ('R'); ! 594: goto more; ! 595: ! 596: case ARRAY_TYPE: ! 597: #if PARM_CAN_BE_ARRAY_TYPE ! 598: { ! 599: tree length; ! 600: ! 601: OB_PUTC ('A'); ! 602: if (TYPE_DOMAIN (parmtype) == NULL_TREE) ! 603: error ("pointer or reference to array of unknown bound in parm type"); ! 604: else ! 605: { ! 606: length = array_type_nelts (parmtype); ! 607: if (TREE_CODE (length) == INTEGER_CST) ! 608: icat (TREE_INT_CST_LOW (length) + 1); ! 609: } ! 610: OB_PUTC ('_'); ! 611: goto more; ! 612: } ! 613: #else ! 614: OB_PUTC ('P'); ! 615: goto more; ! 616: #endif ! 617: ! 618: case POINTER_TYPE: ! 619: OB_PUTC ('P'); ! 620: more: ! 621: build_overload_name (TREE_TYPE (parmtype), 0, 0); ! 622: break; ! 623: ! 624: case FUNCTION_TYPE: ! 625: case METHOD_TYPE: ! 626: { ! 627: tree firstarg = TYPE_ARG_TYPES (parmtype); ! 628: /* Otherwise have to implement reentrant typevecs, ! 629: unmark and remark types, etc. */ ! 630: int old_nofold = nofold; ! 631: nofold = 1; ! 632: ! 633: if (nrepeats) ! 634: flush_repeats (typevec[maxtype-1]); ! 635: ! 636: /* @@ It may be possible to pass a function type in ! 637: which is not preceded by a 'P'. */ ! 638: if (TREE_CODE (parmtype) == FUNCTION_TYPE) ! 639: { ! 640: OB_PUTC ('F'); ! 641: if (firstarg == NULL_TREE) ! 642: OB_PUTC ('e'); ! 643: else if (firstarg == void_list_node) ! 644: OB_PUTC ('v'); ! 645: else ! 646: build_overload_name (firstarg, 0, 0); ! 647: } ! 648: else ! 649: { ! 650: int constp = TYPE_READONLY (TREE_TYPE (TREE_VALUE (firstarg))); ! 651: int volatilep = TYPE_VOLATILE (TREE_TYPE (TREE_VALUE (firstarg))); ! 652: OB_PUTC ('M'); ! 653: firstarg = TREE_CHAIN (firstarg); ! 654: ! 655: build_overload_name (TYPE_METHOD_BASETYPE (parmtype), 0, 0); ! 656: if (constp) ! 657: OB_PUTC ('C'); ! 658: if (volatilep) ! 659: OB_PUTC ('V'); ! 660: ! 661: /* For cfront 2.0 compatibility. */ ! 662: OB_PUTC ('F'); ! 663: ! 664: if (firstarg == NULL_TREE) ! 665: OB_PUTC ('e'); ! 666: else if (firstarg == void_list_node) ! 667: OB_PUTC ('v'); ! 668: else ! 669: build_overload_name (firstarg, 0, 0); ! 670: } ! 671: ! 672: /* Separate args from return type. */ ! 673: OB_PUTC ('_'); ! 674: build_overload_name (TREE_TYPE (parmtype), 0, 0); ! 675: nofold = old_nofold; ! 676: break; ! 677: } ! 678: ! 679: case INTEGER_TYPE: ! 680: parmtype = TYPE_MAIN_VARIANT (parmtype); ! 681: if (parmtype == integer_type_node ! 682: || parmtype == unsigned_type_node) ! 683: OB_PUTC ('i'); ! 684: else if (parmtype == long_integer_type_node ! 685: || parmtype == long_unsigned_type_node) ! 686: OB_PUTC ('l'); ! 687: else if (parmtype == short_integer_type_node ! 688: || parmtype == short_unsigned_type_node) ! 689: OB_PUTC ('s'); ! 690: else if (parmtype == signed_char_type_node) ! 691: { ! 692: OB_PUTC ('S'); ! 693: OB_PUTC ('c'); ! 694: } ! 695: else if (parmtype == char_type_node ! 696: || parmtype == unsigned_char_type_node) ! 697: OB_PUTC ('c'); ! 698: else if (parmtype == wchar_type_node) ! 699: OB_PUTC ('w'); ! 700: else if (parmtype == long_long_integer_type_node ! 701: || parmtype == long_long_unsigned_type_node) ! 702: OB_PUTC ('x'); ! 703: #if 0 ! 704: /* it would seem there is no way to enter these in source code, ! 705: yet. (mrs) */ ! 706: else if (parmtype == long_long_long_integer_type_node ! 707: || parmtype == long_long_long_unsigned_type_node) ! 708: OB_PUTC ('q'); ! 709: #endif ! 710: else ! 711: my_friendly_abort (73); ! 712: break; ! 713: ! 714: case BOOLEAN_TYPE: ! 715: OB_PUTC ('b'); ! 716: break; ! 717: ! 718: case REAL_TYPE: ! 719: parmtype = TYPE_MAIN_VARIANT (parmtype); ! 720: if (parmtype == long_double_type_node) ! 721: OB_PUTC ('r'); ! 722: else if (parmtype == double_type_node) ! 723: OB_PUTC ('d'); ! 724: else if (parmtype == float_type_node) ! 725: OB_PUTC ('f'); ! 726: else my_friendly_abort (74); ! 727: break; ! 728: ! 729: case VOID_TYPE: ! 730: if (! just_one) ! 731: { ! 732: #if 0 ! 733: extern tree void_list_node; ! 734: ! 735: /* See if anybody is wasting memory. */ ! 736: my_friendly_assert (parmtypes == void_list_node, 247); ! 737: #endif ! 738: /* This is the end of a parameter list. */ ! 739: if (end) OB_FINISH (); ! 740: return (char *)obstack_base (&scratch_obstack); ! 741: } ! 742: OB_PUTC ('v'); ! 743: break; ! 744: ! 745: case ERROR_MARK: /* not right, but nothing is anyway */ ! 746: break; ! 747: ! 748: /* have to do these */ ! 749: case UNION_TYPE: ! 750: case RECORD_TYPE: ! 751: if (! just_one) ! 752: /* Make this type signature look incompatible ! 753: with AT&T. */ ! 754: OB_PUTC ('G'); ! 755: goto common; ! 756: case ENUMERAL_TYPE: ! 757: common: ! 758: { ! 759: tree name = TYPE_NAME (parmtype); ! 760: int i = 1; ! 761: ! 762: if (TREE_CODE (name) == TYPE_DECL) ! 763: { ! 764: tree context = name; ! 765: while (DECL_CONTEXT (context)) ! 766: { ! 767: i += 1; ! 768: context = DECL_CONTEXT (context); ! 769: if (TREE_CODE_CLASS (TREE_CODE (context)) == 't') ! 770: context = TYPE_NAME (context); ! 771: } ! 772: name = DECL_NAME (name); ! 773: } ! 774: my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 248); ! 775: if (i > 1) ! 776: { ! 777: OB_PUTC ('Q'); ! 778: if (i > 9) ! 779: OB_PUTC ('_'); ! 780: icat (i); ! 781: if (i > 9) ! 782: OB_PUTC ('_'); ! 783: numeric_outputed_need_bar = 0; ! 784: build_overload_nested_name (TYPE_NAME (parmtype)); ! 785: } ! 786: else ! 787: build_overload_identifier (name); ! 788: break; ! 789: } ! 790: ! 791: case UNKNOWN_TYPE: ! 792: /* This will take some work. */ ! 793: OB_PUTC ('?'); ! 794: break; ! 795: ! 796: case TEMPLATE_TYPE_PARM: ! 797: case TEMPLATE_CONST_PARM: ! 798: case UNINSTANTIATED_P_TYPE: ! 799: /* We don't ever want this output, but it's inconvenient not to ! 800: be able to build the string. This should cause assembler ! 801: errors we'll notice. */ ! 802: { ! 803: static int n; ! 804: sprintf (digit_buffer, " *%d", n++); ! 805: OB_PUTCP (digit_buffer); ! 806: } ! 807: break; ! 808: ! 809: default: ! 810: my_friendly_abort (75); ! 811: } ! 812: ! 813: next: ! 814: if (just_one) break; ! 815: parmtypes = TREE_CHAIN (parmtypes); ! 816: } ! 817: if (! just_one) ! 818: { ! 819: if (nrepeats) ! 820: flush_repeats (typevec[maxtype-1]); ! 821: ! 822: /* To get here, parms must end with `...'. */ ! 823: OB_PUTC ('e'); ! 824: } ! 825: ! 826: if (end) OB_FINISH (); ! 827: return (char *)obstack_base (&scratch_obstack); ! 828: } ! 829: ! 830: tree ! 831: build_static_name (basetype, name) ! 832: tree basetype, name; ! 833: { ! 834: char *basename = build_overload_name (basetype, 1, 1); ! 835: char *buf = (char *) alloca (IDENTIFIER_LENGTH (name) ! 836: + sizeof (STATIC_NAME_FORMAT) ! 837: + strlen (basename)); ! 838: sprintf (buf, STATIC_NAME_FORMAT, basename, IDENTIFIER_POINTER (name)); ! 839: return get_identifier (buf); ! 840: } ! 841: ! 842: /* Generate an identifier that encodes the (ANSI) exception TYPE. */ ! 843: ! 844: /* This should be part of `ansi_opname', or at least be defined by the std. */ ! 845: #define EXCEPTION_NAME_PREFIX "__ex" ! 846: #define EXCEPTION_NAME_LENGTH 4 ! 847: ! 848: tree ! 849: cplus_exception_name (type) ! 850: tree type; ! 851: { ! 852: OB_INIT (); ! 853: OB_PUTS (EXCEPTION_NAME_PREFIX); ! 854: return get_identifier (build_overload_name (type, 0, 1)); ! 855: } ! 856: ! 857: /* Change the name of a function definition so that it may be ! 858: overloaded. NAME is the name of the function to overload, ! 859: PARMS is the parameter list (which determines what name the ! 860: final function obtains). ! 861: ! 862: FOR_METHOD is 1 if this overload is being performed ! 863: for a method, rather than a function type. It is 2 if ! 864: this overload is being performed for a constructor. */ ! 865: tree ! 866: build_decl_overload (dname, parms, for_method) ! 867: tree dname; ! 868: tree parms; ! 869: int for_method; ! 870: { ! 871: char *name = IDENTIFIER_POINTER (dname); ! 872: ! 873: /* member operators new and delete look like methods at this point. */ ! 874: if (! for_method && parms != NULL_TREE && TREE_CODE (parms) == TREE_LIST) ! 875: { ! 876: if (dname == ansi_opname[(int) DELETE_EXPR]) ! 877: return get_identifier ("__builtin_delete"); ! 878: else if (dname == ansi_opname[(int) VEC_DELETE_EXPR]) ! 879: return get_identifier ("__builtin_vec_delete"); ! 880: else if (TREE_CHAIN (parms) == void_list_node) ! 881: { ! 882: if (dname == ansi_opname[(int) NEW_EXPR]) ! 883: return get_identifier ("__builtin_new"); ! 884: else if (dname == ansi_opname[(int) VEC_NEW_EXPR]) ! 885: return get_identifier ("__builtin_vec_new"); ! 886: } ! 887: } ! 888: ! 889: OB_INIT (); ! 890: if (for_method != 2) ! 891: OB_PUTCP (name); ! 892: /* Otherwise, we can divine that this is a constructor, ! 893: and figure out its name without any extra encoding. */ ! 894: ! 895: OB_PUTC2 ('_', '_'); ! 896: if (for_method) ! 897: { ! 898: #if 0 ! 899: /* We can get away without doing this. */ ! 900: OB_PUTC ('M'); ! 901: #endif ! 902: { ! 903: tree this_type = TREE_VALUE (parms); ! 904: ! 905: if (TREE_CODE (this_type) == RECORD_TYPE) /* a signature pointer */ ! 906: parms = temp_tree_cons (NULL_TREE, SIGNATURE_TYPE (this_type), ! 907: TREE_CHAIN (parms)); ! 908: else ! 909: parms = temp_tree_cons (NULL_TREE, TREE_TYPE (this_type), ! 910: TREE_CHAIN (parms)); ! 911: } ! 912: } ! 913: else ! 914: OB_PUTC ('F'); ! 915: ! 916: if (parms == NULL_TREE) ! 917: OB_PUTC2 ('e', '\0'); ! 918: else if (parms == void_list_node) ! 919: OB_PUTC2 ('v', '\0'); ! 920: else ! 921: { ! 922: ALLOCATE_TYPEVEC (parms); ! 923: nofold = 0; ! 924: if (for_method) ! 925: { ! 926: build_overload_name (TREE_VALUE (parms), 0, 0); ! 927: ! 928: typevec[maxtype++] = TREE_VALUE (parms); ! 929: TREE_USED (TREE_VALUE (parms)) = 1; ! 930: ! 931: if (TREE_CHAIN (parms)) ! 932: build_overload_name (TREE_CHAIN (parms), 0, 1); ! 933: else ! 934: OB_PUTC2 ('e', '\0'); ! 935: } ! 936: else ! 937: build_overload_name (parms, 0, 1); ! 938: DEALLOCATE_TYPEVEC (parms); ! 939: } ! 940: { ! 941: tree n = get_identifier (obstack_base (&scratch_obstack)); ! 942: if (IDENTIFIER_OPNAME_P (dname)) ! 943: IDENTIFIER_OPNAME_P (n) = 1; ! 944: return n; ! 945: } ! 946: } ! 947: ! 948: /* Build an overload name for the type expression TYPE. */ ! 949: tree ! 950: build_typename_overload (type) ! 951: tree type; ! 952: { ! 953: tree id; ! 954: ! 955: OB_INIT (); ! 956: OB_PUTID (ansi_opname[(int) TYPE_EXPR]); ! 957: nofold = 1; ! 958: build_overload_name (type, 0, 1); ! 959: id = get_identifier (obstack_base (&scratch_obstack)); ! 960: IDENTIFIER_OPNAME_P (id) = 1; ! 961: #if 0 ! 962: IDENTIFIER_GLOBAL_VALUE (id) = TYPE_NAME (type); ! 963: #endif ! 964: TREE_TYPE (id) = type; ! 965: return id; ! 966: } ! 967: ! 968: #ifndef NO_DOLLAR_IN_LABEL ! 969: #define T_DESC_FORMAT "TD$" ! 970: #define I_DESC_FORMAT "ID$" ! 971: #define M_DESC_FORMAT "MD$" ! 972: #else ! 973: #if !defined(NO_DOT_IN_LABEL) ! 974: #define T_DESC_FORMAT "TD." ! 975: #define I_DESC_FORMAT "ID." ! 976: #define M_DESC_FORMAT "MD." ! 977: #else ! 978: #define T_DESC_FORMAT "__t_desc_" ! 979: #define I_DESC_FORMAT "__i_desc_" ! 980: #define M_DESC_FORMAT "__m_desc_" ! 981: #endif ! 982: #endif ! 983: ! 984: /* Build an overload name for the type expression TYPE. */ ! 985: tree ! 986: build_t_desc_overload (type) ! 987: tree type; ! 988: { ! 989: OB_INIT (); ! 990: OB_PUTS (T_DESC_FORMAT); ! 991: nofold = 1; ! 992: ! 993: #if 0 ! 994: /* Use a different format if the type isn't defined yet. */ ! 995: if (TYPE_SIZE (type) == NULL_TREE) ! 996: { ! 997: char *p; ! 998: int changed; ! 999: ! 1000: for (p = tname; *p; p++) ! 1001: if (isupper (*p)) ! 1002: { ! 1003: changed = 1; ! 1004: *p = tolower (*p); ! 1005: } ! 1006: /* If there's no change, we have an inappropriate T_DESC_FORMAT. */ ! 1007: my_friendly_assert (changed != 0, 249); ! 1008: } ! 1009: #endif ! 1010: ! 1011: build_overload_name (type, 0, 1); ! 1012: return get_identifier (obstack_base (&scratch_obstack)); ! 1013: } ! 1014: ! 1015: /* Top-level interface to explicit overload requests. Allow NAME ! 1016: to be overloaded. Error if NAME is already declared for the current ! 1017: scope. Warning if function is redundantly overloaded. */ ! 1018: ! 1019: void ! 1020: declare_overloaded (name) ! 1021: tree name; ! 1022: { ! 1023: #ifdef NO_AUTO_OVERLOAD ! 1024: if (is_overloaded (name)) ! 1025: warning ("function `%s' already declared overloaded", ! 1026: IDENTIFIER_POINTER (name)); ! 1027: else if (IDENTIFIER_GLOBAL_VALUE (name)) ! 1028: error ("overloading function `%s' that is already defined", ! 1029: IDENTIFIER_POINTER (name)); ! 1030: else ! 1031: { ! 1032: TREE_OVERLOADED (name) = 1; ! 1033: IDENTIFIER_GLOBAL_VALUE (name) = build_tree_list (name, NULL_TREE); ! 1034: TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (name)) = unknown_type_node; ! 1035: } ! 1036: #else ! 1037: if (current_lang_name == lang_name_cplusplus) ! 1038: { ! 1039: if (0) ! 1040: warning ("functions are implicitly overloaded in C++"); ! 1041: } ! 1042: else if (current_lang_name == lang_name_c) ! 1043: error ("overloading function `%s' cannot be done in C language context"); ! 1044: else ! 1045: my_friendly_abort (76); ! 1046: #endif ! 1047: } ! 1048: ! 1049: #ifdef NO_AUTO_OVERLOAD ! 1050: /* Check to see if NAME is overloaded. For first approximation, ! 1051: check to see if its TREE_OVERLOADED is set. This is used on ! 1052: IDENTIFIER nodes. */ ! 1053: int ! 1054: is_overloaded (name) ! 1055: tree name; ! 1056: { ! 1057: /* @@ */ ! 1058: return (TREE_OVERLOADED (name) ! 1059: && (! IDENTIFIER_CLASS_VALUE (name) || current_class_type == 0) ! 1060: && ! IDENTIFIER_LOCAL_VALUE (name)); ! 1061: } ! 1062: #endif ! 1063: ! 1064: /* Given a tree_code CODE, and some arguments (at least one), ! 1065: attempt to use an overloaded operator on the arguments. ! 1066: ! 1067: For unary operators, only the first argument need be checked. ! 1068: For binary operators, both arguments may need to be checked. ! 1069: ! 1070: Member functions can convert class references to class pointers, ! 1071: for one-level deep indirection. More than that is not supported. ! 1072: Operators [](), ()(), and ->() must be member functions. ! 1073: ! 1074: We call function call building calls with LOOKUP_COMPLAIN if they ! 1075: are our only hope. This is true when we see a vanilla operator ! 1076: applied to something of aggregate type. If this fails, we are free ! 1077: to return `error_mark_node', because we will have reported the ! 1078: error. ! 1079: ! 1080: Operators NEW and DELETE overload in funny ways: operator new takes ! 1081: a single `size' parameter, and operator delete takes a pointer to the ! 1082: storage being deleted. When overloading these operators, success is ! 1083: assumed. If there is a failure, report an error message and return ! 1084: `error_mark_node'. */ ! 1085: ! 1086: /* NOSTRICT */ ! 1087: tree ! 1088: build_opfncall (code, flags, xarg1, xarg2, arg3) ! 1089: enum tree_code code; ! 1090: int flags; ! 1091: tree xarg1, xarg2, arg3; ! 1092: { ! 1093: tree rval = 0; ! 1094: tree arg1, arg2; ! 1095: tree type1, type2, fnname; ! 1096: tree fields1 = 0, parms = 0; ! 1097: tree global_fn; ! 1098: int try_second; ! 1099: int binary_is_unary; ! 1100: ! 1101: if (xarg1 == error_mark_node) ! 1102: return error_mark_node; ! 1103: ! 1104: if (code == COND_EXPR) ! 1105: { ! 1106: if (TREE_CODE (xarg2) == ERROR_MARK ! 1107: || TREE_CODE (arg3) == ERROR_MARK) ! 1108: return error_mark_node; ! 1109: } ! 1110: if (code == COMPONENT_REF) ! 1111: if (TREE_CODE (TREE_TYPE (xarg1)) == POINTER_TYPE) ! 1112: return rval; ! 1113: ! 1114: /* First, see if we can work with the first argument */ ! 1115: type1 = TREE_TYPE (xarg1); ! 1116: ! 1117: /* Some tree codes have length > 1, but we really only want to ! 1118: overload them if their first argument has a user defined type. */ ! 1119: switch (code) ! 1120: { ! 1121: case PREINCREMENT_EXPR: ! 1122: case PREDECREMENT_EXPR: ! 1123: case POSTINCREMENT_EXPR: ! 1124: case POSTDECREMENT_EXPR: ! 1125: case COMPONENT_REF: ! 1126: binary_is_unary = 1; ! 1127: try_second = 0; ! 1128: break; ! 1129: ! 1130: /* ARRAY_REFs and CALL_EXPRs must overload successfully. ! 1131: If they do not, return error_mark_node instead of NULL_TREE. */ ! 1132: case ARRAY_REF: ! 1133: if (xarg2 == error_mark_node) ! 1134: return error_mark_node; ! 1135: case CALL_EXPR: ! 1136: rval = error_mark_node; ! 1137: binary_is_unary = 0; ! 1138: try_second = 0; ! 1139: break; ! 1140: ! 1141: case VEC_NEW_EXPR: ! 1142: case NEW_EXPR: ! 1143: { ! 1144: tree args = tree_cons (NULL_TREE, xarg2, arg3); ! 1145: fnname = ansi_opname[(int) code]; ! 1146: if (flags & LOOKUP_GLOBAL) ! 1147: return build_overload_call (fnname, args, flags & LOOKUP_COMPLAIN, ! 1148: (struct candidate *)0); ! 1149: ! 1150: rval = build_method_call ! 1151: (build_indirect_ref (build1 (NOP_EXPR, xarg1, error_mark_node), ! 1152: "new"), ! 1153: fnname, args, NULL_TREE, flags); ! 1154: if (rval == error_mark_node) ! 1155: /* User might declare fancy operator new, but invoke it ! 1156: like standard one. */ ! 1157: return rval; ! 1158: ! 1159: TREE_TYPE (rval) = xarg1; ! 1160: TREE_CALLS_NEW (rval) = 1; ! 1161: return rval; ! 1162: } ! 1163: break; ! 1164: ! 1165: case VEC_DELETE_EXPR: ! 1166: case DELETE_EXPR: ! 1167: { ! 1168: fnname = ansi_opname[(int) code]; ! 1169: if (flags & LOOKUP_GLOBAL) ! 1170: return build_overload_call (fnname, ! 1171: build_tree_list (NULL_TREE, xarg1), ! 1172: flags & LOOKUP_COMPLAIN, ! 1173: (struct candidate *)0); ! 1174: ! 1175: rval = build_method_call ! 1176: (build_indirect_ref (build1 (NOP_EXPR, TREE_TYPE (xarg1), ! 1177: error_mark_node), ! 1178: NULL_PTR), ! 1179: fnname, tree_cons (NULL_TREE, xarg1, ! 1180: build_tree_list (NULL_TREE, xarg2)), ! 1181: NULL_TREE, flags); ! 1182: /* This happens when the user mis-declares `operator delete'. ! 1183: Should now be impossible. */ ! 1184: my_friendly_assert (rval != error_mark_node, 250); ! 1185: TREE_TYPE (rval) = void_type_node; ! 1186: return rval; ! 1187: } ! 1188: break; ! 1189: ! 1190: default: ! 1191: binary_is_unary = 0; ! 1192: try_second = tree_code_length [(int) code] == 2; ! 1193: if (try_second && xarg2 == error_mark_node) ! 1194: return error_mark_node; ! 1195: break; ! 1196: } ! 1197: ! 1198: if (try_second && xarg2 == error_mark_node) ! 1199: return error_mark_node; ! 1200: ! 1201: /* What ever it was, we do not know how to deal with it. */ ! 1202: if (type1 == NULL_TREE) ! 1203: return rval; ! 1204: ! 1205: if (TREE_CODE (type1) == OFFSET_TYPE) ! 1206: type1 = TREE_TYPE (type1); ! 1207: ! 1208: if (TREE_CODE (type1) == REFERENCE_TYPE) ! 1209: { ! 1210: arg1 = convert_from_reference (xarg1); ! 1211: type1 = TREE_TYPE (arg1); ! 1212: } ! 1213: else ! 1214: { ! 1215: arg1 = xarg1; ! 1216: } ! 1217: ! 1218: if (!IS_AGGR_TYPE (type1) || TYPE_PTRMEMFUNC_P (type1)) ! 1219: { ! 1220: /* Try to fail. First, fail if unary */ ! 1221: if (! try_second) ! 1222: return rval; ! 1223: /* Second, see if second argument is non-aggregate. */ ! 1224: type2 = TREE_TYPE (xarg2); ! 1225: if (TREE_CODE (type2) == OFFSET_TYPE) ! 1226: type2 = TREE_TYPE (type2); ! 1227: if (TREE_CODE (type2) == REFERENCE_TYPE) ! 1228: { ! 1229: arg2 = convert_from_reference (xarg2); ! 1230: type2 = TREE_TYPE (arg2); ! 1231: } ! 1232: else ! 1233: { ! 1234: arg2 = xarg2; ! 1235: } ! 1236: ! 1237: if (!IS_AGGR_TYPE (type2)) ! 1238: return rval; ! 1239: try_second = 0; ! 1240: } ! 1241: ! 1242: if (try_second) ! 1243: { ! 1244: /* First arg may succeed; see whether second should. */ ! 1245: type2 = TREE_TYPE (xarg2); ! 1246: if (TREE_CODE (type2) == OFFSET_TYPE) ! 1247: type2 = TREE_TYPE (type2); ! 1248: if (TREE_CODE (type2) == REFERENCE_TYPE) ! 1249: { ! 1250: arg2 = convert_from_reference (xarg2); ! 1251: type2 = TREE_TYPE (arg2); ! 1252: } ! 1253: else ! 1254: { ! 1255: arg2 = xarg2; ! 1256: } ! 1257: ! 1258: if (! IS_AGGR_TYPE (type2)) ! 1259: try_second = 0; ! 1260: } ! 1261: ! 1262: if (type1 == unknown_type_node ! 1263: || (try_second && TREE_TYPE (xarg2) == unknown_type_node)) ! 1264: { ! 1265: /* This will not be implemented in the foreseeable future. */ ! 1266: return rval; ! 1267: } ! 1268: ! 1269: if (code == MODIFY_EXPR) ! 1270: fnname = ansi_assopname[(int) TREE_CODE (arg3)]; ! 1271: else ! 1272: fnname = ansi_opname[(int) code]; ! 1273: ! 1274: global_fn = lookup_name_nonclass (fnname); ! 1275: ! 1276: /* This is the last point where we will accept failure. This ! 1277: may be too eager if we wish an overloaded operator not to match, ! 1278: but would rather a normal operator be called on a type-converted ! 1279: argument. */ ! 1280: ! 1281: if (IS_AGGR_TYPE (type1)) ! 1282: { ! 1283: fields1 = lookup_fnfields (TYPE_BINFO (type1), fnname, 0); ! 1284: /* ARM $13.4.7, prefix/postfix ++/--. */ ! 1285: if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR) ! 1286: { ! 1287: xarg2 = integer_zero_node; ! 1288: binary_is_unary = 0; ! 1289: ! 1290: if (fields1) ! 1291: { ! 1292: tree t, t2; ! 1293: int have_postfix = 0; ! 1294: ! 1295: /* Look for an `operator++ (int)'. If they didn't have ! 1296: one, then we fall back to the old way of doing things. */ ! 1297: for (t = TREE_VALUE (fields1); t ; t = TREE_CHAIN (t)) ! 1298: { ! 1299: t2 = TYPE_ARG_TYPES (TREE_TYPE (t)); ! 1300: if (TREE_CHAIN (t2) != NULL_TREE ! 1301: && TREE_VALUE (TREE_CHAIN (t2)) == integer_type_node) ! 1302: { ! 1303: have_postfix = 1; ! 1304: break; ! 1305: } ! 1306: } ! 1307: ! 1308: if (! have_postfix) ! 1309: { ! 1310: char *op = POSTINCREMENT_EXPR ? "++" : "--"; ! 1311: ! 1312: /* There's probably a LOT of code in the world that ! 1313: relies upon this old behavior. So we'll only give this ! 1314: warning when we've been given -pedantic. A few ! 1315: releases after 2.4, we'll convert this to be a pedwarn ! 1316: or something else more appropriate. */ ! 1317: if (pedantic) ! 1318: warning ("no `operator%s (int)' declared for postfix `%s'", ! 1319: op, op); ! 1320: xarg2 = NULL_TREE; ! 1321: binary_is_unary = 1; ! 1322: } ! 1323: } ! 1324: } ! 1325: } ! 1326: ! 1327: if (fields1 == NULL_TREE && global_fn == NULL_TREE) ! 1328: return rval; ! 1329: ! 1330: /* If RVAL winds up being `error_mark_node', we will return ! 1331: that... There is no way that normal semantics of these ! 1332: operators will succeed. */ ! 1333: ! 1334: /* This argument may be an uncommitted OFFSET_REF. This is ! 1335: the case for example when dealing with static class members ! 1336: which are referenced from their class name rather than ! 1337: from a class instance. */ ! 1338: if (TREE_CODE (xarg1) == OFFSET_REF ! 1339: && TREE_CODE (TREE_OPERAND (xarg1, 1)) == VAR_DECL) ! 1340: xarg1 = TREE_OPERAND (xarg1, 1); ! 1341: if (try_second && xarg2 && TREE_CODE (xarg2) == OFFSET_REF ! 1342: && TREE_CODE (TREE_OPERAND (xarg2, 1)) == VAR_DECL) ! 1343: xarg2 = TREE_OPERAND (xarg2, 1); ! 1344: ! 1345: if (global_fn) ! 1346: flags |= LOOKUP_GLOBAL; ! 1347: ! 1348: if (code == CALL_EXPR) ! 1349: { ! 1350: /* This can only be a member function. */ ! 1351: return build_method_call (xarg1, fnname, xarg2, ! 1352: NULL_TREE, LOOKUP_NORMAL); ! 1353: } ! 1354: else if (tree_code_length[(int) code] == 1 || binary_is_unary) ! 1355: { ! 1356: parms = NULL_TREE; ! 1357: rval = build_method_call (xarg1, fnname, NULL_TREE, NULL_TREE, flags); ! 1358: } ! 1359: else if (code == COND_EXPR) ! 1360: { ! 1361: parms = tree_cons (0, xarg2, build_tree_list (NULL_TREE, arg3)); ! 1362: rval = build_method_call (xarg1, fnname, parms, NULL_TREE, flags); ! 1363: } ! 1364: else if (code == METHOD_CALL_EXPR) ! 1365: { ! 1366: /* must be a member function. */ ! 1367: parms = tree_cons (NULL_TREE, xarg2, arg3); ! 1368: return build_method_call (xarg1, fnname, parms, NULL_TREE, ! 1369: LOOKUP_NORMAL); ! 1370: } ! 1371: else if (fields1) ! 1372: { ! 1373: parms = build_tree_list (NULL_TREE, xarg2); ! 1374: rval = build_method_call (xarg1, fnname, parms, NULL_TREE, flags); ! 1375: } ! 1376: else ! 1377: { ! 1378: parms = tree_cons (NULL_TREE, xarg1, ! 1379: build_tree_list (NULL_TREE, xarg2)); ! 1380: rval = build_overload_call (fnname, parms, flags, ! 1381: (struct candidate *)0); ! 1382: } ! 1383: ! 1384: return rval; ! 1385: } ! 1386: ! 1387: /* This function takes an identifier, ID, and attempts to figure out what ! 1388: it means. There are a number of possible scenarios, presented in increasing ! 1389: order of hair: ! 1390: ! 1391: 1) not in a class's scope ! 1392: 2) in class's scope, member name of the class's method ! 1393: 3) in class's scope, but not a member name of the class ! 1394: 4) in class's scope, member name of a class's variable ! 1395: ! 1396: NAME is $1 from the bison rule. It is an IDENTIFIER_NODE. ! 1397: VALUE is $$ from the bison rule. It is the value returned by lookup_name ($1) ! 1398: yychar is the pending input character (suitably encoded :-). ! 1399: ! 1400: As a last ditch, try to look up the name as a label and return that ! 1401: address. ! 1402: ! 1403: Values which are declared as being of REFERENCE_TYPE are ! 1404: automatically dereferenced here (as a hack to make the ! 1405: compiler faster). */ ! 1406: ! 1407: tree ! 1408: hack_identifier (value, name, yychar) ! 1409: tree value, name; ! 1410: int yychar; ! 1411: { ! 1412: tree type; ! 1413: ! 1414: if (TREE_CODE (value) == ERROR_MARK) ! 1415: { ! 1416: if (current_class_name) ! 1417: { ! 1418: tree fields = lookup_fnfields (TYPE_BINFO (current_class_type), name, 1); ! 1419: if (fields == error_mark_node) ! 1420: return error_mark_node; ! 1421: if (fields) ! 1422: { ! 1423: tree fndecl; ! 1424: ! 1425: fndecl = TREE_VALUE (fields); ! 1426: my_friendly_assert (TREE_CODE (fndecl) == FUNCTION_DECL, 251); ! 1427: if (DECL_CHAIN (fndecl) == NULL_TREE) ! 1428: { ! 1429: warning ("methods cannot be converted to function pointers"); ! 1430: return fndecl; ! 1431: } ! 1432: else ! 1433: { ! 1434: error ("ambiguous request for method pointer `%s'", ! 1435: IDENTIFIER_POINTER (name)); ! 1436: return error_mark_node; ! 1437: } ! 1438: } ! 1439: } ! 1440: if (flag_labels_ok && IDENTIFIER_LABEL_VALUE (name)) ! 1441: { ! 1442: return IDENTIFIER_LABEL_VALUE (name); ! 1443: } ! 1444: return error_mark_node; ! 1445: } ! 1446: ! 1447: type = TREE_TYPE (value); ! 1448: if (TREE_CODE (value) == FIELD_DECL) ! 1449: { ! 1450: if (current_class_decl == NULL_TREE) ! 1451: { ! 1452: error ("request for member `%s' in static member function", ! 1453: IDENTIFIER_POINTER (DECL_NAME (value))); ! 1454: return error_mark_node; ! 1455: } ! 1456: TREE_USED (current_class_decl) = 1; ! 1457: if (yychar == '(') ! 1458: if (! ((TYPE_LANG_SPECIFIC (type) ! 1459: && TYPE_OVERLOADS_CALL_EXPR (type)) ! 1460: || (TREE_CODE (type) == REFERENCE_TYPE ! 1461: && TYPE_LANG_SPECIFIC (TREE_TYPE (type)) ! 1462: && TYPE_OVERLOADS_CALL_EXPR (TREE_TYPE (type)))) ! 1463: && TREE_CODE (type) != FUNCTION_TYPE ! 1464: && TREE_CODE (type) != METHOD_TYPE ! 1465: && !TYPE_PTRMEMFUNC_P (type) ! 1466: && (TREE_CODE (type) != POINTER_TYPE ! 1467: || (TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE ! 1468: && TREE_CODE (TREE_TYPE (type)) != METHOD_TYPE))) ! 1469: { ! 1470: error ("component `%s' is not a method", ! 1471: IDENTIFIER_POINTER (name)); ! 1472: return error_mark_node; ! 1473: } ! 1474: /* Mark so that if we are in a constructor, and then find that ! 1475: this field was initialized by a base initializer, ! 1476: we can emit an error message. */ ! 1477: TREE_USED (value) = 1; ! 1478: return build_component_ref (C_C_D, name, 0, 1); ! 1479: } ! 1480: ! 1481: if (really_overloaded_fn (value)) ! 1482: { ! 1483: tree t = get_first_fn (value); ! 1484: for (; t; t = DECL_CHAIN (t)) ! 1485: { ! 1486: if (TREE_CODE (t) == TEMPLATE_DECL) ! 1487: continue; ! 1488: ! 1489: assemble_external (t); ! 1490: TREE_USED (t) = 1; ! 1491: } ! 1492: } ! 1493: else if (TREE_CODE (value) == TREE_LIST) ! 1494: { ! 1495: tree t = value; ! 1496: while (t && TREE_CODE (t) == TREE_LIST) ! 1497: { ! 1498: assemble_external (TREE_VALUE (t)); ! 1499: TREE_USED (t) = 1; ! 1500: t = TREE_CHAIN (t); ! 1501: } ! 1502: } ! 1503: else ! 1504: { ! 1505: assemble_external (value); ! 1506: TREE_USED (value) = 1; ! 1507: } ! 1508: ! 1509: if (TREE_CODE_CLASS (TREE_CODE (value)) == 'd' && DECL_NONLOCAL (value)) ! 1510: { ! 1511: if (DECL_LANG_SPECIFIC (value) ! 1512: && DECL_CLASS_CONTEXT (value) != current_class_type) ! 1513: { ! 1514: tree path; ! 1515: enum access_type access; ! 1516: register tree context ! 1517: = (TREE_CODE (value) == FUNCTION_DECL && DECL_VIRTUAL_P (value)) ! 1518: ? DECL_CLASS_CONTEXT (value) ! 1519: : DECL_CONTEXT (value); ! 1520: ! 1521: get_base_distance (context, current_class_type, 0, &path); ! 1522: if (path) ! 1523: { ! 1524: access = compute_access (path, value); ! 1525: if (access != access_public) ! 1526: { ! 1527: if (TREE_CODE (value) == VAR_DECL) ! 1528: error ("static member `%s' is %s", ! 1529: IDENTIFIER_POINTER (name), ! 1530: TREE_PRIVATE (value) ? "private" : ! 1531: "from a private base class"); ! 1532: else ! 1533: error ("enum `%s' is from private base class", ! 1534: IDENTIFIER_POINTER (name)); ! 1535: return error_mark_node; ! 1536: } ! 1537: } ! 1538: } ! 1539: return value; ! 1540: } ! 1541: if (TREE_CODE (value) == TREE_LIST && TREE_NONLOCAL_FLAG (value)) ! 1542: { ! 1543: if (type == 0) ! 1544: { ! 1545: error ("request for member `%s' is ambiguous in multiple inheritance lattice", ! 1546: IDENTIFIER_POINTER (name)); ! 1547: return error_mark_node; ! 1548: } ! 1549: ! 1550: return value; ! 1551: } ! 1552: ! 1553: if (TREE_CODE (type) == REFERENCE_TYPE) ! 1554: { ! 1555: my_friendly_assert (TREE_CODE (value) == VAR_DECL ! 1556: || TREE_CODE (value) == PARM_DECL ! 1557: || TREE_CODE (value) == RESULT_DECL, 252); ! 1558: if (DECL_REFERENCE_SLOT (value)) ! 1559: return DECL_REFERENCE_SLOT (value); ! 1560: } ! 1561: return value; ! 1562: } ! 1563: ! 1564: ! 1565: #if 0 ! 1566: /* Given an object OF, and a type conversion operator COMPONENT ! 1567: build a call to the conversion operator, if a call is requested, ! 1568: or return the address (as a pointer to member function) if one is not. ! 1569: ! 1570: OF can be a TYPE_DECL or any kind of datum that would normally ! 1571: be passed to `build_component_ref'. It may also be NULL_TREE, ! 1572: in which case `current_class_type' and `current_class_decl' ! 1573: provide default values. ! 1574: ! 1575: BASETYPE_PATH, if non-null, is the path of basetypes ! 1576: to go through before we get the the instance of interest. ! 1577: ! 1578: PROTECT says whether we apply C++ scoping rules or not. */ ! 1579: tree ! 1580: build_component_type_expr (of, component, basetype_path, protect) ! 1581: tree of, component, basetype_path; ! 1582: int protect; ! 1583: { ! 1584: tree cname = NULL_TREE; ! 1585: tree tmp, last; ! 1586: tree name; ! 1587: int flags = protect ? LOOKUP_NORMAL : LOOKUP_COMPLAIN; ! 1588: ! 1589: if (of) ! 1590: my_friendly_assert (IS_AGGR_TYPE (TREE_TYPE (of)), 253); ! 1591: my_friendly_assert (TREE_CODE (component) == TYPE_EXPR, 254); ! 1592: ! 1593: tmp = TREE_OPERAND (component, 0); ! 1594: last = NULL_TREE; ! 1595: ! 1596: while (tmp) ! 1597: { ! 1598: switch (TREE_CODE (tmp)) ! 1599: { ! 1600: case CALL_EXPR: ! 1601: if (last) ! 1602: TREE_OPERAND (last, 0) = TREE_OPERAND (tmp, 0); ! 1603: else ! 1604: TREE_OPERAND (component, 0) = TREE_OPERAND (tmp, 0); ! 1605: ! 1606: last = groktypename (build_tree_list (TREE_TYPE (component), ! 1607: TREE_OPERAND (component, 0))); ! 1608: name = build_typename_overload (last); ! 1609: TREE_TYPE (name) = last; ! 1610: ! 1611: if (TREE_OPERAND (tmp, 0) ! 1612: && TREE_OPERAND (tmp, 0) != void_list_node) ! 1613: { ! 1614: cp_error ("`operator %T' requires empty parameter list", last); ! 1615: TREE_OPERAND (tmp, 0) = NULL_TREE; ! 1616: } ! 1617: ! 1618: if (of && TREE_CODE (of) != TYPE_DECL) ! 1619: return build_method_call (of, name, NULL_TREE, NULL_TREE, flags); ! 1620: else if (of) ! 1621: { ! 1622: tree this_this; ! 1623: ! 1624: if (current_class_decl == NULL_TREE) ! 1625: { ! 1626: cp_error ("object required for `operator %T' call", ! 1627: TREE_TYPE (name)); ! 1628: return error_mark_node; ! 1629: } ! 1630: ! 1631: this_this = convert_pointer_to (TREE_TYPE (of), ! 1632: current_class_decl); ! 1633: this_this = build_indirect_ref (this_this, NULL_PTR); ! 1634: return build_method_call (this_this, name, NULL_TREE, ! 1635: NULL_TREE, flags | LOOKUP_NONVIRTUAL); ! 1636: } ! 1637: else if (current_class_decl) ! 1638: return build_method_call (tmp, name, NULL_TREE, NULL_TREE, flags); ! 1639: ! 1640: cp_error ("object required for `operator %T' call", ! 1641: TREE_TYPE (name)); ! 1642: return error_mark_node; ! 1643: ! 1644: case INDIRECT_REF: ! 1645: case ADDR_EXPR: ! 1646: case ARRAY_REF: ! 1647: break; ! 1648: ! 1649: case SCOPE_REF: ! 1650: my_friendly_assert (cname == 0, 255); ! 1651: cname = TREE_OPERAND (tmp, 0); ! 1652: tmp = TREE_OPERAND (tmp, 1); ! 1653: break; ! 1654: ! 1655: default: ! 1656: my_friendly_abort (77); ! 1657: } ! 1658: last = tmp; ! 1659: tmp = TREE_OPERAND (tmp, 0); ! 1660: } ! 1661: ! 1662: last = groktypename (build_tree_list (TREE_TYPE (component), TREE_OPERAND (component, 0))); ! 1663: name = build_typename_overload (last); ! 1664: TREE_TYPE (name) = last; ! 1665: if (of && TREE_CODE (of) == TYPE_DECL) ! 1666: { ! 1667: if (cname == NULL_TREE) ! 1668: { ! 1669: cname = DECL_NAME (of); ! 1670: of = NULL_TREE; ! 1671: } ! 1672: else my_friendly_assert (cname == DECL_NAME (of), 256); ! 1673: } ! 1674: ! 1675: if (of) ! 1676: { ! 1677: tree this_this; ! 1678: ! 1679: if (current_class_decl == NULL_TREE) ! 1680: { ! 1681: cp_error ("object required for `operator %T' call", ! 1682: TREE_TYPE (name)); ! 1683: return error_mark_node; ! 1684: } ! 1685: ! 1686: this_this = convert_pointer_to (TREE_TYPE (of), current_class_decl); ! 1687: return build_component_ref (this_this, name, 0, protect); ! 1688: } ! 1689: else if (cname) ! 1690: return build_offset_ref (cname, name); ! 1691: else if (current_class_name) ! 1692: return build_offset_ref (current_class_name, name); ! 1693: ! 1694: cp_error ("object required for `operator %T' member reference", ! 1695: TREE_TYPE (name)); ! 1696: return error_mark_node; ! 1697: } ! 1698: #endif ! 1699: ! 1700: static char * ! 1701: thunk_printable_name (decl) ! 1702: tree decl; ! 1703: { ! 1704: return "<thunk function>"; ! 1705: } ! 1706: ! 1707: tree ! 1708: make_thunk (function, delta) ! 1709: tree function; ! 1710: int delta; ! 1711: { ! 1712: char buffer[250]; ! 1713: tree thunk_fndecl, thunk_id; ! 1714: tree thunk; ! 1715: char *func_name; ! 1716: static int thunk_number = 0; ! 1717: tree func_decl; ! 1718: if (TREE_CODE (function) != ADDR_EXPR) ! 1719: abort (); ! 1720: func_decl = TREE_OPERAND (function, 0); ! 1721: if (TREE_CODE (func_decl) != FUNCTION_DECL) ! 1722: abort (); ! 1723: func_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (func_decl)); ! 1724: sprintf (buffer, "__thunk_%d_%s", -delta, func_name); ! 1725: thunk_id = get_identifier (buffer); ! 1726: thunk = IDENTIFIER_GLOBAL_VALUE (thunk_id); ! 1727: if (thunk && TREE_CODE (thunk) != THUNK_DECL) ! 1728: { ! 1729: error_with_decl ("implementation-reserved name `%s' used"); ! 1730: IDENTIFIER_GLOBAL_VALUE (thunk_id) = thunk = NULL_TREE; ! 1731: } ! 1732: if (thunk == NULL_TREE) ! 1733: { ! 1734: thunk = build_decl (THUNK_DECL, thunk_id, TREE_TYPE (func_decl)); ! 1735: DECL_RESULT (thunk) ! 1736: = build_decl (RESULT_DECL, NULL_TREE, TREE_TYPE (vtable_entry_type)); ! 1737: make_function_rtl (thunk); ! 1738: DECL_INITIAL (thunk) = function; ! 1739: THUNK_DELTA (thunk) = delta; ! 1740: /* So that finish_file can write out any thunks that need to be: */ ! 1741: pushdecl_top_level (thunk); ! 1742: } ! 1743: return thunk; ! 1744: } ! 1745: ! 1746: void ! 1747: emit_thunk (thunk_fndecl) ! 1748: tree thunk_fndecl; ! 1749: { ! 1750: rtx insns; ! 1751: char *fnname; ! 1752: char buffer[250]; ! 1753: tree argp; ! 1754: struct args_size stack_args_size; ! 1755: tree function = TREE_OPERAND (DECL_INITIAL (thunk_fndecl), 0); ! 1756: int delta = THUNK_DELTA (thunk_fndecl); ! 1757: int tem; ! 1758: int failure = 0; ! 1759: int current_call_is_indirect = 0; /* needed for HPPA FUNCTION_ARG */ ! 1760: ! 1761: /* Used to remember which regs we need to emit a USE rtx for. */ ! 1762: rtx need_use[FIRST_PSEUDO_REGISTER]; ! 1763: int need_use_count = 0; ! 1764: ! 1765: /* rtx for the 'this' parameter. */ ! 1766: rtx this_rtx = 0, this_reg_rtx = 0, fixed_this_rtx; ! 1767: ! 1768: char *(*save_decl_printable_name) () = decl_printable_name; ! 1769: /* Data on reg parms scanned so far. */ ! 1770: CUMULATIVE_ARGS args_so_far; ! 1771: ! 1772: if (TREE_ASM_WRITTEN (thunk_fndecl)) ! 1773: return; ! 1774: ! 1775: TREE_ASM_WRITTEN (thunk_fndecl) = 1; ! 1776: ! 1777: if (TREE_PUBLIC (function)) ! 1778: { ! 1779: TREE_PUBLIC (thunk_fndecl) = 1; ! 1780: if (DECL_EXTERNAL (function)) ! 1781: { ! 1782: DECL_EXTERNAL (thunk_fndecl) = 1; ! 1783: assemble_external (thunk_fndecl); ! 1784: return; ! 1785: } ! 1786: } ! 1787: ! 1788: decl_printable_name = thunk_printable_name; ! 1789: if (current_function_decl) ! 1790: abort (); ! 1791: current_function_decl = thunk_fndecl; ! 1792: init_function_start (thunk_fndecl, input_filename, lineno); ! 1793: pushlevel (0); ! 1794: expand_start_bindings (1); ! 1795: ! 1796: /* Start updating where the next arg would go. */ ! 1797: INIT_CUMULATIVE_ARGS (args_so_far, TREE_TYPE (function), NULL_RTX); ! 1798: stack_args_size.constant = 0; ! 1799: stack_args_size.var = 0; ! 1800: /* SETUP for possible structure return address FIXME */ ! 1801: ! 1802: /* Now look through all the parameters, make sure that we ! 1803: don't clobber any registers used for parameters. ! 1804: Also, pick up an rtx for the first "this" parameter. */ ! 1805: for (argp = TYPE_ARG_TYPES (TREE_TYPE (function)); ! 1806: argp != NULL_TREE; ! 1807: argp = TREE_CHAIN (argp)) ! 1808: ! 1809: { ! 1810: tree passed_type = TREE_VALUE (argp); ! 1811: register rtx entry_parm; ! 1812: int named = 1; /* FIXME */ ! 1813: struct args_size stack_offset; ! 1814: struct args_size arg_size; ! 1815: ! 1816: if (passed_type == void_type_node) ! 1817: break; ! 1818: ! 1819: if ((TREE_CODE (TYPE_SIZE (passed_type)) != INTEGER_CST ! 1820: && contains_placeholder_p (TYPE_SIZE (passed_type))) ! 1821: #ifdef FUNCTION_ARG_PASS_BY_REFERENCE ! 1822: || FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, ! 1823: TYPE_MODE (passed_type), ! 1824: passed_type, named) ! 1825: #endif ! 1826: ) ! 1827: passed_type = build_pointer_type (passed_type); ! 1828: ! 1829: entry_parm = FUNCTION_ARG (args_so_far, ! 1830: TYPE_MODE (passed_type), ! 1831: passed_type, ! 1832: named); ! 1833: if (entry_parm != 0) ! 1834: need_use[need_use_count++] = entry_parm; ! 1835: ! 1836: locate_and_pad_parm (TYPE_MODE (passed_type), passed_type, ! 1837: #ifdef STACK_PARMS_IN_REG_PARM_AREA ! 1838: 1, ! 1839: #else ! 1840: entry_parm != 0, ! 1841: #endif ! 1842: thunk_fndecl, ! 1843: &stack_args_size, &stack_offset, &arg_size); ! 1844: ! 1845: /* REGNO (entry_parm);*/ ! 1846: if (this_rtx == 0) ! 1847: { ! 1848: this_reg_rtx = entry_parm; ! 1849: if (!entry_parm) ! 1850: { ! 1851: rtx offset_rtx = ARGS_SIZE_RTX (stack_offset); ! 1852: ! 1853: rtx internal_arg_pointer, stack_parm; ! 1854: ! 1855: if ((ARG_POINTER_REGNUM == STACK_POINTER_REGNUM ! 1856: || ! (fixed_regs[ARG_POINTER_REGNUM] ! 1857: || ARG_POINTER_REGNUM == FRAME_POINTER_REGNUM))) ! 1858: internal_arg_pointer = copy_to_reg (virtual_incoming_args_rtx); ! 1859: else ! 1860: internal_arg_pointer = virtual_incoming_args_rtx; ! 1861: ! 1862: if (offset_rtx == const0_rtx) ! 1863: entry_parm = gen_rtx (MEM, TYPE_MODE (passed_type), ! 1864: internal_arg_pointer); ! 1865: else ! 1866: entry_parm = gen_rtx (MEM, TYPE_MODE (passed_type), ! 1867: gen_rtx (PLUS, Pmode, ! 1868: internal_arg_pointer, ! 1869: offset_rtx)); ! 1870: } ! 1871: ! 1872: this_rtx = entry_parm; ! 1873: } ! 1874: ! 1875: FUNCTION_ARG_ADVANCE (args_so_far, ! 1876: TYPE_MODE (passed_type), ! 1877: passed_type, ! 1878: named); ! 1879: } ! 1880: ! 1881: fixed_this_rtx = plus_constant (this_rtx, delta); ! 1882: if (this_rtx != fixed_this_rtx) ! 1883: emit_move_insn (this_rtx, fixed_this_rtx); ! 1884: ! 1885: if (this_reg_rtx) ! 1886: emit_insn (gen_rtx (USE, VOIDmode, this_reg_rtx)); ! 1887: ! 1888: emit_indirect_jump (XEXP (DECL_RTL (function), 0)); ! 1889: ! 1890: while (need_use_count > 0) ! 1891: emit_insn (gen_rtx (USE, VOIDmode, need_use[--need_use_count])); ! 1892: ! 1893: expand_end_bindings (NULL, 1, 0); ! 1894: poplevel (0, 0, 0); ! 1895: ! 1896: /* From now on, allocate rtl in current_obstack, not in saveable_obstack. ! 1897: Note that that may have been done above, in save_for_inline_copying. ! 1898: The call to resume_temporary_allocation near the end of this function ! 1899: goes back to the usual state of affairs. */ ! 1900: ! 1901: rtl_in_current_obstack (); ! 1902: ! 1903: insns = get_insns (); ! 1904: ! 1905: /* Copy any shared structure that should not be shared. */ ! 1906: ! 1907: unshare_all_rtl (insns); ! 1908: ! 1909: /* We are no longer anticipating cse in this function, at least. */ ! 1910: ! 1911: cse_not_expected = 1; ! 1912: ! 1913: /* Now we choose between stupid (pcc-like) register allocation ! 1914: (if we got the -noreg switch and not -opt) ! 1915: and smart register allocation. */ ! 1916: ! 1917: if (optimize > 0) /* Stupid allocation probably won't work */ ! 1918: obey_regdecls = 0; /* if optimizations being done. */ ! 1919: ! 1920: regclass_init (); ! 1921: ! 1922: regclass (insns, max_reg_num ()); ! 1923: if (obey_regdecls) ! 1924: { ! 1925: stupid_life_analysis (insns, max_reg_num (), NULL); ! 1926: failure = reload (insns, 0, NULL); ! 1927: } ! 1928: else ! 1929: { ! 1930: /* Do control and data flow analysis, ! 1931: and write some of the results to dump file. */ ! 1932: ! 1933: flow_analysis (insns, max_reg_num (), NULL); ! 1934: local_alloc (); ! 1935: failure = global_alloc (NULL); ! 1936: } ! 1937: ! 1938: reload_completed = 1; ! 1939: ! 1940: #ifdef LEAF_REGISTERS ! 1941: leaf_function = 0; ! 1942: if (optimize > 0 && only_leaf_regs_used () && leaf_function_p ()) ! 1943: leaf_function = 1; ! 1944: #endif ! 1945: ! 1946: /* If a machine dependent reorganization is needed, call it. */ ! 1947: #ifdef MACHINE_DEPENDENT_REORG ! 1948: MACHINE_DEPENDENT_REORG (insns); ! 1949: #endif ! 1950: ! 1951: /* Now turn the rtl into assembler code. */ ! 1952: ! 1953: { ! 1954: char *fnname = XSTR (XEXP (DECL_RTL (thunk_fndecl), 0), 0); ! 1955: assemble_start_function (thunk_fndecl, fnname); ! 1956: final (insns, asm_out_file, optimize, 0); ! 1957: assemble_end_function (thunk_fndecl, fnname); ! 1958: }; ! 1959: ! 1960: exit_rest_of_compilation: ! 1961: ! 1962: reload_completed = 0; ! 1963: ! 1964: /* Cancel the effect of rtl_in_current_obstack. */ ! 1965: ! 1966: resume_temporary_allocation (); ! 1967: ! 1968: decl_printable_name = save_decl_printable_name; ! 1969: current_function_decl = 0; ! 1970: } ! 1971: ! 1972: /* Code for synthesizing methods which have default semantics defined. */ ! 1973: ! 1974: void ! 1975: build_default_constructor (fndecl) ! 1976: tree fndecl; ! 1977: { ! 1978: start_function (NULL_TREE, fndecl, NULL_TREE, 1); ! 1979: store_parm_decls (); ! 1980: setup_vtbl_ptr (); ! 1981: finish_function (lineno, 0); ! 1982: } ! 1983: ! 1984: /* For the anonymous union in TYPE, return the member that is at least as ! 1985: large as the rest of the members, so we can copy it. */ ! 1986: static tree ! 1987: largest_union_member (type) ! 1988: tree type; ! 1989: { ! 1990: tree f, type_size = TYPE_SIZE (type); ! 1991: ! 1992: for (f = TYPE_FIELDS (type); f; f = TREE_CHAIN (f)) ! 1993: if (simple_cst_equal (DECL_SIZE (f), type_size)) ! 1994: return f; ! 1995: ! 1996: /* We should always find one. */ ! 1997: my_friendly_abort (323); ! 1998: return NULL_TREE; ! 1999: } ! 2000: ! 2001: /* Generate code for default X(X&) constructor. */ ! 2002: void ! 2003: build_copy_constructor (fndecl) ! 2004: tree fndecl; ! 2005: { ! 2006: tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl)); ! 2007: tree t; ! 2008: ! 2009: start_function (NULL_TREE, fndecl, NULL_TREE, 1); ! 2010: store_parm_decls (); ! 2011: clear_last_expr (); ! 2012: push_momentary (); ! 2013: ! 2014: if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) ! 2015: parm = TREE_CHAIN (parm); ! 2016: parm = convert_from_reference (parm); ! 2017: ! 2018: if (! TYPE_HAS_COMPLEX_INIT_REF (current_class_type)) ! 2019: { ! 2020: t = build (INIT_EXPR, void_type_node, C_C_D, parm); ! 2021: TREE_SIDE_EFFECTS (t) = 1; ! 2022: cplus_expand_expr_stmt (t); ! 2023: } ! 2024: else ! 2025: { ! 2026: tree fields = TYPE_FIELDS (current_class_type); ! 2027: int n_bases = CLASSTYPE_N_BASECLASSES (current_class_type); ! 2028: tree binfos = TYPE_BINFO_BASETYPES (current_class_type); ! 2029: int i; ! 2030: ! 2031: for (t = CLASSTYPE_VBASECLASSES (current_class_type); t; ! 2032: t = TREE_CHAIN (t)) ! 2033: { ! 2034: tree basetype = BINFO_TYPE (t); ! 2035: tree p = convert (build_reference_type (basetype), parm); ! 2036: p = convert_from_reference (p); ! 2037: current_base_init_list = tree_cons (TYPE_NESTED_NAME (basetype), ! 2038: p, current_base_init_list); ! 2039: } ! 2040: ! 2041: for (i = 0; i < n_bases; ++i) ! 2042: { ! 2043: tree p, basetype = TREE_VEC_ELT (binfos, i); ! 2044: if (TREE_VIA_VIRTUAL (basetype)) ! 2045: continue; ! 2046: ! 2047: basetype = BINFO_TYPE (basetype); ! 2048: p = convert (build_reference_type (basetype), parm); ! 2049: p = convert_from_reference (p); ! 2050: current_base_init_list = tree_cons (TYPE_NESTED_NAME (basetype), ! 2051: p, current_base_init_list); ! 2052: } ! 2053: for (; fields; fields = TREE_CHAIN (fields)) ! 2054: { ! 2055: tree name, init, t; ! 2056: if (TREE_CODE (fields) != FIELD_DECL) ! 2057: continue; ! 2058: if (DECL_NAME (fields)) ! 2059: { ! 2060: if (VFIELD_NAME_P (DECL_NAME (fields))) ! 2061: continue; ! 2062: if (VBASE_NAME_P (DECL_NAME (fields))) ! 2063: continue; ! 2064: ! 2065: /* True for duplicate members. */ ! 2066: if (IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) != fields) ! 2067: continue; ! 2068: } ! 2069: else if ((t = TREE_TYPE (fields)) != NULL_TREE ! 2070: && TREE_CODE (t) == UNION_TYPE ! 2071: && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)) ! 2072: && TYPE_FIELDS (t) != NULL_TREE) ! 2073: fields = largest_union_member (t); ! 2074: else ! 2075: continue; ! 2076: ! 2077: init = build (COMPONENT_REF, TREE_TYPE (fields), parm, fields); ! 2078: init = build_tree_list (NULL_TREE, init); ! 2079: ! 2080: current_member_init_list ! 2081: = tree_cons (DECL_NAME (fields), init, current_member_init_list); ! 2082: } ! 2083: current_member_init_list = nreverse (current_member_init_list); ! 2084: setup_vtbl_ptr (); ! 2085: } ! 2086: ! 2087: pop_momentary (); ! 2088: finish_function (lineno, 0); ! 2089: } ! 2090: ! 2091: void ! 2092: build_assign_ref (fndecl) ! 2093: tree fndecl; ! 2094: { ! 2095: tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl)); ! 2096: ! 2097: start_function (NULL_TREE, fndecl, NULL_TREE, 1); ! 2098: store_parm_decls (); ! 2099: push_momentary (); ! 2100: ! 2101: parm = convert_from_reference (parm); ! 2102: ! 2103: if (! TYPE_HAS_COMPLEX_ASSIGN_REF (current_class_type)) ! 2104: { ! 2105: tree t = build (MODIFY_EXPR, void_type_node, C_C_D, parm); ! 2106: TREE_SIDE_EFFECTS (t) = 1; ! 2107: cplus_expand_expr_stmt (t); ! 2108: } ! 2109: else ! 2110: { ! 2111: tree fields = TYPE_FIELDS (current_class_type); ! 2112: int n_bases = CLASSTYPE_N_BASECLASSES (current_class_type); ! 2113: tree binfos = TYPE_BINFO_BASETYPES (current_class_type); ! 2114: int i; ! 2115: ! 2116: for (i = 0; i < n_bases; ++i) ! 2117: { ! 2118: tree basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, i)); ! 2119: if (TYPE_HAS_ASSIGN_REF (basetype)) ! 2120: { ! 2121: tree p = convert (build_reference_type (basetype), parm); ! 2122: p = convert_from_reference (p); ! 2123: p = build_member_call (TYPE_NESTED_NAME (basetype), ! 2124: ansi_opname [MODIFY_EXPR], ! 2125: build_tree_list (NULL_TREE, p)); ! 2126: expand_expr_stmt (p); ! 2127: } ! 2128: } ! 2129: for (; fields; fields = TREE_CHAIN (fields)) ! 2130: { ! 2131: tree comp, init, t; ! 2132: if (TREE_CODE (fields) != FIELD_DECL) ! 2133: continue; ! 2134: if (DECL_NAME (fields)) ! 2135: { ! 2136: if (VFIELD_NAME_P (DECL_NAME (fields))) ! 2137: continue; ! 2138: if (VBASE_NAME_P (DECL_NAME (fields))) ! 2139: continue; ! 2140: ! 2141: /* True for duplicate members. */ ! 2142: if (IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) != fields) ! 2143: continue; ! 2144: } ! 2145: else if ((t = TREE_TYPE (fields)) != NULL_TREE ! 2146: && TREE_CODE (t) == UNION_TYPE ! 2147: && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)) ! 2148: && TYPE_FIELDS (t) != NULL_TREE) ! 2149: fields = largest_union_member (t); ! 2150: else ! 2151: continue; ! 2152: ! 2153: comp = build (COMPONENT_REF, TREE_TYPE (fields), C_C_D, fields); ! 2154: init = build (COMPONENT_REF, TREE_TYPE (fields), parm, fields); ! 2155: ! 2156: expand_expr_stmt (build_modify_expr (comp, NOP_EXPR, init)); ! 2157: } ! 2158: } ! 2159: c_expand_return (C_C_D); ! 2160: pop_momentary (); ! 2161: finish_function (lineno, 0); ! 2162: } ! 2163: ! 2164: void ! 2165: build_dtor (fndecl) ! 2166: tree fndecl; ! 2167: { ! 2168: start_function (NULL_TREE, fndecl, NULL_TREE, 1); ! 2169: store_parm_decls (); ! 2170: finish_function (lineno, 0); ! 2171: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.