|
|
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 "cp-class.h" ! 33: #include "obstack.h" ! 34: #include <ctype.h> ! 35: ! 36: /* TREE_LIST of the current inline functions that need to be ! 37: processed. */ ! 38: struct pending_inline *pending_inlines; ! 39: ! 40: #define obstack_chunk_alloc xmalloc ! 41: #define obstack_chunk_free free ! 42: ! 43: /* Obstack where we build text strings for overloading, etc. */ ! 44: static struct obstack scratch_obstack; ! 45: static char *scratch_firstobj; ! 46: ! 47: # define OB_INIT() (scratch_firstobj ? (obstack_free (&scratch_obstack, scratch_firstobj), 0) : 0) ! 48: # define OB_PUTC(C) (obstack_1grow (&scratch_obstack, (C))) ! 49: # define OB_PUTC2(C1,C2) \ ! 50: (obstack_1grow (&scratch_obstack, (C1)), obstack_1grow (&scratch_obstack, (C2))) ! 51: # define OB_PUTS(S) (obstack_grow (&scratch_obstack, (S), sizeof (S) - 1)) ! 52: # define OB_PUTID(ID) \ ! 53: (obstack_grow (&scratch_obstack, IDENTIFIER_POINTER (ID), \ ! 54: IDENTIFIER_LENGTH (ID))) ! 55: # define OB_PUTCP(S) (obstack_grow (&scratch_obstack, (S), strlen (S))) ! 56: # define OB_FINISH() (obstack_1grow (&scratch_obstack, '\0')) ! 57: ! 58: #ifdef NO_AUTO_OVERLOAD ! 59: int is_overloaded (); ! 60: #endif ! 61: ! 62: void ! 63: init_method () ! 64: { ! 65: gcc_obstack_init (&scratch_obstack); ! 66: scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0); ! 67: } ! 68: ! 69: /* This must be large enough to hold any printed integer or floating-point ! 70: value. */ ! 71: static char digit_buffer[128]; ! 72: ! 73: /* Move inline function definitions out of structure so that they ! 74: can be processed normally. CNAME is the name of the class ! 75: we are working from, METHOD_LIST is the list of method lists ! 76: of the structure. We delete friend methods here, after ! 77: saving away their inline function definitions (if any). */ ! 78: ! 79: void ! 80: do_inline_function_hair (type, friend_list) ! 81: tree type, friend_list; ! 82: { ! 83: tree method = TYPE_METHODS (type); ! 84: ! 85: if (method && TREE_CODE (method) == TREE_VEC) ! 86: { ! 87: if (TREE_VEC_ELT (method, 0)) ! 88: method = TREE_VEC_ELT (method, 0); ! 89: else ! 90: method = TREE_VEC_ELT (method, 1); ! 91: } ! 92: ! 93: while (method) ! 94: { ! 95: /* Do inline member functions. */ ! 96: struct pending_inline *info = DECL_PENDING_INLINE_INFO (method); ! 97: if (info) ! 98: { ! 99: tree args; ! 100: ! 101: my_friendly_assert (info->fndecl == method, 238); ! 102: args = DECL_ARGUMENTS (method); ! 103: while (args) ! 104: { ! 105: DECL_CONTEXT (args) = method; ! 106: args = TREE_CHAIN (args); ! 107: } ! 108: ! 109: /* Allow this decl to be seen in global scope */ ! 110: IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (method)) = method; ! 111: } ! 112: method = TREE_CHAIN (method); ! 113: } ! 114: while (friend_list) ! 115: { ! 116: tree fndecl = TREE_VALUE (friend_list); ! 117: struct pending_inline *info = DECL_PENDING_INLINE_INFO (fndecl); ! 118: if (info) ! 119: { ! 120: tree args; ! 121: ! 122: my_friendly_assert (info->fndecl == fndecl, 239); ! 123: args = DECL_ARGUMENTS (fndecl); ! 124: while (args) ! 125: { ! 126: DECL_CONTEXT (args) = fndecl; ! 127: args = TREE_CHAIN (args); ! 128: } ! 129: ! 130: /* Allow this decl to be seen in global scope */ ! 131: IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (fndecl)) = fndecl; ! 132: } ! 133: ! 134: friend_list = TREE_CHAIN (friend_list); ! 135: } ! 136: } ! 137: ! 138: /* Report an argument type mismatch between the best declared function ! 139: we could find and the current argument list that we have. */ ! 140: void ! 141: report_type_mismatch (cp, parmtypes, name_kind, err_name) ! 142: struct candidate *cp; ! 143: tree parmtypes; ! 144: char *name_kind, *err_name; ! 145: { ! 146: int i = cp->u.bad_arg; ! 147: tree ttf, tta; ! 148: char *tmp_firstobj; ! 149: ! 150: switch (i) ! 151: { ! 152: case -4: ! 153: my_friendly_assert (TREE_CODE (cp->function) == TEMPLATE_DECL, 240); ! 154: error ("type unification failed for function template `%s'", err_name); ! 155: return; ! 156: ! 157: case -3: ! 158: if (TYPE_READONLY (TREE_TYPE (TREE_VALUE (parmtypes)))) ! 159: error ("call to const %s `%s' with non-const object", name_kind, err_name); ! 160: else ! 161: error ("call to non-const %s `%s' with const object", name_kind, err_name); ! 162: return; ! 163: case -2: ! 164: error ("too few arguments for %s `%s'", name_kind, err_name); ! 165: return; ! 166: case -1: ! 167: error ("too many arguments for %s `%s'", name_kind, err_name); ! 168: return; ! 169: case 0: ! 170: if (TREE_CODE (TREE_TYPE (cp->function)) == METHOD_TYPE) ! 171: { ! 172: /* Happens when we have an ambiguous base class. */ ! 173: my_friendly_assert (get_binfo (DECL_CLASS_CONTEXT (cp->function), ! 174: TREE_TYPE (TREE_TYPE (TREE_VALUE (parmtypes))), 1) == error_mark_node, ! 175: 241); ! 176: return; ! 177: } ! 178: } ! 179: ! 180: ttf = TYPE_ARG_TYPES (TREE_TYPE (cp->function)); ! 181: tta = parmtypes; ! 182: ! 183: while (i-- > 0) ! 184: { ! 185: ttf = TREE_CHAIN (ttf); ! 186: tta = TREE_CHAIN (tta); ! 187: } ! 188: ! 189: OB_INIT (); ! 190: OB_PUTS ("bad argument "); ! 191: sprintf (digit_buffer, "%d", cp->u.bad_arg ! 192: - (TREE_CODE (TREE_TYPE (cp->function)) == METHOD_TYPE) ! 193: + 1); ! 194: OB_PUTCP (digit_buffer); ! 195: ! 196: OB_PUTS (" for function `"); ! 197: OB_PUTCP (decl_as_string (cp->function, 1)); ! 198: OB_PUTS ("' (type was "); ! 199: ! 200: /* Reset `i' so that type printing routines do the right thing. */ ! 201: if (tta) ! 202: { ! 203: enum tree_code code = TREE_CODE (TREE_TYPE (TREE_VALUE (tta))); ! 204: if (code == ERROR_MARK) ! 205: OB_PUTS ("(failed type instantiation)"); ! 206: else ! 207: { ! 208: i = (code == FUNCTION_TYPE || code == METHOD_TYPE); ! 209: OB_PUTCP (type_as_string (TREE_TYPE (TREE_VALUE (tta)), 1)); ! 210: } ! 211: } ! 212: else OB_PUTS ("void"); ! 213: OB_PUTC (')'); ! 214: OB_FINISH (); ! 215: ! 216: tmp_firstobj = (char *)alloca (obstack_object_size (&scratch_obstack)); ! 217: bcopy (obstack_base (&scratch_obstack), tmp_firstobj, ! 218: obstack_object_size (&scratch_obstack)); ! 219: error (tmp_firstobj); ! 220: } ! 221: ! 222: /* Here is where overload code starts. */ ! 223: ! 224: /* Array of types seen so far in top-level call to `build_overload_name'. ! 225: Allocated and deallocated by caller. */ ! 226: static tree *typevec; ! 227: ! 228: /* Number of types interned by `build_overload_name' so far. */ ! 229: static int maxtype; ! 230: ! 231: /* Number of occurrences of last type seen. */ ! 232: static int nrepeats; ! 233: ! 234: /* Nonzero if we should not try folding parameter types. */ ! 235: static int nofold; ! 236: ! 237: #define ALLOCATE_TYPEVEC(PARMTYPES) \ ! 238: do { maxtype = 0, nrepeats = 0; \ ! 239: typevec = (tree *)alloca (list_length (PARMTYPES) * sizeof (tree)); } while (0) ! 240: ! 241: #define DEALLOCATE_TYPEVEC(PARMTYPES) \ ! 242: do { tree t = (PARMTYPES); \ ! 243: while (t) { TREE_USED (TREE_VALUE (t)) = 0; t = TREE_CHAIN (t); } \ ! 244: } while (0) ! 245: ! 246: /* Code to concatenate an asciified integer to a string. */ ! 247: static ! 248: #ifdef __GNUC__ ! 249: __inline ! 250: #endif ! 251: void ! 252: icat (i) ! 253: int i; ! 254: { ! 255: /* Handle this case first, to go really quickly. For many common values, ! 256: the result of i/10 below is 1. */ ! 257: if (i == 1) ! 258: { ! 259: OB_PUTC ('1'); ! 260: return; ! 261: } ! 262: ! 263: if (i < 0) ! 264: { ! 265: OB_PUTC ('m'); ! 266: i = -i; ! 267: } ! 268: if (i < 10) ! 269: OB_PUTC ('0' + i); ! 270: else ! 271: { ! 272: icat (i / 10); ! 273: OB_PUTC ('0' + (i % 10)); ! 274: } ! 275: } ! 276: ! 277: static ! 278: #ifdef __GNUC__ ! 279: __inline ! 280: #endif ! 281: void ! 282: flush_repeats (type) ! 283: tree type; ! 284: { ! 285: int tindex = 0; ! 286: ! 287: while (typevec[tindex] != type) ! 288: tindex++; ! 289: ! 290: if (nrepeats > 1) ! 291: { ! 292: OB_PUTC ('N'); ! 293: icat (nrepeats); ! 294: if (nrepeats > 9) ! 295: OB_PUTC ('_'); ! 296: } ! 297: else ! 298: OB_PUTC ('T'); ! 299: nrepeats = 0; ! 300: icat (tindex); ! 301: if (tindex > 9) ! 302: OB_PUTC ('_'); ! 303: } ! 304: ! 305: static void build_overload_identifier (); ! 306: ! 307: static void ! 308: build_overload_nested_name (context) ! 309: tree context; ! 310: { ! 311: /* We use DECL_NAME here, because pushtag now sets the DECL_ASSEMBLER_NAME. */ ! 312: tree name = DECL_NAME (context); ! 313: if (DECL_CONTEXT (context)) ! 314: { ! 315: context = DECL_CONTEXT (context); ! 316: if (TREE_CODE_CLASS (TREE_CODE (context)) == 't') ! 317: context = TYPE_NAME (context); ! 318: build_overload_nested_name (context); ! 319: } ! 320: build_overload_identifier (name); ! 321: } ! 322: ! 323: static void ! 324: build_overload_value (type, value) ! 325: tree type, value; ! 326: { ! 327: while (TREE_CODE (value) == NON_LVALUE_EXPR ! 328: || TREE_CODE (value) == NOP_EXPR) ! 329: value = TREE_OPERAND (value, 0); ! 330: my_friendly_assert (TREE_CODE (type) == PARM_DECL, 242); ! 331: type = TREE_TYPE (type); ! 332: switch (TREE_CODE (type)) ! 333: { ! 334: case INTEGER_TYPE: ! 335: case ENUMERAL_TYPE: ! 336: { ! 337: my_friendly_assert (TREE_CODE (value) == INTEGER_CST, 243); ! 338: if (TYPE_PRECISION (value) == 2 * HOST_BITS_PER_WIDE_INT) ! 339: { ! 340: if (tree_int_cst_lt (value, integer_zero_node)) ! 341: { ! 342: OB_PUTC ('m'); ! 343: value = build_int_2 (~ TREE_INT_CST_LOW (value), ! 344: - TREE_INT_CST_HIGH (value)); ! 345: } ! 346: if (TREE_INT_CST_HIGH (value) ! 347: != (TREE_INT_CST_LOW (value) >> (HOST_BITS_PER_WIDE_INT - 1))) ! 348: { ! 349: /* need to print a DImode value in decimal */ ! 350: sorry ("conversion of long long as PT parameter"); ! 351: } ! 352: /* else fall through to print in smaller mode */ ! 353: } ! 354: /* Wordsize or smaller */ ! 355: icat (TREE_INT_CST_LOW (value)); ! 356: return; ! 357: } ! 358: #ifndef REAL_IS_NOT_DOUBLE ! 359: case REAL_TYPE: ! 360: { ! 361: REAL_VALUE_TYPE val; ! 362: char *bufp = digit_buffer; ! 363: extern char *index (); ! 364: ! 365: my_friendly_assert (TREE_CODE (value) == REAL_CST, 244); ! 366: val = TREE_REAL_CST (value); ! 367: if (val < 0) ! 368: { ! 369: val = -val; ! 370: *bufp++ = 'm'; ! 371: } ! 372: sprintf (bufp, "%e", val); ! 373: bufp = (char *) index (bufp, 'e'); ! 374: if (!bufp) ! 375: strcat (digit_buffer, "e0"); ! 376: else ! 377: { ! 378: char *p; ! 379: bufp++; ! 380: if (*bufp == '-') ! 381: { ! 382: *bufp++ = 'm'; ! 383: } ! 384: p = bufp; ! 385: if (*p == '+') ! 386: p++; ! 387: while (*p == '0') ! 388: p++; ! 389: if (*p == 0) ! 390: { ! 391: *bufp++ = '0'; ! 392: *bufp = 0; ! 393: } ! 394: else if (p != bufp) ! 395: { ! 396: while (*p) ! 397: *bufp++ = *p++; ! 398: *bufp = 0; ! 399: } ! 400: } ! 401: OB_PUTCP (digit_buffer); ! 402: return; ! 403: } ! 404: #endif ! 405: case POINTER_TYPE: ! 406: value = TREE_OPERAND (value, 0); ! 407: if (TREE_CODE (value) == VAR_DECL) ! 408: { ! 409: my_friendly_assert (DECL_NAME (value) != 0, 245); ! 410: build_overload_identifier (DECL_NAME (value)); ! 411: return; ! 412: } ! 413: else if (TREE_CODE (value) == FUNCTION_DECL) ! 414: { ! 415: my_friendly_assert (DECL_NAME (value) != 0, 246); ! 416: build_overload_identifier (DECL_NAME (value)); ! 417: return; ! 418: } ! 419: else ! 420: my_friendly_abort (71); ! 421: break; /* not really needed */ ! 422: ! 423: default: ! 424: sorry ("conversion of %s as template parameter", ! 425: tree_code_name [(int) TREE_CODE (type)]); ! 426: my_friendly_abort (72); ! 427: } ! 428: } ! 429: ! 430: static void ! 431: build_overload_identifier (name) ! 432: tree name; ! 433: { ! 434: if (IDENTIFIER_TEMPLATE (name)) ! 435: { ! 436: tree template, parmlist, arglist, tname; ! 437: int i, nparms; ! 438: template = IDENTIFIER_TEMPLATE (name); ! 439: arglist = TREE_VALUE (template); ! 440: template = TREE_PURPOSE (template); ! 441: tname = DECL_NAME (template); ! 442: parmlist = DECL_ARGUMENTS (template); ! 443: nparms = TREE_VEC_LENGTH (parmlist); ! 444: OB_PUTC ('t'); ! 445: icat (IDENTIFIER_LENGTH (tname)); ! 446: OB_PUTID (tname); ! 447: icat (nparms); ! 448: for (i = 0; i < nparms; i++) ! 449: { ! 450: tree parm = TREE_VEC_ELT (parmlist, i); ! 451: tree arg = TREE_VEC_ELT (arglist, i); ! 452: if (TREE_CODE (parm) == IDENTIFIER_NODE) ! 453: { ! 454: /* This parameter is a type. */ ! 455: OB_PUTC ('Z'); ! 456: build_overload_name (arg, 0, 0); ! 457: } ! 458: else ! 459: { ! 460: /* It's a PARM_DECL. */ ! 461: build_overload_name (TREE_TYPE (parm), 0, 0); ! 462: build_overload_value (parm, arg); ! 463: } ! 464: } ! 465: } ! 466: else ! 467: { ! 468: icat (IDENTIFIER_LENGTH (name)); ! 469: OB_PUTID (name); ! 470: } ! 471: } ! 472: ! 473: /* Given a list of parameters in PARMTYPES, create an unambiguous ! 474: overload string. Should distinguish any type that C (or C++) can ! 475: distinguish. I.e., pointers to functions are treated correctly. ! 476: ! 477: Caller must deal with whether a final `e' goes on the end or not. ! 478: ! 479: Any default conversions must take place before this function ! 480: is called. ! 481: ! 482: BEGIN and END control initialization and finalization of the ! 483: obstack where we build the string. */ ! 484: ! 485: char * ! 486: build_overload_name (parmtypes, begin, end) ! 487: tree parmtypes; ! 488: int begin, end; ! 489: { ! 490: int just_one; ! 491: tree parmtype; ! 492: ! 493: if (begin) OB_INIT (); ! 494: ! 495: if (just_one = (TREE_CODE (parmtypes) != TREE_LIST)) ! 496: { ! 497: parmtype = parmtypes; ! 498: goto only_one; ! 499: } ! 500: ! 501: while (parmtypes) ! 502: { ! 503: parmtype = TREE_VALUE (parmtypes); ! 504: ! 505: only_one: ! 506: ! 507: if (! nofold) ! 508: { ! 509: if (! just_one) ! 510: /* Every argument gets counted. */ ! 511: typevec[maxtype++] = parmtype; ! 512: ! 513: if (TREE_USED (parmtype)) ! 514: { ! 515: if (! just_one && parmtype == typevec[maxtype-2]) ! 516: nrepeats++; ! 517: else ! 518: { ! 519: if (nrepeats) ! 520: flush_repeats (parmtype); ! 521: if (! just_one && TREE_CHAIN (parmtypes) ! 522: && parmtype == TREE_VALUE (TREE_CHAIN (parmtypes))) ! 523: nrepeats++; ! 524: else ! 525: { ! 526: int tindex = 0; ! 527: ! 528: while (typevec[tindex] != parmtype) ! 529: tindex++; ! 530: OB_PUTC ('T'); ! 531: icat (tindex); ! 532: if (tindex > 9) ! 533: OB_PUTC ('_'); ! 534: } ! 535: } ! 536: goto next; ! 537: } ! 538: if (nrepeats) ! 539: flush_repeats (typevec[maxtype-2]); ! 540: if (! just_one ! 541: /* Only cache types which take more than one character. */ ! 542: && (parmtype != TYPE_MAIN_VARIANT (parmtype) ! 543: || (TREE_CODE (parmtype) != INTEGER_TYPE ! 544: && TREE_CODE (parmtype) != REAL_TYPE))) ! 545: TREE_USED (parmtype) = 1; ! 546: } ! 547: ! 548: if (TYPE_PTRMEMFUNC_P (parmtype)) ! 549: parmtype = TYPE_PTRMEMFUNC_FN_TYPE (parmtype); ! 550: ! 551: if (TREE_READONLY (parmtype)) ! 552: OB_PUTC ('C'); ! 553: if (TREE_CODE (parmtype) == INTEGER_TYPE ! 554: && TYPE_MAIN_VARIANT (parmtype) == unsigned_type (TYPE_MAIN_VARIANT (parmtype))) ! 555: OB_PUTC ('U'); ! 556: if (TYPE_VOLATILE (parmtype)) ! 557: OB_PUTC ('V'); ! 558: ! 559: switch (TREE_CODE (parmtype)) ! 560: { ! 561: case OFFSET_TYPE: ! 562: OB_PUTC ('O'); ! 563: build_overload_name (TYPE_OFFSET_BASETYPE (parmtype), 0, 0); ! 564: OB_PUTC ('_'); ! 565: build_overload_name (TREE_TYPE (parmtype), 0, 0); ! 566: break; ! 567: ! 568: case REFERENCE_TYPE: ! 569: OB_PUTC ('R'); ! 570: goto more; ! 571: ! 572: case ARRAY_TYPE: ! 573: #if PARM_CAN_BE_ARRAY_TYPE ! 574: { ! 575: tree length; ! 576: ! 577: OB_PUTC ('A'); ! 578: if (TYPE_DOMAIN (parmtype) == NULL_TREE) ! 579: { ! 580: error ("parameter type with unspecified array bounds invalid"); ! 581: icat (1); ! 582: } ! 583: else ! 584: { ! 585: length = array_type_nelts (parmtype); ! 586: if (TREE_CODE (length) == INTEGER_CST) ! 587: icat (TREE_INT_CST_LOW (length) + 1); ! 588: } ! 589: OB_PUTC ('_'); ! 590: goto more; ! 591: } ! 592: #else ! 593: OB_PUTC ('P'); ! 594: goto more; ! 595: #endif ! 596: ! 597: case POINTER_TYPE: ! 598: OB_PUTC ('P'); ! 599: more: ! 600: build_overload_name (TREE_TYPE (parmtype), 0, 0); ! 601: break; ! 602: ! 603: case FUNCTION_TYPE: ! 604: case METHOD_TYPE: ! 605: { ! 606: tree firstarg = TYPE_ARG_TYPES (parmtype); ! 607: /* Otherwise have to implement reentrant typevecs, ! 608: unmark and remark types, etc. */ ! 609: int old_nofold = nofold; ! 610: nofold = 1; ! 611: ! 612: if (nrepeats) ! 613: flush_repeats (typevec[maxtype-1]); ! 614: ! 615: /* @@ It may be possible to pass a function type in ! 616: which is not preceded by a 'P'. */ ! 617: if (TREE_CODE (parmtype) == FUNCTION_TYPE) ! 618: { ! 619: OB_PUTC ('F'); ! 620: if (firstarg == NULL_TREE) ! 621: OB_PUTC ('e'); ! 622: else if (firstarg == void_list_node) ! 623: OB_PUTC ('v'); ! 624: else ! 625: build_overload_name (firstarg, 0, 0); ! 626: } ! 627: else ! 628: { ! 629: int constp = TYPE_READONLY (TREE_TYPE (TREE_VALUE (firstarg))); ! 630: int volatilep = TYPE_VOLATILE (TREE_TYPE (TREE_VALUE (firstarg))); ! 631: OB_PUTC ('M'); ! 632: firstarg = TREE_CHAIN (firstarg); ! 633: ! 634: build_overload_name (TYPE_METHOD_BASETYPE (parmtype), 0, 0); ! 635: if (constp) ! 636: OB_PUTC ('C'); ! 637: if (volatilep) ! 638: OB_PUTC ('V'); ! 639: ! 640: /* For cfront 2.0 compatibility. */ ! 641: OB_PUTC ('F'); ! 642: ! 643: if (firstarg == NULL_TREE) ! 644: OB_PUTC ('e'); ! 645: else if (firstarg == void_list_node) ! 646: OB_PUTC ('v'); ! 647: else ! 648: build_overload_name (firstarg, 0, 0); ! 649: } ! 650: ! 651: /* Separate args from return type. */ ! 652: OB_PUTC ('_'); ! 653: build_overload_name (TREE_TYPE (parmtype), 0, 0); ! 654: nofold = old_nofold; ! 655: break; ! 656: } ! 657: ! 658: case INTEGER_TYPE: ! 659: parmtype = TYPE_MAIN_VARIANT (parmtype); ! 660: if (parmtype == integer_type_node ! 661: || parmtype == unsigned_type_node) ! 662: OB_PUTC ('i'); ! 663: else if (parmtype == long_integer_type_node ! 664: || parmtype == long_unsigned_type_node) ! 665: OB_PUTC ('l'); ! 666: else if (parmtype == short_integer_type_node ! 667: || parmtype == short_unsigned_type_node) ! 668: OB_PUTC ('s'); ! 669: else if (parmtype == signed_char_type_node) ! 670: { ! 671: OB_PUTC ('S'); ! 672: OB_PUTC ('c'); ! 673: } ! 674: else if (parmtype == char_type_node ! 675: || parmtype == unsigned_char_type_node) ! 676: OB_PUTC ('c'); ! 677: else if (parmtype == wchar_type_node) ! 678: OB_PUTC ('w'); ! 679: else if (parmtype == long_long_integer_type_node ! 680: || parmtype == long_long_unsigned_type_node) ! 681: OB_PUTC ('x'); ! 682: #if 0 ! 683: /* it would seem there is no way to enter these in source code, ! 684: yet. (mrs) */ ! 685: else if (parmtype == long_long_long_integer_type_node ! 686: || parmtype == long_long_long_unsigned_type_node) ! 687: OB_PUTC ('q'); ! 688: #endif ! 689: else ! 690: my_friendly_abort (73); ! 691: break; ! 692: ! 693: case REAL_TYPE: ! 694: parmtype = TYPE_MAIN_VARIANT (parmtype); ! 695: if (parmtype == long_double_type_node) ! 696: OB_PUTC ('r'); ! 697: else if (parmtype == double_type_node) ! 698: OB_PUTC ('d'); ! 699: else if (parmtype == float_type_node) ! 700: OB_PUTC ('f'); ! 701: else my_friendly_abort (74); ! 702: break; ! 703: ! 704: case VOID_TYPE: ! 705: if (! just_one) ! 706: { ! 707: #if 0 ! 708: extern tree void_list_node; ! 709: ! 710: /* See if anybody is wasting memory. */ ! 711: my_friendly_assert (parmtypes == void_list_node, 247); ! 712: #endif ! 713: /* This is the end of a parameter list. */ ! 714: if (end) OB_FINISH (); ! 715: return (char *)obstack_base (&scratch_obstack); ! 716: } ! 717: OB_PUTC ('v'); ! 718: break; ! 719: ! 720: case ERROR_MARK: /* not right, but nothing is anyway */ ! 721: break; ! 722: ! 723: /* have to do these */ ! 724: case UNION_TYPE: ! 725: case RECORD_TYPE: ! 726: if (! just_one) ! 727: /* Make this type signature look incompatible ! 728: with AT&T. */ ! 729: OB_PUTC ('G'); ! 730: goto common; ! 731: case ENUMERAL_TYPE: ! 732: common: ! 733: { ! 734: tree name = TYPE_NAME (parmtype); ! 735: int i = 1; ! 736: ! 737: if (TREE_CODE (name) == TYPE_DECL) ! 738: { ! 739: tree context = name; ! 740: while (DECL_CONTEXT (context)) ! 741: { ! 742: i += 1; ! 743: context = DECL_CONTEXT (context); ! 744: if (TREE_CODE_CLASS (TREE_CODE (context)) == 't') ! 745: context = TYPE_NAME (context); ! 746: } ! 747: name = DECL_NAME (name); ! 748: } ! 749: my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 248); ! 750: if (i > 1) ! 751: { ! 752: OB_PUTC ('Q'); ! 753: if (i > 9) ! 754: OB_PUTC ('_'); ! 755: icat (i); ! 756: if (i > 9) ! 757: OB_PUTC ('_'); ! 758: build_overload_nested_name (TYPE_NAME (parmtype)); ! 759: } ! 760: else ! 761: build_overload_identifier (name); ! 762: break; ! 763: } ! 764: ! 765: case UNKNOWN_TYPE: ! 766: /* This will take some work. */ ! 767: OB_PUTC ('?'); ! 768: break; ! 769: ! 770: case TEMPLATE_TYPE_PARM: ! 771: case TEMPLATE_CONST_PARM: ! 772: case UNINSTANTIATED_P_TYPE: ! 773: /* We don't ever want this output, but it's inconvenient not to ! 774: be able to build the string. This should cause assembler ! 775: errors we'll notice. */ ! 776: { ! 777: static int n; ! 778: sprintf (digit_buffer, " *%d", n++); ! 779: OB_PUTCP (digit_buffer); ! 780: } ! 781: break; ! 782: ! 783: default: ! 784: my_friendly_abort (75); ! 785: } ! 786: ! 787: next: ! 788: if (just_one) break; ! 789: parmtypes = TREE_CHAIN (parmtypes); ! 790: } ! 791: if (! just_one) ! 792: { ! 793: if (nrepeats) ! 794: flush_repeats (typevec[maxtype-1]); ! 795: ! 796: /* To get here, parms must end with `...'. */ ! 797: OB_PUTC ('e'); ! 798: } ! 799: ! 800: if (end) OB_FINISH (); ! 801: return (char *)obstack_base (&scratch_obstack); ! 802: } ! 803: ! 804: /* Generate an identifier that encodes the (ANSI) exception TYPE. */ ! 805: ! 806: /* This should be part of `ansi_opname', or at least be defined by the std. */ ! 807: #define EXCEPTION_NAME_PREFIX "__ex" ! 808: #define EXCEPTION_NAME_LENGTH 4 ! 809: ! 810: tree ! 811: cplus_exception_name (type) ! 812: tree type; ! 813: { ! 814: OB_INIT (); ! 815: OB_PUTS (EXCEPTION_NAME_PREFIX); ! 816: return get_identifier (build_overload_name (type, 0, 1)); ! 817: } ! 818: ! 819: /* Change the name of a function definition so that it may be ! 820: overloaded. NAME is the name of the function to overload, ! 821: PARMS is the parameter list (which determines what name the ! 822: final function obtains). ! 823: ! 824: FOR_METHOD is 1 if this overload is being performed ! 825: for a method, rather than a function type. It is 2 if ! 826: this overload is being performed for a constructor. */ ! 827: tree ! 828: build_decl_overload (dname, parms, for_method) ! 829: tree dname; ! 830: tree parms; ! 831: int for_method; ! 832: { ! 833: char *name = IDENTIFIER_POINTER (dname); ! 834: ! 835: if (dname == ansi_opname[(int) NEW_EXPR] ! 836: && parms != NULL_TREE ! 837: && TREE_CODE (parms) == TREE_LIST ! 838: && TREE_VALUE (parms) == sizetype ! 839: && TREE_CHAIN (parms) == void_list_node) ! 840: return get_identifier ("__builtin_new"); ! 841: else if (dname == ansi_opname[(int) DELETE_EXPR] ! 842: && parms != NULL_TREE ! 843: && TREE_CODE (parms) == TREE_LIST ! 844: && TREE_VALUE (parms) == ptr_type_node ! 845: && TREE_CHAIN (parms) == void_list_node) ! 846: return get_identifier ("__builtin_delete"); ! 847: else if (dname == ansi_opname[(int) DELETE_EXPR] ! 848: && parms != NULL_TREE ! 849: && TREE_CODE (parms) == TREE_LIST ! 850: && TREE_VALUE (parms) == ptr_type_node ! 851: && TREE_CHAIN (parms) != NULL_TREE ! 852: && TREE_CODE (TREE_CHAIN (parms)) == TREE_LIST ! 853: && TREE_VALUE (TREE_CHAIN (parms)) == sizetype ! 854: && TREE_CHAIN (TREE_CHAIN (parms)) == void_list_node) ! 855: return get_identifier ("__builtin_delete"); ! 856: ! 857: OB_INIT (); ! 858: if (for_method != 2) ! 859: OB_PUTCP (name); ! 860: /* Otherwise, we can divine that this is a constructor, ! 861: and figure out its name without any extra encoding. */ ! 862: ! 863: OB_PUTC2 ('_', '_'); ! 864: if (for_method) ! 865: { ! 866: #if 0 ! 867: /* We can get away without doing this. */ ! 868: OB_PUTC ('M'); ! 869: #endif ! 870: parms = temp_tree_cons (NULL_TREE, TREE_TYPE (TREE_VALUE (parms)), TREE_CHAIN (parms)); ! 871: } ! 872: else ! 873: OB_PUTC ('F'); ! 874: ! 875: if (parms == NULL_TREE) ! 876: OB_PUTC2 ('e', '\0'); ! 877: else if (parms == void_list_node) ! 878: OB_PUTC2 ('v', '\0'); ! 879: else ! 880: { ! 881: ALLOCATE_TYPEVEC (parms); ! 882: nofold = 0; ! 883: if (for_method) ! 884: { ! 885: build_overload_name (TREE_VALUE (parms), 0, 0); ! 886: ! 887: typevec[maxtype++] = TREE_VALUE (parms); ! 888: TREE_USED (TREE_VALUE (parms)) = 1; ! 889: ! 890: if (TREE_CHAIN (parms)) ! 891: build_overload_name (TREE_CHAIN (parms), 0, 1); ! 892: else ! 893: OB_PUTC2 ('e', '\0'); ! 894: } ! 895: else ! 896: build_overload_name (parms, 0, 1); ! 897: DEALLOCATE_TYPEVEC (parms); ! 898: } ! 899: { ! 900: tree n = get_identifier (obstack_base (&scratch_obstack)); ! 901: if (IDENTIFIER_OPNAME_P (dname)) ! 902: IDENTIFIER_OPNAME_P (n) = 1; ! 903: return n; ! 904: } ! 905: } ! 906: ! 907: /* Build an overload name for the type expression TYPE. */ ! 908: tree ! 909: build_typename_overload (type) ! 910: tree type; ! 911: { ! 912: tree id; ! 913: ! 914: OB_INIT (); ! 915: OB_PUTID (ansi_opname[(int) TYPE_EXPR]); ! 916: nofold = 1; ! 917: build_overload_name (type, 0, 1); ! 918: id = get_identifier (obstack_base (&scratch_obstack)); ! 919: IDENTIFIER_OPNAME_P (id) = 1; ! 920: return id; ! 921: } ! 922: ! 923: #ifndef NO_DOLLAR_IN_LABEL ! 924: #define T_DESC_FORMAT "TD$" ! 925: #define I_DESC_FORMAT "ID$" ! 926: #define M_DESC_FORMAT "MD$" ! 927: #else ! 928: #if !defined(NO_DOT_IN_LABEL) ! 929: #define T_DESC_FORMAT "TD." ! 930: #define I_DESC_FORMAT "ID." ! 931: #define M_DESC_FORMAT "MD." ! 932: #else ! 933: #define T_DESC_FORMAT "__t_desc_" ! 934: #define I_DESC_FORMAT "__i_desc_" ! 935: #define M_DESC_FORMAT "__m_desc_" ! 936: #endif ! 937: #endif ! 938: ! 939: /* Build an overload name for the type expression TYPE. */ ! 940: tree ! 941: build_t_desc_overload (type) ! 942: tree type; ! 943: { ! 944: OB_INIT (); ! 945: OB_PUTS (T_DESC_FORMAT); ! 946: nofold = 1; ! 947: ! 948: #if 0 ! 949: /* Use a different format if the type isn't defined yet. */ ! 950: if (TYPE_SIZE (type) == NULL_TREE) ! 951: { ! 952: char *p; ! 953: int changed; ! 954: ! 955: for (p = tname; *p; p++) ! 956: if (isupper (*p)) ! 957: { ! 958: changed = 1; ! 959: *p = tolower (*p); ! 960: } ! 961: /* If there's no change, we have an inappropriate T_DESC_FORMAT. */ ! 962: my_friendly_assert (changed != 0, 249); ! 963: } ! 964: #endif ! 965: ! 966: build_overload_name (type, 0, 1); ! 967: return get_identifier (obstack_base (&scratch_obstack)); ! 968: } ! 969: ! 970: /* Top-level interface to explicit overload requests. Allow NAME ! 971: to be overloaded. Error if NAME is already declared for the current ! 972: scope. Warning if function is redundantly overloaded. */ ! 973: ! 974: void ! 975: declare_overloaded (name) ! 976: tree name; ! 977: { ! 978: #ifdef NO_AUTO_OVERLOAD ! 979: if (is_overloaded (name)) ! 980: warning ("function `%s' already declared overloaded", ! 981: IDENTIFIER_POINTER (name)); ! 982: else if (IDENTIFIER_GLOBAL_VALUE (name)) ! 983: error ("overloading function `%s' that is already defined", ! 984: IDENTIFIER_POINTER (name)); ! 985: else ! 986: { ! 987: TREE_OVERLOADED (name) = 1; ! 988: IDENTIFIER_GLOBAL_VALUE (name) = build_tree_list (name, NULL_TREE); ! 989: TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (name)) = unknown_type_node; ! 990: } ! 991: #else ! 992: if (current_lang_name == lang_name_cplusplus) ! 993: { ! 994: if (0) ! 995: warning ("functions are implicitly overloaded in C++"); ! 996: } ! 997: else if (current_lang_name == lang_name_c) ! 998: error ("overloading function `%s' cannot be done in C language context"); ! 999: else ! 1000: my_friendly_abort (76); ! 1001: #endif ! 1002: } ! 1003: ! 1004: #ifdef NO_AUTO_OVERLOAD ! 1005: /* Check to see if NAME is overloaded. For first approximation, ! 1006: check to see if its TREE_OVERLOADED is set. This is used on ! 1007: IDENTIFIER nodes. */ ! 1008: int ! 1009: is_overloaded (name) ! 1010: tree name; ! 1011: { ! 1012: /* @@ */ ! 1013: return (TREE_OVERLOADED (name) ! 1014: && (! IDENTIFIER_CLASS_VALUE (name) || current_class_type == 0) ! 1015: && ! IDENTIFIER_LOCAL_VALUE (name)); ! 1016: } ! 1017: #endif ! 1018: ! 1019: /* Given a tree_code CODE, and some arguments (at least one), ! 1020: attempt to use an overloaded operator on the arguments. ! 1021: ! 1022: For unary operators, only the first argument need be checked. ! 1023: For binary operators, both arguments may need to be checked. ! 1024: ! 1025: Member functions can convert class references to class pointers, ! 1026: for one-level deep indirection. More than that is not supported. ! 1027: Operators [](), ()(), and ->() must be member functions. ! 1028: ! 1029: We call function call building calls with nonzero complain if ! 1030: they are our only hope. This is true when we see a vanilla operator ! 1031: applied to something of aggregate type. If this fails, we are free to ! 1032: return `error_mark_node', because we will have reported the error. ! 1033: ! 1034: Operators NEW and DELETE overload in funny ways: operator new takes ! 1035: a single `size' parameter, and operator delete takes a pointer to the ! 1036: storage being deleted. When overloading these operators, success is ! 1037: assumed. If there is a failure, report an error message and return ! 1038: `error_mark_node'. */ ! 1039: ! 1040: /* NOSTRICT */ ! 1041: tree ! 1042: build_opfncall (code, flags, xarg1, xarg2, arg3) ! 1043: enum tree_code code; ! 1044: int flags; ! 1045: tree xarg1, xarg2, arg3; ! 1046: { ! 1047: tree rval = 0; ! 1048: tree arg1, arg2; ! 1049: tree type1, type2, fnname; ! 1050: tree fields1 = 0, parms = 0; ! 1051: tree global_fn; ! 1052: int try_second; ! 1053: int binary_is_unary; ! 1054: ! 1055: if (xarg1 == error_mark_node) ! 1056: return error_mark_node; ! 1057: ! 1058: if (code == COND_EXPR) ! 1059: { ! 1060: if (TREE_CODE (xarg2) == ERROR_MARK ! 1061: || TREE_CODE (arg3) == ERROR_MARK) ! 1062: return error_mark_node; ! 1063: } ! 1064: if (code == COMPONENT_REF) ! 1065: if (TREE_CODE (TREE_TYPE (xarg1)) == POINTER_TYPE) ! 1066: return rval; ! 1067: ! 1068: /* First, see if we can work with the first argument */ ! 1069: type1 = TREE_TYPE (xarg1); ! 1070: ! 1071: /* Some tree codes have length > 1, but we really only want to ! 1072: overload them if their first argument has a user defined type. */ ! 1073: switch (code) ! 1074: { ! 1075: case PREINCREMENT_EXPR: ! 1076: case PREDECREMENT_EXPR: ! 1077: case POSTINCREMENT_EXPR: ! 1078: case POSTDECREMENT_EXPR: ! 1079: case COMPONENT_REF: ! 1080: binary_is_unary = 1; ! 1081: try_second = 0; ! 1082: break; ! 1083: ! 1084: /* ARRAY_REFs and CALL_EXPRs must overload successfully. ! 1085: If they do not, return error_mark_node instead of NULL_TREE. */ ! 1086: case ARRAY_REF: ! 1087: if (xarg2 == error_mark_node) ! 1088: return error_mark_node; ! 1089: case CALL_EXPR: ! 1090: rval = error_mark_node; ! 1091: binary_is_unary = 0; ! 1092: try_second = 0; ! 1093: break; ! 1094: ! 1095: case NEW_EXPR: ! 1096: { ! 1097: /* For operators `new' (`delete'), only check visibility ! 1098: if we are in a constructor (destructor), and we are ! 1099: allocating for that constructor's (destructor's) type. */ ! 1100: ! 1101: fnname = ansi_opname[(int) NEW_EXPR]; ! 1102: if (flags & LOOKUP_GLOBAL) ! 1103: return build_overload_call (fnname, tree_cons (NULL_TREE, xarg2, arg3), ! 1104: flags & LOOKUP_COMPLAIN, ! 1105: (struct candidate *)0); ! 1106: ! 1107: if (current_function_decl == NULL_TREE ! 1108: || !DECL_CONSTRUCTOR_P (current_function_decl) ! 1109: || current_class_type != TYPE_MAIN_VARIANT (type1)) ! 1110: flags = LOOKUP_COMPLAIN; ! 1111: rval = build_method_call (build1 (NOP_EXPR, xarg1, error_mark_node), ! 1112: fnname, tree_cons (NULL_TREE, xarg2, arg3), ! 1113: NULL_TREE, flags); ! 1114: if (rval == error_mark_node) ! 1115: /* User might declare fancy operator new, but invoke it ! 1116: like standard one. */ ! 1117: return rval; ! 1118: ! 1119: TREE_TYPE (rval) = xarg1; ! 1120: TREE_CALLS_NEW (rval) = 1; ! 1121: return rval; ! 1122: } ! 1123: break; ! 1124: ! 1125: case DELETE_EXPR: ! 1126: { ! 1127: /* See comment above. */ ! 1128: ! 1129: fnname = ansi_opname[(int) DELETE_EXPR]; ! 1130: if (flags & LOOKUP_GLOBAL) ! 1131: return build_overload_call (fnname, ! 1132: tree_cons (NULL_TREE, xarg1, ! 1133: build_tree_list (NULL_TREE, xarg2)), ! 1134: flags & LOOKUP_COMPLAIN, ! 1135: (struct candidate *)0); ! 1136: ! 1137: if (current_function_decl == NULL_TREE ! 1138: || !DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (current_function_decl)) ! 1139: || current_class_type != TYPE_MAIN_VARIANT (type1)) ! 1140: flags = LOOKUP_COMPLAIN; ! 1141: rval = build_method_call (build1 (NOP_EXPR, TREE_TYPE (xarg1), ! 1142: error_mark_node), ! 1143: fnname, tree_cons (NULL_TREE, xarg1, ! 1144: build_tree_list (NULL_TREE, xarg2)), ! 1145: NULL_TREE, flags); ! 1146: /* This happens when the user mis-declares `operator delete'. ! 1147: Should now be impossible. */ ! 1148: my_friendly_assert (rval != error_mark_node, 250); ! 1149: TREE_TYPE (rval) = void_type_node; ! 1150: return rval; ! 1151: } ! 1152: break; ! 1153: ! 1154: default: ! 1155: binary_is_unary = 0; ! 1156: try_second = tree_code_length [(int) code] == 2; ! 1157: if (try_second && xarg2 == error_mark_node) ! 1158: return error_mark_node; ! 1159: break; ! 1160: } ! 1161: ! 1162: if (try_second && xarg2 == error_mark_node) ! 1163: return error_mark_node; ! 1164: ! 1165: /* What ever it was, we do not know how to deal with it. */ ! 1166: if (type1 == NULL_TREE) ! 1167: return rval; ! 1168: ! 1169: if (TREE_CODE (type1) == OFFSET_TYPE) ! 1170: type1 = TREE_TYPE (type1); ! 1171: ! 1172: if (TREE_CODE (type1) == REFERENCE_TYPE) ! 1173: { ! 1174: arg1 = convert_from_reference (xarg1); ! 1175: type1 = TREE_TYPE (arg1); ! 1176: } ! 1177: else ! 1178: { ! 1179: arg1 = xarg1; ! 1180: } ! 1181: ! 1182: if (!IS_AGGR_TYPE (type1)) ! 1183: { ! 1184: /* Try to fail. First, fail if unary */ ! 1185: if (! try_second) ! 1186: return rval; ! 1187: /* Second, see if second argument is non-aggregate. */ ! 1188: type2 = TREE_TYPE (xarg2); ! 1189: if (TREE_CODE (type2) == OFFSET_TYPE) ! 1190: type2 = TREE_TYPE (type2); ! 1191: if (TREE_CODE (type2) == REFERENCE_TYPE) ! 1192: { ! 1193: arg2 = convert_from_reference (xarg2); ! 1194: type2 = TREE_TYPE (arg2); ! 1195: } ! 1196: else ! 1197: { ! 1198: arg2 = xarg2; ! 1199: } ! 1200: ! 1201: if (!IS_AGGR_TYPE (type2)) ! 1202: return rval; ! 1203: try_second = 0; ! 1204: } ! 1205: ! 1206: if (try_second) ! 1207: { ! 1208: /* First arg may succeed; see whether second should. */ ! 1209: type2 = TREE_TYPE (xarg2); ! 1210: if (TREE_CODE (type2) == OFFSET_TYPE) ! 1211: type2 = TREE_TYPE (type2); ! 1212: if (TREE_CODE (type2) == REFERENCE_TYPE) ! 1213: { ! 1214: arg2 = convert_from_reference (xarg2); ! 1215: type2 = TREE_TYPE (arg2); ! 1216: } ! 1217: else ! 1218: { ! 1219: arg2 = xarg2; ! 1220: } ! 1221: ! 1222: if (! IS_AGGR_TYPE (type2)) ! 1223: try_second = 0; ! 1224: } ! 1225: ! 1226: if (type1 == unknown_type_node ! 1227: || (try_second && TREE_TYPE (xarg2) == unknown_type_node)) ! 1228: { ! 1229: /* This will not be implemented in the foreseeable future. */ ! 1230: return rval; ! 1231: } ! 1232: ! 1233: if (code == MODIFY_EXPR) ! 1234: fnname = ansi_assopname[(int) TREE_CODE (arg3)]; ! 1235: else ! 1236: fnname = ansi_opname[(int) code]; ! 1237: ! 1238: global_fn = IDENTIFIER_GLOBAL_VALUE (fnname); ! 1239: ! 1240: /* This is the last point where we will accept failure. This ! 1241: may be too eager if we wish an overloaded operator not to match, ! 1242: but would rather a normal operator be called on a type-converted ! 1243: argument. */ ! 1244: ! 1245: if (IS_AGGR_TYPE (type1)) ! 1246: { ! 1247: fields1 = lookup_fnfields (TYPE_BINFO (type1), fnname, 0); ! 1248: /* ARM $13.4.7, prefix/postfix ++/--. */ ! 1249: if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR) ! 1250: { ! 1251: xarg2 = integer_zero_node; ! 1252: binary_is_unary = 0; ! 1253: ! 1254: if (fields1) ! 1255: { ! 1256: tree t, t2; ! 1257: int have_postfix = 0; ! 1258: ! 1259: /* Look for an `operator++ (int)'. If they didn't have ! 1260: one, then we fall back to the old way of doing things. */ ! 1261: for (t = TREE_VALUE (fields1); t ; t = TREE_CHAIN (t)) ! 1262: { ! 1263: t2 = TYPE_ARG_TYPES (TREE_TYPE (t)); ! 1264: if (TREE_CHAIN (t2) != NULL_TREE ! 1265: && TREE_VALUE (TREE_CHAIN (t2)) == integer_type_node) ! 1266: { ! 1267: have_postfix = 1; ! 1268: break; ! 1269: } ! 1270: } ! 1271: ! 1272: if (! have_postfix) ! 1273: { ! 1274: char *op = POSTINCREMENT_EXPR ? "++" : "--"; ! 1275: ! 1276: /* There's probably a LOT of code in the world that ! 1277: relies upon this old behavior. So we'll only give this ! 1278: warning when we've been given -pedantic. A few ! 1279: releases after 2.4, we'll convert this to be a pedwarn ! 1280: or something else more appropriate. */ ! 1281: if (pedantic) ! 1282: warning ("no `operator%s (int)' declared for postfix `%s'", ! 1283: op, op); ! 1284: xarg2 = NULL_TREE; ! 1285: binary_is_unary = 1; ! 1286: } ! 1287: } ! 1288: } ! 1289: } ! 1290: ! 1291: if (fields1 == NULL_TREE && global_fn == NULL_TREE) ! 1292: return rval; ! 1293: ! 1294: /* If RVAL winds up being `error_mark_node', we will return ! 1295: that... There is no way that normal semantics of these ! 1296: operators will succeed. */ ! 1297: ! 1298: /* This argument may be an uncommitted OFFSET_REF. This is ! 1299: the case for example when dealing with static class members ! 1300: which are referenced from their class name rather than ! 1301: from a class instance. */ ! 1302: if (TREE_CODE (xarg1) == OFFSET_REF ! 1303: && TREE_CODE (TREE_OPERAND (xarg1, 1)) == VAR_DECL) ! 1304: xarg1 = TREE_OPERAND (xarg1, 1); ! 1305: if (try_second && xarg2 && TREE_CODE (xarg2) == OFFSET_REF ! 1306: && TREE_CODE (TREE_OPERAND (xarg2, 1)) == VAR_DECL) ! 1307: xarg2 = TREE_OPERAND (xarg2, 1); ! 1308: ! 1309: if (global_fn) ! 1310: flags |= LOOKUP_GLOBAL; ! 1311: ! 1312: if (code == CALL_EXPR) ! 1313: { ! 1314: /* This can only be a member function. */ ! 1315: return build_method_call (xarg1, fnname, xarg2, ! 1316: NULL_TREE, LOOKUP_NORMAL); ! 1317: } ! 1318: else if (tree_code_length[(int) code] == 1 || binary_is_unary) ! 1319: { ! 1320: parms = NULL_TREE; ! 1321: rval = build_method_call (xarg1, fnname, NULL_TREE, NULL_TREE, flags); ! 1322: } ! 1323: else if (code == COND_EXPR) ! 1324: { ! 1325: parms = tree_cons (0, xarg2, build_tree_list (NULL_TREE, arg3)); ! 1326: rval = build_method_call (xarg1, fnname, parms, NULL_TREE, flags); ! 1327: } ! 1328: else if (code == METHOD_CALL_EXPR) ! 1329: { ! 1330: /* must be a member function. */ ! 1331: parms = tree_cons (NULL_TREE, xarg2, arg3); ! 1332: return build_method_call (xarg1, fnname, parms, NULL_TREE, LOOKUP_NORMAL); ! 1333: } ! 1334: else if (fields1) ! 1335: { ! 1336: parms = build_tree_list (NULL_TREE, xarg2); ! 1337: rval = build_method_call (xarg1, fnname, parms, NULL_TREE, flags); ! 1338: } ! 1339: else ! 1340: { ! 1341: parms = tree_cons (NULL_TREE, xarg1, ! 1342: build_tree_list (NULL_TREE, xarg2)); ! 1343: rval = build_overload_call (fnname, parms, flags & LOOKUP_COMPLAIN, ! 1344: (struct candidate *)0); ! 1345: } ! 1346: ! 1347: /* If we did not win, do not lose yet, since type conversion may work. */ ! 1348: if (TREE_CODE (rval) == ERROR_MARK) ! 1349: { ! 1350: if (flags & LOOKUP_COMPLAIN) ! 1351: return rval; ! 1352: return 0; ! 1353: } ! 1354: ! 1355: return rval; ! 1356: } ! 1357: ! 1358: /* This function takes an identifier, ID, and attempts to figure out what ! 1359: it means. There are a number of possible scenarios, presented in increasing ! 1360: order of hair: ! 1361: ! 1362: 1) not in a class's scope ! 1363: 2) in class's scope, member name of the class's method ! 1364: 3) in class's scope, but not a member name of the class ! 1365: 4) in class's scope, member name of a class's variable ! 1366: ! 1367: NAME is $1 from the bison rule. It is an IDENTIFIER_NODE. ! 1368: VALUE is $$ from the bison rule. It is the value returned by lookup_name ($1) ! 1369: yychar is the pending input character (suitably encoded :-). ! 1370: ! 1371: As a last ditch, try to look up the name as a label and return that ! 1372: address. ! 1373: ! 1374: Values which are declared as being of REFERENCE_TYPE are ! 1375: automatically dereferenced here (as a hack to make the ! 1376: compiler faster). */ ! 1377: ! 1378: tree ! 1379: hack_identifier (value, name, yychar) ! 1380: tree value, name; ! 1381: int yychar; ! 1382: { ! 1383: tree type; ! 1384: ! 1385: if (TREE_CODE (value) == ERROR_MARK) ! 1386: { ! 1387: if (current_class_name) ! 1388: { ! 1389: tree fields = lookup_fnfields (TYPE_BINFO (current_class_type), name, 1); ! 1390: if (fields == error_mark_node) ! 1391: return error_mark_node; ! 1392: if (fields) ! 1393: { ! 1394: tree fndecl; ! 1395: ! 1396: fndecl = TREE_VALUE (fields); ! 1397: my_friendly_assert (TREE_CODE (fndecl) == FUNCTION_DECL, 251); ! 1398: if (DECL_CHAIN (fndecl) == NULL_TREE) ! 1399: { ! 1400: warning ("methods cannot be converted to function pointers"); ! 1401: return fndecl; ! 1402: } ! 1403: else ! 1404: { ! 1405: error ("ambiguous request for method pointer `%s'", ! 1406: IDENTIFIER_POINTER (name)); ! 1407: return error_mark_node; ! 1408: } ! 1409: } ! 1410: } ! 1411: if (flag_labels_ok && IDENTIFIER_LABEL_VALUE (name)) ! 1412: { ! 1413: return IDENTIFIER_LABEL_VALUE (name); ! 1414: } ! 1415: return error_mark_node; ! 1416: } ! 1417: ! 1418: type = TREE_TYPE (value); ! 1419: if (TREE_CODE (value) == FIELD_DECL) ! 1420: { ! 1421: if (current_class_decl == NULL_TREE) ! 1422: { ! 1423: error ("request for member `%s' in static member function", ! 1424: IDENTIFIER_POINTER (DECL_NAME (value))); ! 1425: return error_mark_node; ! 1426: } ! 1427: TREE_USED (current_class_decl) = 1; ! 1428: if (yychar == '(') ! 1429: if (! ((TYPE_LANG_SPECIFIC (type) ! 1430: && TYPE_OVERLOADS_CALL_EXPR (type)) ! 1431: || (TREE_CODE (type) == REFERENCE_TYPE ! 1432: && TYPE_LANG_SPECIFIC (TREE_TYPE (type)) ! 1433: && TYPE_OVERLOADS_CALL_EXPR (TREE_TYPE (type)))) ! 1434: && TREE_CODE (type) != FUNCTION_TYPE ! 1435: && TREE_CODE (type) != METHOD_TYPE ! 1436: && (TREE_CODE (type) != POINTER_TYPE ! 1437: || (TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE ! 1438: && TREE_CODE (TREE_TYPE (type)) != METHOD_TYPE))) ! 1439: { ! 1440: error ("component `%s' is not a method", ! 1441: IDENTIFIER_POINTER (name)); ! 1442: return error_mark_node; ! 1443: } ! 1444: /* Mark so that if we are in a constructor, and then find that ! 1445: this field was initialized by a base initializer, ! 1446: we can emit an error message. */ ! 1447: TREE_USED (value) = 1; ! 1448: return build_component_ref (C_C_D, name, 0, 1); ! 1449: } ! 1450: ! 1451: if (TREE_CODE (value) == TREE_LIST) ! 1452: { ! 1453: tree t = value; ! 1454: while (t && TREE_CODE (t) == TREE_LIST) ! 1455: { ! 1456: assemble_external (TREE_VALUE (t)); ! 1457: TREE_USED (t) = 1; ! 1458: t = TREE_CHAIN (t); ! 1459: } ! 1460: } ! 1461: else ! 1462: { ! 1463: assemble_external (value); ! 1464: TREE_USED (value) = 1; ! 1465: } ! 1466: ! 1467: if (TREE_CODE_CLASS (TREE_CODE (value)) == 'd' && DECL_NONLOCAL (value)) ! 1468: { ! 1469: if (DECL_LANG_SPECIFIC (value) ! 1470: && DECL_CLASS_CONTEXT (value) != current_class_type) ! 1471: { ! 1472: tree path; ! 1473: enum visibility_type visibility; ! 1474: register tree context ! 1475: = (TREE_CODE (value) == FUNCTION_DECL && DECL_VIRTUAL_P (value)) ! 1476: ? DECL_CLASS_CONTEXT (value) ! 1477: : DECL_CONTEXT (value); ! 1478: ! 1479: get_base_distance (context, current_class_type, 0, &path); ! 1480: if (path) ! 1481: { ! 1482: visibility = compute_visibility (path, value); ! 1483: if (visibility != visibility_public) ! 1484: { ! 1485: if (TREE_CODE (value) == VAR_DECL) ! 1486: error ("static member `%s' is from private base class", ! 1487: IDENTIFIER_POINTER (name)); ! 1488: else ! 1489: error ("enum `%s' is from private base class", ! 1490: IDENTIFIER_POINTER (name)); ! 1491: return error_mark_node; ! 1492: } ! 1493: } ! 1494: } ! 1495: return value; ! 1496: } ! 1497: if (TREE_CODE (value) == TREE_LIST && TREE_NONLOCAL_FLAG (value)) ! 1498: { ! 1499: if (type == 0) ! 1500: { ! 1501: error ("request for member `%s' is ambiguous in multiple inheritance lattice", ! 1502: IDENTIFIER_POINTER (name)); ! 1503: return error_mark_node; ! 1504: } ! 1505: ! 1506: return value; ! 1507: } ! 1508: ! 1509: if (TREE_CODE (type) == REFERENCE_TYPE) ! 1510: { ! 1511: my_friendly_assert (TREE_CODE (value) == VAR_DECL ! 1512: || TREE_CODE (value) == PARM_DECL ! 1513: || TREE_CODE (value) == RESULT_DECL, 252); ! 1514: if (DECL_REFERENCE_SLOT (value)) ! 1515: return DECL_REFERENCE_SLOT (value); ! 1516: } ! 1517: return value; ! 1518: } ! 1519: ! 1520: ! 1521: /* Given an object OF, and a type conversion operator COMPONENT ! 1522: build a call to the conversion operator, if a call is requested, ! 1523: or return the address (as a pointer to member function) if one is not. ! 1524: ! 1525: OF can be a TYPE_DECL or any kind of datum that would normally ! 1526: be passed to `build_component_ref'. It may also be NULL_TREE, ! 1527: in which case `current_class_type' and `current_class_decl' ! 1528: provide default values. ! 1529: ! 1530: BASETYPE_PATH, if non-null, is the path of basetypes ! 1531: to go through before we get the the instance of interest. ! 1532: ! 1533: PROTECT says whether we apply C++ scoping rules or not. */ ! 1534: tree ! 1535: build_component_type_expr (of, component, basetype_path, protect) ! 1536: tree of, component, basetype_path; ! 1537: int protect; ! 1538: { ! 1539: tree cname = NULL_TREE; ! 1540: tree tmp, last; ! 1541: tree name; ! 1542: int flags = protect ? LOOKUP_NORMAL : LOOKUP_COMPLAIN; ! 1543: ! 1544: if (of) ! 1545: my_friendly_assert (IS_AGGR_TYPE (TREE_TYPE (of)), 253); ! 1546: my_friendly_assert (TREE_CODE (component) == TYPE_EXPR, 254); ! 1547: ! 1548: tmp = TREE_OPERAND (component, 0); ! 1549: last = NULL_TREE; ! 1550: ! 1551: while (tmp) ! 1552: { ! 1553: switch (TREE_CODE (tmp)) ! 1554: { ! 1555: case CALL_EXPR: ! 1556: if (last) ! 1557: TREE_OPERAND (last, 0) = TREE_OPERAND (tmp, 0); ! 1558: else ! 1559: TREE_OPERAND (component, 0) = TREE_OPERAND (tmp, 0); ! 1560: ! 1561: last = groktypename (build_tree_list (TREE_TYPE (component), ! 1562: TREE_OPERAND (component, 0))); ! 1563: name = build_typename_overload (last); ! 1564: TREE_TYPE (name) = last; ! 1565: ! 1566: if (TREE_OPERAND (tmp, 0) ! 1567: && TREE_OPERAND (tmp, 0) != void_list_node) ! 1568: { ! 1569: cp_error ("`operator %T' requires empty parameter list", last); ! 1570: TREE_OPERAND (tmp, 0) = NULL_TREE; ! 1571: } ! 1572: ! 1573: if (of && TREE_CODE (of) != TYPE_DECL) ! 1574: return build_method_call (of, name, NULL_TREE, NULL_TREE, flags); ! 1575: else if (of) ! 1576: { ! 1577: tree this_this; ! 1578: ! 1579: if (current_class_decl == NULL_TREE) ! 1580: { ! 1581: cp_error ("object required for `operator %T' call", ! 1582: TREE_TYPE (name)); ! 1583: return error_mark_node; ! 1584: } ! 1585: ! 1586: this_this = convert_pointer_to (TREE_TYPE (of), current_class_decl); ! 1587: return build_method_call (this_this, name, NULL_TREE, ! 1588: NULL_TREE, flags | LOOKUP_NONVIRTUAL); ! 1589: } ! 1590: else if (current_class_decl) ! 1591: return build_method_call (tmp, name, NULL_TREE, NULL_TREE, flags); ! 1592: ! 1593: cp_error ("object required for `operator %T' call", ! 1594: TREE_TYPE (name)); ! 1595: return error_mark_node; ! 1596: ! 1597: case INDIRECT_REF: ! 1598: case ADDR_EXPR: ! 1599: case ARRAY_REF: ! 1600: break; ! 1601: ! 1602: case SCOPE_REF: ! 1603: my_friendly_assert (cname == 0, 255); ! 1604: cname = TREE_OPERAND (tmp, 0); ! 1605: tmp = TREE_OPERAND (tmp, 1); ! 1606: break; ! 1607: ! 1608: default: ! 1609: my_friendly_abort (77); ! 1610: } ! 1611: last = tmp; ! 1612: tmp = TREE_OPERAND (tmp, 0); ! 1613: } ! 1614: ! 1615: last = groktypename (build_tree_list (TREE_TYPE (component), TREE_OPERAND (component, 0))); ! 1616: name = build_typename_overload (last); ! 1617: TREE_TYPE (name) = last; ! 1618: if (of && TREE_CODE (of) == TYPE_DECL) ! 1619: { ! 1620: if (cname == NULL_TREE) ! 1621: { ! 1622: cname = DECL_NAME (of); ! 1623: of = NULL_TREE; ! 1624: } ! 1625: else my_friendly_assert (cname == DECL_NAME (of), 256); ! 1626: } ! 1627: ! 1628: if (of) ! 1629: { ! 1630: tree this_this; ! 1631: ! 1632: if (current_class_decl == NULL_TREE) ! 1633: { ! 1634: cp_error ("object required for `operator %T' call", ! 1635: TREE_TYPE (name)); ! 1636: return error_mark_node; ! 1637: } ! 1638: ! 1639: this_this = convert_pointer_to (TREE_TYPE (of), current_class_decl); ! 1640: return build_component_ref (this_this, name, 0, protect); ! 1641: } ! 1642: else if (cname) ! 1643: return build_offset_ref (cname, name); ! 1644: else if (current_class_name) ! 1645: return build_offset_ref (current_class_name, name); ! 1646: ! 1647: cp_error ("object required for `operator %T' member reference", ! 1648: TREE_TYPE (name)); ! 1649: return error_mark_node; ! 1650: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.