|
|
1.1 ! root 1: /* Handle the hair of processing (but not expanding) inline functions. ! 2: Also manage function and varaible name overloading. ! 3: Copyright (C) 1987, 1989, 1992 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 <string.h> ! 30: #include "config.h" ! 31: #include "tree.h" ! 32: #include "cp-tree.h" ! 33: #include "cp-class.h" ! 34: #include "assert.h" ! 35: #include "obstack.h" ! 36: ! 37: #define obstack_chunk_alloc xmalloc ! 38: #define obstack_chunk_free free ! 39: ! 40: extern int xmalloc (); ! 41: extern void free (); ! 42: ! 43: /* TREE_LIST of the current inline functions that need to be ! 44: processed. */ ! 45: struct pending_inline *pending_inlines; ! 46: ! 47: /* Obstack where we build text strings for overloading, etc. */ ! 48: static struct obstack scratch_obstack; ! 49: static char *scratch_firstobj; ! 50: ! 51: # define OB_INIT() (scratch_firstobj ? (obstack_free (&scratch_obstack, scratch_firstobj), 0) : 0) ! 52: # define OB_PUTC(C) (obstack_1grow (&scratch_obstack, (C))) ! 53: # define OB_PUTC2(C1,C2) \ ! 54: (obstack_1grow (&scratch_obstack, (C1)), obstack_1grow (&scratch_obstack, (C2))) ! 55: # define OB_PUTS(S) (obstack_grow (&scratch_obstack, (S), sizeof (S) - 1)) ! 56: # define OB_PUTID(ID) \ ! 57: (obstack_grow (&scratch_obstack, IDENTIFIER_POINTER (ID), \ ! 58: IDENTIFIER_LENGTH (ID))) ! 59: # define OB_PUTCP(S) (obstack_grow (&scratch_obstack, (S), strlen (S))) ! 60: # define OB_FINISH() (obstack_1grow (&scratch_obstack, '\0')) ! 61: ! 62: /* Counter to help build parameter names in case they were omitted. */ ! 63: static int dummy_name; ! 64: static int in_parmlist; ! 65: ! 66: /* This points to a safe place to resume processing in case an expression ! 67: generates an error while we're trying to format it. */ ! 68: static int scratch_error_offset; ! 69: ! 70: static void dump_type (), dump_decl (); ! 71: static void dump_init (), dump_unary_op (), dump_binary_op (); ! 72: ! 73: tree wrapper_name, wrapper_pred_name, anti_wrapper_name; ! 74: ! 75: #ifdef NO_AUTO_OVERLOAD ! 76: int is_overloaded (); ! 77: #endif ! 78: ! 79: void ! 80: init_method () ! 81: { ! 82: char buf[sizeof (ANTI_WRAPPER_NAME_FORMAT) + 8]; ! 83: sprintf (buf, WRAPPER_NAME_FORMAT, ""); ! 84: wrapper_name = get_identifier (buf); ! 85: sprintf (buf, WRAPPER_PRED_NAME_FORMAT, ""); ! 86: wrapper_pred_name = get_identifier (buf); ! 87: sprintf (buf, ANTI_WRAPPER_NAME_FORMAT, ""); ! 88: anti_wrapper_name = get_identifier (buf); ! 89: gcc_obstack_init (&scratch_obstack); ! 90: scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0); ! 91: } ! 92: ! 93: /* Return a pointer to the end of the new text in INLINE_BUFFER. ! 94: We cannot use `fatal' or `error' in here because that ! 95: might cause an infinite loop. */ ! 96: static char * ! 97: new_text_len (s) ! 98: char *s; ! 99: { ! 100: while (*s++) ; ! 101: return s - 1; ! 102: } ! 103: ! 104: tree ! 105: make_anon_parm_name () ! 106: { ! 107: char buf[32]; ! 108: ! 109: sprintf (buf, ANON_PARMNAME_FORMAT, dummy_name++); ! 110: return get_identifier (buf); ! 111: } ! 112: ! 113: void ! 114: clear_anon_parm_name () ! 115: { ! 116: /* recycle these names. */ ! 117: dummy_name = 0; ! 118: } ! 119: ! 120: static void ! 121: dump_readonly_or_volatile (t) ! 122: tree t; ! 123: { ! 124: if (TYPE_READONLY (t)) ! 125: OB_PUTS ("const "); ! 126: if (TYPE_VOLATILE (t)) ! 127: OB_PUTS ("volatile "); ! 128: } ! 129: ! 130: static void ! 131: dump_aggr_type (t) ! 132: tree t; ! 133: { ! 134: tree name; ! 135: char *aggr_string; ! 136: char *context_string = 0; ! 137: ! 138: if (TYPE_READONLY (t)) ! 139: OB_PUTS ("const "); ! 140: if (TYPE_VOLATILE (t)) ! 141: OB_PUTS ("volatile "); ! 142: if (TREE_CODE (t) == ENUMERAL_TYPE) ! 143: aggr_string = "enum"; ! 144: else if (TREE_CODE (t) == UNION_TYPE) ! 145: aggr_string = "union"; ! 146: else if (TYPE_LANG_SPECIFIC (t) && CLASSTYPE_DECLARED_CLASS (t)) ! 147: aggr_string = "class"; ! 148: else ! 149: aggr_string = "struct"; ! 150: ! 151: name = TYPE_NAME (t); ! 152: ! 153: if (TREE_CODE (name) == TYPE_DECL) ! 154: { ! 155: if (DECL_LANG_SPECIFIC (name) && DECL_CLASS_CONTEXT (name)) ! 156: context_string = TYPE_NAME_STRING (DECL_CLASS_CONTEXT (name)); ! 157: name = DECL_NAME (name); ! 158: } ! 159: ! 160: obstack_grow (&scratch_obstack, aggr_string, strlen (aggr_string)); ! 161: OB_PUTC (' '); ! 162: if (context_string) ! 163: { ! 164: obstack_grow (&scratch_obstack, context_string, strlen (context_string)-1); ! 165: OB_PUTC2 (':', ':'); ! 166: } ! 167: OB_PUTID (name); ! 168: } ! 169: ! 170: /* This must be large enough to hold any anonymous parm name. */ ! 171: static char anon_buffer[sizeof (ANON_PARMNAME_FORMAT) + 20]; ! 172: /* This must be large enough to hold any printed integer or floatingpoint value. */ ! 173: static char digit_buffer[128]; ! 174: ! 175: static void ! 176: dump_type_prefix (t, p) ! 177: tree t; ! 178: int *p; ! 179: { ! 180: int old_p = 0; ! 181: int print_struct = 1; ! 182: tree name; ! 183: ! 184: if (t == NULL_TREE) ! 185: return; ! 186: ! 187: switch (TREE_CODE (t)) ! 188: { ! 189: case ERROR_MARK: ! 190: sprintf (anon_buffer, ANON_PARMNAME_FORMAT, dummy_name++); ! 191: OB_PUTCP (anon_buffer); ! 192: break; ! 193: ! 194: case UNKNOWN_TYPE: ! 195: OB_PUTS ("<unknown type>"); ! 196: return; ! 197: ! 198: case TREE_LIST: ! 199: dump_type (TREE_VALUE (t), &old_p); ! 200: if (TREE_CHAIN (t)) ! 201: { ! 202: if (TREE_CHAIN (t) != void_list_node) ! 203: { ! 204: OB_PUTC (','); ! 205: dump_type (TREE_CHAIN (t), &old_p); ! 206: } ! 207: } ! 208: else OB_PUTS ("..."); ! 209: return; ! 210: ! 211: case POINTER_TYPE: ! 212: *p += 1; ! 213: dump_type_prefix (TREE_TYPE (t), p); ! 214: while (*p) ! 215: { ! 216: OB_PUTC ('*'); ! 217: *p -= 1; ! 218: } ! 219: if (TYPE_READONLY (t)) ! 220: OB_PUTS ("const "); ! 221: if (TYPE_VOLATILE (t)) ! 222: OB_PUTS ("volatile "); ! 223: return; ! 224: ! 225: case OFFSET_TYPE: ! 226: { ! 227: tree type = TREE_TYPE (t); ! 228: if (TREE_CODE (type) == FUNCTION_TYPE) ! 229: { ! 230: type = TREE_TYPE (type); ! 231: if (in_parmlist) ! 232: OB_PUTS ("auto "); ! 233: } ! 234: ! 235: dump_type_prefix (type, &old_p); ! 236: ! 237: OB_PUTC ('('); ! 238: dump_type (TYPE_OFFSET_BASETYPE (t), &old_p); ! 239: OB_PUTC2 (':', ':'); ! 240: while (*p) ! 241: { ! 242: OB_PUTC ('*'); ! 243: *p -= 1; ! 244: } ! 245: if (TYPE_READONLY (t) | TYPE_VOLATILE (t)) ! 246: dump_readonly_or_volatile (t); ! 247: return; ! 248: } ! 249: ! 250: case METHOD_TYPE: ! 251: { ! 252: tree type = TREE_TYPE (t); ! 253: if (in_parmlist) ! 254: OB_PUTS ("auto "); ! 255: ! 256: dump_type_prefix (type, &old_p); ! 257: ! 258: OB_PUTC ('('); ! 259: dump_type (TYPE_METHOD_BASETYPE (t), &old_p); ! 260: OB_PUTC2 (':', ':'); ! 261: while (*p) ! 262: { ! 263: OB_PUTC ('*'); ! 264: *p -= 1; ! 265: } ! 266: if (TYPE_READONLY (t) | TYPE_VOLATILE (t)) ! 267: dump_readonly_or_volatile (t); ! 268: return; ! 269: } ! 270: ! 271: case REFERENCE_TYPE: ! 272: dump_type_prefix (TREE_TYPE (t), p); ! 273: OB_PUTC ('&'); ! 274: if (TYPE_READONLY (t) | TYPE_VOLATILE (t)) ! 275: dump_readonly_or_volatile (t); ! 276: return; ! 277: ! 278: case ARRAY_TYPE: ! 279: if (TYPE_READONLY (t) | TYPE_VOLATILE (t)) ! 280: dump_readonly_or_volatile (t); ! 281: dump_type_prefix (TREE_TYPE (t), p); ! 282: return; ! 283: ! 284: case FUNCTION_TYPE: ! 285: if (in_parmlist) ! 286: OB_PUTS ("auto "); ! 287: dump_type_prefix (TREE_TYPE (t), &old_p); ! 288: OB_PUTC ('('); ! 289: while (*p) ! 290: { ! 291: OB_PUTC ('*'); ! 292: *p -= 1; ! 293: } ! 294: if (TYPE_READONLY (t) | TYPE_VOLATILE (t)) ! 295: dump_readonly_or_volatile (t); ! 296: return; ! 297: ! 298: case IDENTIFIER_NODE: ! 299: OB_PUTID (t); ! 300: OB_PUTC (' '); ! 301: break; ! 302: ! 303: case RECORD_TYPE: ! 304: case UNION_TYPE: ! 305: case ENUMERAL_TYPE: ! 306: dump_aggr_type (t); ! 307: break; ! 308: ! 309: case TYPE_DECL: ! 310: if (TYPE_READONLY (t)) ! 311: OB_PUTS ("const "); ! 312: if (TYPE_VOLATILE (t)) ! 313: OB_PUTS ("volatile "); ! 314: OB_PUTID (DECL_NAME (t)); ! 315: OB_PUTC (' '); ! 316: break; ! 317: ! 318: case INTEGER_TYPE: ! 319: #if 0 ! 320: /* Normally, `unsigned' is part of the deal. Not so if it comes ! 321: with `const' or `volatile'. */ ! 322: if (TYPE_MAIN_VARIANT (t) == unsigned_type (TYPE_MAIN_VARIANT (t)) ! 323: && (TYPE_READONLY (t) || TYPE_VOLATILE (t))) ! 324: OB_PUTS ("unsigned "); ! 325: #endif ! 326: /* fall through. */ ! 327: case REAL_TYPE: ! 328: case VOID_TYPE: ! 329: if (TYPE_READONLY (t)) ! 330: OB_PUTS ("const "); ! 331: if (TYPE_VOLATILE (t)) ! 332: OB_PUTS ("volatile "); ! 333: OB_PUTID (DECL_NAME (TYPE_NAME (t))); ! 334: OB_PUTC (' '); ! 335: break; ! 336: ! 337: default: ! 338: abort (); ! 339: } ! 340: } ! 341: ! 342: static void ! 343: dump_type_suffix (t, p) ! 344: tree t; ! 345: int *p; ! 346: { ! 347: int old_p = 0; ! 348: ! 349: if (t == NULL_TREE) ! 350: return; ! 351: ! 352: switch (TREE_CODE (t)) ! 353: { ! 354: case ERROR_MARK: ! 355: sprintf (anon_buffer, ANON_PARMNAME_FORMAT, dummy_name++); ! 356: OB_PUTCP (anon_buffer); ! 357: break; ! 358: ! 359: case UNKNOWN_TYPE: ! 360: return; ! 361: ! 362: case POINTER_TYPE: ! 363: dump_type_suffix (TREE_TYPE (t), p); ! 364: return; ! 365: ! 366: case OFFSET_TYPE: ! 367: { ! 368: tree type = TREE_TYPE (t); ! 369: ! 370: OB_PUTC (')'); ! 371: if (TREE_CODE (type) == FUNCTION_TYPE) ! 372: { ! 373: #if 0 ! 374: tree next_arg = TREE_CHAIN (TYPE_ARG_TYPES (type)); ! 375: OB_PUTC ('('); ! 376: if (next_arg) ! 377: { ! 378: if (next_arg != void_list_node) ! 379: { ! 380: in_parmlist++; ! 381: dump_type (next_arg, &old_p); ! 382: in_parmlist--; ! 383: } ! 384: } ! 385: else OB_PUTS ("..."); ! 386: OB_PUTC (')'); ! 387: dump_type_suffix (TREE_TYPE (type), p); ! 388: #else ! 389: abort (); ! 390: #endif ! 391: } ! 392: return; ! 393: } ! 394: ! 395: case METHOD_TYPE: ! 396: { ! 397: tree next_arg; ! 398: OB_PUTC (')'); ! 399: next_arg = TREE_CHAIN (TYPE_ARG_TYPES (t)); ! 400: OB_PUTC ('('); ! 401: if (next_arg) ! 402: { ! 403: if (next_arg != void_list_node) ! 404: { ! 405: in_parmlist++; ! 406: dump_type (next_arg, &old_p); ! 407: in_parmlist--; ! 408: } ! 409: } ! 410: else OB_PUTS ("..."); ! 411: OB_PUTC (')'); ! 412: dump_readonly_or_volatile (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t)))); ! 413: dump_type_suffix (TREE_TYPE (t), p); ! 414: return; ! 415: } ! 416: ! 417: case REFERENCE_TYPE: ! 418: dump_type_suffix (TREE_TYPE (t), p); ! 419: return; ! 420: ! 421: case ARRAY_TYPE: ! 422: dump_type_suffix (TREE_TYPE (t), p); ! 423: OB_PUTC2 ('[', ']'); ! 424: return; ! 425: ! 426: case FUNCTION_TYPE: ! 427: OB_PUTC2 (')', '('); ! 428: if (TYPE_ARG_TYPES (t) && TYPE_ARG_TYPES (t) != void_list_node) ! 429: { ! 430: in_parmlist++; ! 431: dump_type (TYPE_ARG_TYPES (t), &old_p); ! 432: in_parmlist--; ! 433: } ! 434: OB_PUTC (')'); ! 435: dump_type_suffix (TREE_TYPE (t), p); ! 436: return; ! 437: ! 438: case IDENTIFIER_NODE: ! 439: case RECORD_TYPE: ! 440: case UNION_TYPE: ! 441: case ENUMERAL_TYPE: ! 442: case TYPE_DECL: ! 443: case INTEGER_TYPE: ! 444: case REAL_TYPE: ! 445: case VOID_TYPE: ! 446: return; ! 447: ! 448: default: ! 449: abort (); ! 450: } ! 451: } ! 452: ! 453: static void ! 454: dump_type (t, p) ! 455: tree t; ! 456: int *p; ! 457: { ! 458: int old_p = 0; ! 459: int print_struct = 1; ! 460: ! 461: if (t == NULL_TREE) ! 462: return; ! 463: ! 464: switch (TREE_CODE (t)) ! 465: { ! 466: case ERROR_MARK: ! 467: sprintf (anon_buffer, ANON_PARMNAME_FORMAT, dummy_name++); ! 468: OB_PUTCP (anon_buffer); ! 469: break; ! 470: ! 471: case UNKNOWN_TYPE: ! 472: OB_PUTS ("<unknown type>"); ! 473: return; ! 474: ! 475: case TREE_LIST: ! 476: dump_type (TREE_VALUE (t), &old_p); ! 477: if (TREE_CHAIN (t)) ! 478: { ! 479: if (TREE_CHAIN (t) != void_list_node) ! 480: { ! 481: OB_PUTC (','); ! 482: dump_type (TREE_CHAIN (t), &old_p); ! 483: } ! 484: } ! 485: else OB_PUTS ("..."); ! 486: return; ! 487: ! 488: case POINTER_TYPE: ! 489: if (TYPE_READONLY (t) | TYPE_VOLATILE (t)) ! 490: dump_readonly_or_volatile (t); ! 491: *p += 1; ! 492: dump_type (TREE_TYPE (t), p); ! 493: while (*p) ! 494: { ! 495: OB_PUTC ('*'); ! 496: *p -= 1; ! 497: } ! 498: return; ! 499: ! 500: case REFERENCE_TYPE: ! 501: if (TYPE_READONLY (t) | TYPE_VOLATILE (t)) ! 502: dump_readonly_or_volatile (t); ! 503: dump_type (TREE_TYPE (t), p); ! 504: OB_PUTC ('&'); ! 505: return; ! 506: ! 507: case ARRAY_TYPE: ! 508: if (TYPE_READONLY (t) | TYPE_VOLATILE (t)) ! 509: dump_readonly_or_volatile (t); ! 510: dump_type (TREE_TYPE (t), p); ! 511: OB_PUTC2 ('[', ']'); ! 512: return; ! 513: ! 514: case OFFSET_TYPE: ! 515: case METHOD_TYPE: ! 516: case FUNCTION_TYPE: ! 517: dump_type_prefix (t, p); ! 518: dump_type_suffix (t, p); ! 519: return; ! 520: ! 521: case IDENTIFIER_NODE: ! 522: OB_PUTID (t); ! 523: OB_PUTC (' '); ! 524: break; ! 525: ! 526: case RECORD_TYPE: ! 527: case UNION_TYPE: ! 528: case ENUMERAL_TYPE: ! 529: dump_aggr_type (t); ! 530: break; ! 531: ! 532: case TYPE_DECL: ! 533: if (TYPE_READONLY (t) | TYPE_VOLATILE (t)) ! 534: dump_readonly_or_volatile (t); ! 535: OB_PUTID (DECL_NAME (t)); ! 536: OB_PUTC (' '); ! 537: break; ! 538: ! 539: case INTEGER_TYPE: ! 540: /* Normally, `unsigned' is part of the deal. Not so if it comes ! 541: with `const' or `volatile'. */ ! 542: if (TYPE_READONLY (t) | TYPE_VOLATILE (t)) ! 543: dump_readonly_or_volatile (t); ! 544: #if 0 ! 545: if (TYPE_MAIN_VARIANT (t) == unsigned_type (TYPE_MAIN_VARIANT (t)) ! 546: && (TYPE_READONLY (t) | TYPE_VOLATILE (t))) ! 547: OB_PUTS ("unsigned "); ! 548: #endif ! 549: OB_PUTID (DECL_NAME (TYPE_NAME (t))); ! 550: OB_PUTC (' '); ! 551: break; ! 552: ! 553: case REAL_TYPE: ! 554: case VOID_TYPE: ! 555: if (TYPE_READONLY (t) | TYPE_VOLATILE (t)) ! 556: dump_readonly_or_volatile (t); ! 557: OB_PUTID (DECL_NAME (TYPE_NAME (t))); ! 558: OB_PUTC (' '); ! 559: break; ! 560: ! 561: case TEMPLATE_TYPE_PARM: ! 562: OB_PUTS ("<template type parm "); ! 563: OB_PUTID (DECL_NAME (TYPE_NAME (t))); ! 564: OB_PUTC ('>'); ! 565: break; ! 566: ! 567: case UNINSTANTIATED_P_TYPE: ! 568: OB_PUTID (DECL_NAME (UPT_TEMPLATE (t))); ! 569: OB_PUTS ("<...>"); ! 570: break; ! 571: ! 572: default: ! 573: abort (); ! 574: } ! 575: } ! 576: ! 577: static void ! 578: dump_decl (t) ! 579: tree t; ! 580: { ! 581: int p = 0; ! 582: ! 583: if (t == NULL_TREE) ! 584: return; ! 585: ! 586: switch (TREE_CODE (t)) ! 587: { ! 588: case ERROR_MARK: ! 589: OB_PUTS (" /* decl error */ "); ! 590: break; ! 591: ! 592: case PARM_DECL: ! 593: dump_type_prefix (TREE_TYPE (t), &p); ! 594: if (DECL_NAME (t)) ! 595: dump_decl (DECL_NAME (t)); ! 596: else ! 597: { ! 598: sprintf (anon_buffer, ANON_PARMNAME_FORMAT, dummy_name++); ! 599: OB_PUTCP (anon_buffer); ! 600: break; ! 601: } ! 602: dump_type_suffix (TREE_TYPE (t), &p); ! 603: return; ! 604: ! 605: case CALL_EXPR: ! 606: dump_decl (TREE_OPERAND (t, 0)); ! 607: OB_PUTC ('('); ! 608: in_parmlist++; ! 609: dump_decl (TREE_OPERAND (t, 1)); ! 610: in_parmlist--; ! 611: t = tree_last (TYPE_ARG_TYPES (TREE_TYPE (t))); ! 612: if (!t || t != void_list_node) ! 613: OB_PUTS ("..."); ! 614: OB_PUTC (')'); ! 615: return; ! 616: ! 617: case ARRAY_REF: ! 618: dump_decl (TREE_OPERAND (t, 0)); ! 619: OB_PUTC ('['); ! 620: dump_decl (TREE_OPERAND (t, 1)); ! 621: OB_PUTC (']'); ! 622: return; ! 623: ! 624: case TYPE_DECL: ! 625: OB_PUTID (DECL_NAME (t)); ! 626: OB_PUTC (' '); ! 627: break; ! 628: ! 629: case TYPE_EXPR: ! 630: abort (); ! 631: break; ! 632: ! 633: case IDENTIFIER_NODE: ! 634: if (t == ansi_opname[TYPE_EXPR]) ! 635: { ! 636: OB_PUTS ("operator "); ! 637: /* Not exactly IDENTIFIER_TYPE_VALUE. */ ! 638: dump_type (TREE_TYPE (t), &p); ! 639: return; ! 640: } ! 641: else if (IDENTIFIER_OPNAME_P (t)) ! 642: { ! 643: char *name_string = operator_name_string (t); ! 644: OB_PUTS ("operator "); ! 645: OB_PUTCP (name_string); ! 646: OB_PUTC (' '); ! 647: } ! 648: else ! 649: { ! 650: OB_PUTID (t); ! 651: OB_PUTC (' '); ! 652: } ! 653: break; ! 654: ! 655: case BIT_NOT_EXPR: ! 656: OB_PUTC2 ('~', ' '); ! 657: dump_decl (TREE_OPERAND (t, 0)); ! 658: return; ! 659: ! 660: case SCOPE_REF: ! 661: OB_PUTID (TREE_OPERAND (t, 0)); ! 662: OB_PUTC2 (':', ':'); ! 663: dump_decl (TREE_OPERAND (t, 1)); ! 664: return; ! 665: ! 666: case INDIRECT_REF: ! 667: OB_PUTC ('*'); ! 668: dump_decl (TREE_OPERAND (t, 0)); ! 669: return; ! 670: ! 671: case ADDR_EXPR: ! 672: OB_PUTC ('&'); ! 673: dump_decl (TREE_OPERAND (t, 0)); ! 674: return; ! 675: ! 676: default: ! 677: abort (); ! 678: } ! 679: } ! 680: ! 681: static void ! 682: dump_init_list (l) ! 683: tree l; ! 684: { ! 685: while (l) ! 686: { ! 687: dump_init (TREE_VALUE (l)); ! 688: if (TREE_CHAIN (l)) ! 689: OB_PUTC (','); ! 690: l = TREE_CHAIN (l); ! 691: } ! 692: } ! 693: ! 694: static void ! 695: dump_init (t) ! 696: tree t; ! 697: { ! 698: int dummy; ! 699: ! 700: switch (TREE_CODE (t)) ! 701: { ! 702: case VAR_DECL: ! 703: case PARM_DECL: ! 704: OB_PUTC (' '); ! 705: OB_PUTID (DECL_NAME (t)); ! 706: OB_PUTC (' '); ! 707: break; ! 708: ! 709: case FUNCTION_DECL: ! 710: { ! 711: tree name = DECL_ASSEMBLER_NAME (t); ! 712: ! 713: if (DESTRUCTOR_NAME_P (name)) ! 714: { ! 715: OB_PUTC2 (' ', '~'); ! 716: OB_PUTID (DECL_NAME (t)); ! 717: } ! 718: else if (IDENTIFIER_TYPENAME_P (name)) ! 719: { ! 720: dummy = 0; ! 721: OB_PUTS ("operator "); ! 722: dump_type (TREE_TYPE (name), &dummy); ! 723: } ! 724: else if (IDENTIFIER_OPNAME_P (name)) ! 725: { ! 726: char *name_string = operator_name_string (name); ! 727: OB_PUTS ("operator "); ! 728: OB_PUTCP (name_string); ! 729: OB_PUTC (' '); ! 730: } ! 731: #if 0 ! 732: else if (WRAPPER_NAME_P (name)) ! 733: sprintf (inline_bufp, " ()%s", IDENTIFIER_POINTER (DECL_NAME (t))); ! 734: else if (WRAPPER_PRED_NAME_P (name)) ! 735: sprintf (inline_bufp, " ()?%s", IDENTIFIER_POINTER (DECL_NAME (t))); ! 736: else if (ANTI_WRAPPER_NAME_P (name)) ! 737: sprintf (inline_bufp, " ~()%s", IDENTIFIER_POINTER (DECL_NAME (t))); ! 738: #endif ! 739: else ! 740: { ! 741: OB_PUTC (' '); ! 742: OB_PUTID (DECL_NAME (t)); ! 743: } ! 744: OB_PUTC (' '); ! 745: } ! 746: break; ! 747: ! 748: case CONST_DECL: ! 749: dummy = 0; ! 750: OB_PUTC2 ('(', '('); ! 751: dump_type (TREE_TYPE (t), &dummy); ! 752: OB_PUTC (')'); ! 753: dump_init (DECL_INITIAL (t)); ! 754: OB_PUTC (')'); ! 755: return; ! 756: ! 757: case INTEGER_CST: ! 758: sprintf (digit_buffer, " %d ", TREE_INT_CST_LOW (t)); ! 759: OB_PUTCP (digit_buffer); ! 760: break; ! 761: ! 762: case REAL_CST: ! 763: sprintf (digit_buffer, " %g ", TREE_REAL_CST (t)); ! 764: OB_PUTCP (digit_buffer); ! 765: break; ! 766: ! 767: case STRING_CST: ! 768: { ! 769: char *p = TREE_STRING_POINTER (t); ! 770: int len = TREE_STRING_LENGTH (t) - 1; ! 771: int i; ! 772: ! 773: OB_PUTC ('\"'); ! 774: for (i = 0; i < len; i++) ! 775: { ! 776: register char c = p[i]; ! 777: if (c == '\"' || c == '\\') ! 778: OB_PUTC ('\\'); ! 779: if (c >= ' ' && c < 0177) ! 780: OB_PUTC (c); ! 781: else ! 782: { ! 783: sprintf (digit_buffer, "\\%03o", c); ! 784: OB_PUTCP (digit_buffer); ! 785: } ! 786: } ! 787: OB_PUTC ('\"'); ! 788: } ! 789: return; ! 790: ! 791: case COMPOUND_EXPR: ! 792: dump_binary_op (",", t, 1); ! 793: break; ! 794: ! 795: case COND_EXPR: ! 796: OB_PUTC ('('); ! 797: dump_init (TREE_OPERAND (t, 0)); ! 798: OB_PUTS (" ? "); ! 799: dump_init (TREE_OPERAND (t, 1)); ! 800: OB_PUTS (" : "); ! 801: dump_init (TREE_OPERAND (t, 2)); ! 802: OB_PUTC (')'); ! 803: return; ! 804: ! 805: case SAVE_EXPR: ! 806: if (TREE_HAS_CONSTRUCTOR (t)) ! 807: { ! 808: dummy = 0; ! 809: OB_PUTS ("new "); ! 810: dump_type (TREE_TYPE (TREE_TYPE (t)), &dummy); ! 811: PARM_DECL_EXPR (t) = 1; ! 812: } ! 813: else ! 814: { ! 815: sorry ("operand of SAVE_EXPR not understood"); ! 816: scratch_obstack.next_free ! 817: = obstack_base (&scratch_obstack) + scratch_error_offset; ! 818: } ! 819: return; ! 820: ! 821: case NEW_EXPR: ! 822: OB_PUTID (DECL_NAME (TYPE_NAME (TREE_TYPE (t)))); ! 823: OB_PUTC ('('); ! 824: dump_init_list (TREE_CHAIN (TREE_OPERAND (t, 1))); ! 825: OB_PUTC (')'); ! 826: return; ! 827: ! 828: case CALL_EXPR: ! 829: OB_PUTC ('('); ! 830: dump_init (TREE_OPERAND (t, 0)); ! 831: dump_init_list (TREE_OPERAND (t, 1)); ! 832: OB_PUTC (')'); ! 833: return; ! 834: ! 835: case WITH_CLEANUP_EXPR: ! 836: /* Note that this only works for G++ cleanups. If somebody ! 837: builds a general cleanup, there's no way to represent it. */ ! 838: dump_init (TREE_OPERAND (t, 0)); ! 839: return; ! 840: ! 841: case TARGET_EXPR: ! 842: /* Note that this only works for G++ target exprs. If somebody ! 843: builds a general TARGET_EXPR, there's no way to represent that ! 844: it initializes anything other that the parameter slot for the ! 845: default argument. */ ! 846: dump_init (TREE_OPERAND (t, 1)); ! 847: return; ! 848: ! 849: case MODIFY_EXPR: ! 850: case PLUS_EXPR: ! 851: case MINUS_EXPR: ! 852: case MULT_EXPR: ! 853: case TRUNC_DIV_EXPR: ! 854: case TRUNC_MOD_EXPR: ! 855: case MIN_EXPR: ! 856: case MAX_EXPR: ! 857: case LSHIFT_EXPR: ! 858: case RSHIFT_EXPR: ! 859: case BIT_IOR_EXPR: ! 860: case BIT_XOR_EXPR: ! 861: case BIT_AND_EXPR: ! 862: case BIT_ANDTC_EXPR: ! 863: case TRUTH_ANDIF_EXPR: ! 864: case TRUTH_ORIF_EXPR: ! 865: case LT_EXPR: ! 866: case LE_EXPR: ! 867: case GT_EXPR: ! 868: case GE_EXPR: ! 869: case EQ_EXPR: ! 870: case NE_EXPR: ! 871: dump_binary_op (opname_tab[(int) TREE_CODE (t)], t, ! 872: strlen (opname_tab[(int) TREE_CODE (t)])); ! 873: return; ! 874: ! 875: case CEIL_DIV_EXPR: ! 876: case FLOOR_DIV_EXPR: ! 877: case ROUND_DIV_EXPR: ! 878: dump_binary_op ("/", t, 1); ! 879: return; ! 880: ! 881: case CEIL_MOD_EXPR: ! 882: case FLOOR_MOD_EXPR: ! 883: case ROUND_MOD_EXPR: ! 884: dump_binary_op ("%", t, 1); ! 885: return; ! 886: ! 887: case COMPONENT_REF: ! 888: dump_binary_op (".", t, 1); ! 889: return; ! 890: ! 891: case CONVERT_EXPR: ! 892: dump_unary_op ("+", t, 1); ! 893: return; ! 894: ! 895: case ADDR_EXPR: ! 896: if (TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL ! 897: || TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST) ! 898: dump_init (TREE_OPERAND (t, 0)); ! 899: else ! 900: dump_unary_op ("&", t, 1); ! 901: return; ! 902: ! 903: case INDIRECT_REF: ! 904: dump_unary_op ("*", t, 1); ! 905: return; ! 906: ! 907: case NEGATE_EXPR: ! 908: case BIT_NOT_EXPR: ! 909: case TRUTH_NOT_EXPR: ! 910: case PREDECREMENT_EXPR: ! 911: case PREINCREMENT_EXPR: ! 912: dump_unary_op (opname_tab [(int)TREE_CODE (t)], t, ! 913: strlen (opname_tab[(int) TREE_CODE (t)])); ! 914: return; ! 915: ! 916: case POSTDECREMENT_EXPR: ! 917: case POSTINCREMENT_EXPR: ! 918: OB_PUTC ('('); ! 919: dump_init (TREE_OPERAND (t, 0)); ! 920: OB_PUTCP (opname_tab[(int)TREE_CODE (t)]); ! 921: OB_PUTC (')'); ! 922: return; ! 923: ! 924: case NOP_EXPR: ! 925: dummy = 0; ! 926: OB_PUTC2 ('(', '('); ! 927: dump_type (TREE_TYPE (t), &dummy); ! 928: OB_PUTC (')'); ! 929: dump_init (TREE_OPERAND (t, 0)); ! 930: OB_PUTC (')'); ! 931: return; ! 932: ! 933: case CONSTRUCTOR: ! 934: OB_PUTC ('{'); ! 935: dump_init_list (CONSTRUCTOR_ELTS (t)); ! 936: OB_PUTC ('}'); ! 937: return; ! 938: ! 939: /* This list is incomplete, but should suffice for now. ! 940: It is very important that `sorry' does not call ! 941: `report_error_function'. That could cause an infinite loop. */ ! 942: default: ! 943: sorry ("`%s' not supported for default parameters", ! 944: tree_code_name[(int) TREE_CODE (t)]); ! 945: ! 946: /* fall through to ERROR_MARK... */ ! 947: case ERROR_MARK: ! 948: scratch_obstack.next_free ! 949: = obstack_base (&scratch_obstack) + scratch_error_offset; ! 950: return; ! 951: } ! 952: } ! 953: ! 954: static void ! 955: dump_binary_op (opstring, t, len) ! 956: char *opstring; ! 957: tree t; ! 958: int len; ! 959: { ! 960: OB_PUTC ('('); ! 961: dump_init (TREE_OPERAND (t, 0)); ! 962: OB_PUTC (' '); ! 963: OB_PUTCP (opstring); ! 964: OB_PUTC (' '); ! 965: dump_init (TREE_OPERAND (t, 1)); ! 966: OB_PUTC (')'); ! 967: } ! 968: ! 969: static void ! 970: dump_unary_op (opstring, t, len) ! 971: char *opstring; ! 972: tree t; ! 973: int len; ! 974: { ! 975: OB_PUTC ('('); ! 976: OB_PUTC (' '); ! 977: OB_PUTCP (opstring); ! 978: OB_PUTC (' '); ! 979: dump_init (TREE_OPERAND (t, 0)); ! 980: OB_PUTC (')'); ! 981: } ! 982: ! 983: /* Pretty printing for announce_function. CNAME is the TYPE_DECL for ! 984: the class that FNDECL belongs to, if we could not figure that out ! 985: from FNDECL itself. FNDECL is the declaration of the function we ! 986: are interested in seeing. PRINT_RET_TYPE_P is non-zero if we ! 987: should print the type that this function returns. */ ! 988: ! 989: char * ! 990: fndecl_as_string (cname, fndecl, print_ret_type_p) ! 991: tree cname, fndecl; ! 992: int print_ret_type_p; ! 993: { ! 994: tree name = DECL_ASSEMBLER_NAME (fndecl); ! 995: tree fntype = TREE_TYPE (fndecl); ! 996: tree parmtypes = TYPE_ARG_TYPES (fntype); ! 997: int p = 0; ! 998: int spaces = 0; ! 999: ! 1000: OB_INIT (); ! 1001: ! 1002: if (DECL_CLASS_CONTEXT (fndecl)) ! 1003: cname = TYPE_NAME (DECL_CLASS_CONTEXT (fndecl)); ! 1004: ! 1005: if (print_ret_type_p && ! IDENTIFIER_TYPENAME_P (name)) ! 1006: { ! 1007: dump_type_prefix (TREE_TYPE (fntype), &p); ! 1008: OB_PUTC (' '); ! 1009: } ! 1010: if (DECL_STATIC_FUNCTION_P (fndecl)) ! 1011: OB_PUTS ("static "); ! 1012: ! 1013: if (cname) ! 1014: { ! 1015: dump_type (cname, &p); ! 1016: *((char *) obstack_next_free (&scratch_obstack) - 1) = ':'; ! 1017: OB_PUTC (':'); ! 1018: if (TREE_CODE (fntype) == METHOD_TYPE && parmtypes) ! 1019: parmtypes = TREE_CHAIN (parmtypes); ! 1020: if (DECL_CONSTRUCTOR_FOR_VBASE_P (fndecl)) ! 1021: /* Skip past "in_charge" identifier. */ ! 1022: parmtypes = TREE_CHAIN (parmtypes); ! 1023: } ! 1024: ! 1025: if (DESTRUCTOR_NAME_P (name)) ! 1026: { ! 1027: OB_PUTC ('~'); ! 1028: parmtypes = TREE_CHAIN (parmtypes); ! 1029: dump_decl (DECL_NAME (fndecl)); ! 1030: } ! 1031: else if (IDENTIFIER_TYPENAME_P (name)) ! 1032: { ! 1033: /* This cannot use the hack that the operator's return ! 1034: type is stashed off of its name because it may be ! 1035: used for error reporting. In the case of conflicting ! 1036: declarations, both will have the same name, yet ! 1037: the types will be different, hence the TREE_TYPE field ! 1038: of the first name will be clobbered by the second. */ ! 1039: OB_PUTS ("operator "); ! 1040: dump_type (TREE_TYPE (TREE_TYPE (fndecl)), &p); ! 1041: } ! 1042: else if (IDENTIFIER_OPNAME_P (name)) ! 1043: { ! 1044: char *name_string = operator_name_string (name); ! 1045: OB_PUTS ("operator "); ! 1046: OB_PUTCP (name_string); ! 1047: OB_PUTC (' '); ! 1048: } ! 1049: else if (DECL_CONSTRUCTOR_P (fndecl)) ! 1050: { ! 1051: #ifdef SOS ! 1052: if (TYPE_DYNAMIC (IDENTIFIER_TYPE_VALUE (cname))) ! 1053: { ! 1054: OB_PUTS ("dynamic "); ! 1055: parmtypes = TREE_CHAIN (parmtypes); ! 1056: } ! 1057: #endif ! 1058: dump_decl (DECL_NAME (fndecl)); ! 1059: } ! 1060: else ! 1061: { ! 1062: #if 0 ! 1063: if (WRAPPER_NAME_P (name)) ! 1064: OB_PUTC2 ('(', ')'); ! 1065: if (WRAPPER_PRED_NAME_P (name)) ! 1066: OB_PUTS ("()?"); ! 1067: else if (ANTI_WRAPPER_NAME_P (name)) ! 1068: OB_PUTS ("~()"); ! 1069: #endif ! 1070: dump_decl (DECL_NAME (fndecl)); ! 1071: } ! 1072: ! 1073: OB_PUTC ('('); ! 1074: if (parmtypes) ! 1075: { ! 1076: in_parmlist++; ! 1077: if (parmtypes != void_list_node) ! 1078: spaces = 2; ! 1079: while (parmtypes && parmtypes != void_list_node) ! 1080: { ! 1081: char *last_space; ! 1082: dump_type (TREE_VALUE (parmtypes), &p); ! 1083: last_space = (char *)obstack_next_free (&scratch_obstack); ! 1084: while (last_space[-1] == ' ') ! 1085: last_space--; ! 1086: scratch_obstack.next_free = last_space; ! 1087: if (TREE_PURPOSE (parmtypes)) ! 1088: { ! 1089: scratch_error_offset = obstack_object_size (&scratch_obstack); ! 1090: OB_PUTS (" (= "); ! 1091: dump_init (TREE_PURPOSE (parmtypes)); ! 1092: OB_PUTC (')'); ! 1093: } ! 1094: OB_PUTC2 (',', ' '); ! 1095: parmtypes = TREE_CHAIN (parmtypes); ! 1096: } ! 1097: in_parmlist--; ! 1098: } ! 1099: ! 1100: if (parmtypes) ! 1101: { ! 1102: if (spaces) ! 1103: scratch_obstack.next_free = obstack_next_free (&scratch_obstack)-spaces; ! 1104: } ! 1105: else ! 1106: OB_PUTS ("..."); ! 1107: ! 1108: OB_PUTC (')'); ! 1109: ! 1110: if (print_ret_type_p && ! IDENTIFIER_TYPENAME_P (name)) ! 1111: dump_type_suffix (TREE_TYPE (fntype), &p); ! 1112: ! 1113: if (TREE_CODE (fntype) == METHOD_TYPE) ! 1114: dump_readonly_or_volatile (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype)))); ! 1115: ! 1116: OB_FINISH (); ! 1117: ! 1118: return (char *)obstack_base (&scratch_obstack); ! 1119: } ! 1120: ! 1121: /* Same, but handtype a _TYPE. */ ! 1122: char * ! 1123: type_as_string (buf, typ) ! 1124: char *buf; ! 1125: tree typ; ! 1126: { ! 1127: int p = 0; ! 1128: int spaces = 0; ! 1129: ! 1130: OB_INIT (); ! 1131: ! 1132: dump_type(typ,&p); ! 1133: ! 1134: OB_FINISH (); ! 1135: ! 1136: return (char *)obstack_base (&scratch_obstack); ! 1137: } ! 1138: ! 1139: /* Move inline function defintions out of structure so that they ! 1140: can be processed normally. CNAME is the name of the class ! 1141: we are working from, METHOD_LIST is the list of method lists ! 1142: of the structure. We delete friend methods here, after ! 1143: saving away their inline function definitions (if any). */ ! 1144: ! 1145: void ! 1146: do_inline_function_hair (type, friend_list) ! 1147: tree type, friend_list; ! 1148: { ! 1149: tree cname = TYPE_IDENTIFIER (type); ! 1150: tree method = TYPE_METHODS (type); ! 1151: ! 1152: if (method && TREE_CODE (method) == TREE_VEC) ! 1153: { ! 1154: if (TREE_VEC_ELT (method, 0)) ! 1155: method = TREE_VEC_ELT (method, 0); ! 1156: else ! 1157: method = TREE_VEC_ELT (method, 1); ! 1158: } ! 1159: ! 1160: while (method) ! 1161: { ! 1162: /* Do inline member functions. */ ! 1163: struct pending_inline *info = DECL_PENDING_INLINE_INFO (method); ! 1164: if (info) ! 1165: { ! 1166: tree args; ! 1167: ! 1168: assert (info->fndecl == method); ! 1169: args = DECL_ARGUMENTS (method); ! 1170: while (args) ! 1171: { ! 1172: DECL_CONTEXT (args) = method; ! 1173: args = TREE_CHAIN (args); ! 1174: } ! 1175: ! 1176: /* Allow this decl to be seen in global scope */ ! 1177: IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (method)) = method; ! 1178: } ! 1179: method = TREE_CHAIN (method); ! 1180: } ! 1181: while (friend_list) ! 1182: { ! 1183: tree fndecl = TREE_VALUE (friend_list); ! 1184: struct pending_inline *info = DECL_PENDING_INLINE_INFO (fndecl); ! 1185: if (info) ! 1186: { ! 1187: tree args; ! 1188: ! 1189: assert (info->fndecl == fndecl); ! 1190: args = DECL_ARGUMENTS (fndecl); ! 1191: while (args) ! 1192: { ! 1193: DECL_CONTEXT (args) = fndecl; ! 1194: args = TREE_CHAIN (args); ! 1195: } ! 1196: ! 1197: /* Allow this decl to be seen in global scope */ ! 1198: IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (fndecl)) = fndecl; ! 1199: } ! 1200: ! 1201: friend_list = TREE_CHAIN (friend_list); ! 1202: } ! 1203: } ! 1204: ! 1205: /* Report a argument type mismatch between the best declared function ! 1206: we could find and the current argument list that we have. */ ! 1207: void ! 1208: report_type_mismatch (cp, parmtypes, name_kind, err_name) ! 1209: struct candidate *cp; ! 1210: tree parmtypes; ! 1211: char *name_kind, *err_name; ! 1212: { ! 1213: int i = cp->u.bad_arg; ! 1214: tree ttf, tta; ! 1215: char *tmp_firstobj; ! 1216: ! 1217: switch (i) ! 1218: { ! 1219: case -4: ! 1220: assert (TREE_CODE (cp->function) == TEMPLATE_DECL); ! 1221: error ("type unification failed for function template `%s'", err_name); ! 1222: return; ! 1223: ! 1224: case -3: ! 1225: if (TYPE_READONLY (TREE_TYPE (TREE_VALUE (parmtypes)))) ! 1226: error ("call to const %s `%s' with non-const object", name_kind, err_name); ! 1227: else ! 1228: error ("call to non-const %s `%s' with const object", name_kind, err_name); ! 1229: return; ! 1230: case -2: ! 1231: error ("too few arguments for %s `%s'", name_kind, err_name); ! 1232: return; ! 1233: case -1: ! 1234: error ("too many arguments for %s `%s'", name_kind, err_name); ! 1235: return; ! 1236: case 0: ! 1237: if (TREE_CODE (TREE_TYPE (cp->function)) == METHOD_TYPE) ! 1238: { ! 1239: /* Happens when we have an ambiguous base class. */ ! 1240: assert (get_binfo (DECL_CLASS_CONTEXT (cp->function), ! 1241: TREE_TYPE (TREE_TYPE (TREE_VALUE (parmtypes))), 1) == error_mark_node); ! 1242: return; ! 1243: } ! 1244: } ! 1245: ! 1246: ttf = TYPE_ARG_TYPES (TREE_TYPE (cp->function)); ! 1247: tta = parmtypes; ! 1248: ! 1249: while (i-- > 0) ! 1250: { ! 1251: ttf = TREE_CHAIN (ttf); ! 1252: tta = TREE_CHAIN (tta); ! 1253: } ! 1254: ! 1255: OB_INIT (); ! 1256: OB_PUTS ("bad argument "); ! 1257: sprintf (digit_buffer, "%d", ! 1258: cp->u.bad_arg - (TREE_CODE (TREE_TYPE (cp->function)) == METHOD_TYPE)); ! 1259: OB_PUTCP (digit_buffer); ! 1260: OB_PUTS (" for function `"); ! 1261: ! 1262: tmp_firstobj = scratch_firstobj; ! 1263: scratch_firstobj = 0; ! 1264: fndecl_as_string (0, cp->function, 0); ! 1265: scratch_firstobj = tmp_firstobj; ! 1266: ! 1267: /* We know that the last char written is next_free-1. */ ! 1268: ((char *) obstack_next_free (&scratch_obstack))[-1] = '\''; ! 1269: OB_PUTS (" (type was "); ! 1270: ! 1271: /* Reset `i' so that type printing routines do the right thing. */ ! 1272: if (tta) ! 1273: { ! 1274: enum tree_code code = TREE_CODE (TREE_TYPE (TREE_VALUE (tta))); ! 1275: if (code == ERROR_MARK) ! 1276: OB_PUTS ("(failed type instatiation)"); ! 1277: else ! 1278: { ! 1279: i = (code == FUNCTION_TYPE || code == METHOD_TYPE); ! 1280: dump_type (TREE_TYPE (TREE_VALUE (tta)), &i); ! 1281: } ! 1282: } ! 1283: else OB_PUTS ("void"); ! 1284: OB_PUTC (')'); ! 1285: OB_FINISH (); ! 1286: ! 1287: tmp_firstobj = (char *)alloca (obstack_object_size (&scratch_obstack)); ! 1288: bcopy (obstack_base (&scratch_obstack), tmp_firstobj, ! 1289: obstack_object_size (&scratch_obstack)); ! 1290: error (tmp_firstobj); ! 1291: } ! 1292: ! 1293: /* Here is where overload code starts. */ ! 1294: ! 1295: /* Array of types seen so far in top-level call to `build_overload_name'. ! 1296: Allocated and deallocated by caller. */ ! 1297: static tree *typevec; ! 1298: ! 1299: /* Number of types interned by `build_overload_name' so far. */ ! 1300: static int maxtype; ! 1301: ! 1302: /* Number of occurances of last type seen. */ ! 1303: static int nrepeats; ! 1304: ! 1305: /* Nonzero if we should not try folding parameter types. */ ! 1306: static int nofold; ! 1307: ! 1308: #define ALLOCATE_TYPEVEC(PARMTYPES) \ ! 1309: do { maxtype = 0, nrepeats = 0; \ ! 1310: typevec = (tree *)alloca (list_length (PARMTYPES) * sizeof (tree)); } while (0) ! 1311: ! 1312: #define DEALLOCATE_TYPEVEC(PARMTYPES) \ ! 1313: do { tree t = (PARMTYPES); \ ! 1314: while (t) { TREE_USED (TREE_VALUE (t)) = 0; t = TREE_CHAIN (t); } \ ! 1315: } while (0) ! 1316: ! 1317: /* Code to concatenate an asciified integer to a string, ! 1318: and return the end of the string. */ ! 1319: static ! 1320: #ifdef __GNUC__ ! 1321: __inline ! 1322: #endif ! 1323: char * ! 1324: icat (i) ! 1325: int i; ! 1326: { ! 1327: if (i < 0) ! 1328: { ! 1329: OB_PUTC ('m'); ! 1330: i = -i; ! 1331: } ! 1332: if (i < 10) ! 1333: OB_PUTC ('0' + i); ! 1334: else ! 1335: { ! 1336: icat (i / 10); ! 1337: OB_PUTC ('0' + (i % 10)); ! 1338: } ! 1339: } ! 1340: ! 1341: static ! 1342: #ifdef __GNUC__ ! 1343: __inline ! 1344: #endif ! 1345: void ! 1346: flush_repeats (type) ! 1347: tree type; ! 1348: { ! 1349: int tindex = 0; ! 1350: char *rval; ! 1351: ! 1352: while (typevec[tindex] != type) ! 1353: tindex++; ! 1354: ! 1355: if (nrepeats > 1) ! 1356: { ! 1357: OB_PUTC ('N'); ! 1358: icat (nrepeats); ! 1359: if (nrepeats > 9) ! 1360: OB_PUTC ('_'); ! 1361: } ! 1362: else ! 1363: OB_PUTC ('T'); ! 1364: nrepeats = 0; ! 1365: icat (tindex); ! 1366: if (tindex > 9) ! 1367: OB_PUTC ('_'); ! 1368: } ! 1369: ! 1370: static void build_overload_identifier (); ! 1371: ! 1372: static void ! 1373: build_overload_nested_name (context) ! 1374: tree context; ! 1375: { ! 1376: tree name = DECL_ASSEMBLER_NAME (context); ! 1377: if (DECL_CONTEXT (context)) ! 1378: { ! 1379: context = DECL_CONTEXT (context); ! 1380: if (TREE_CODE_CLASS (TREE_CODE (context)) == 't') ! 1381: context = TYPE_NAME (context); ! 1382: build_overload_nested_name (context); ! 1383: } ! 1384: build_overload_identifier (name); ! 1385: } ! 1386: ! 1387: static void ! 1388: build_overload_value (type, value) ! 1389: tree type, value; ! 1390: { ! 1391: char buf[40]; ! 1392: while (TREE_CODE (value) == NON_LVALUE_EXPR) ! 1393: value = TREE_OPERAND (value, 0); ! 1394: assert (TREE_CODE (type) == PARM_DECL); ! 1395: type = TREE_TYPE (type); ! 1396: switch (TREE_CODE (type)) ! 1397: { ! 1398: case INTEGER_TYPE: ! 1399: case ENUMERAL_TYPE: ! 1400: { ! 1401: assert (TREE_CODE (value) == INTEGER_CST); ! 1402: if (TYPE_MODE (value) == DImode) ! 1403: { ! 1404: if (tree_int_cst_lt (value, integer_zero_node)) ! 1405: { ! 1406: OB_PUTC ('m'); ! 1407: value = build_int_2 (~ TREE_INT_CST_LOW (value), ! 1408: - TREE_INT_CST_HIGH (value)); ! 1409: } ! 1410: if (TREE_INT_CST_HIGH (value) != (TREE_INT_CST_LOW (value) >> 31)) ! 1411: { ! 1412: /* need to print a DImode value in decimal */ ! 1413: sorry ("conversion of long long as PT parameter"); ! 1414: } ! 1415: /* else fall through to print in smaller mode */ ! 1416: } ! 1417: /* SImode or smaller */ ! 1418: icat (TREE_INT_CST_LOW (value)); ! 1419: return; ! 1420: } ! 1421: #ifndef REAL_IS_NOT_DOUBLE ! 1422: case REAL_TYPE: ! 1423: { ! 1424: REAL_VALUE_TYPE val; ! 1425: char *bufp = digit_buffer; ! 1426: ! 1427: assert (TREE_CODE (value) == REAL_CST); ! 1428: val = TREE_REAL_CST (value); ! 1429: if (val < 0) ! 1430: { ! 1431: val = -val; ! 1432: *bufp++ = 'm'; ! 1433: } ! 1434: sprintf (bufp, "%e", val); ! 1435: bufp = strchr (bufp, 'e'); ! 1436: if (!bufp) ! 1437: strcat (buf, "e0"); ! 1438: else ! 1439: { ! 1440: char *p; ! 1441: bufp++; ! 1442: if (*bufp == '-') ! 1443: { ! 1444: *bufp++ = 'm'; ! 1445: } ! 1446: p = bufp; ! 1447: if (*p == '+') ! 1448: p++; ! 1449: while (*p == '0') ! 1450: p++; ! 1451: if (*p == 0) ! 1452: { ! 1453: *bufp++ = '0'; ! 1454: *bufp = 0; ! 1455: } ! 1456: else if (p != bufp) ! 1457: { ! 1458: while (*p) ! 1459: *bufp++ = *p++; ! 1460: *bufp = 0; ! 1461: } ! 1462: } ! 1463: OB_PUTCP (buf); ! 1464: return; ! 1465: } ! 1466: #endif ! 1467: case POINTER_TYPE: ! 1468: value = TREE_OPERAND (value, 0); ! 1469: if (TREE_CODE (value) == VAR_DECL) ! 1470: { ! 1471: assert (DECL_NAME (value) != 0); ! 1472: build_overload_identifier (DECL_NAME (value)); ! 1473: return; ! 1474: } ! 1475: else ! 1476: { ! 1477: debug_tree (type); ! 1478: debug_tree (value); ! 1479: abort (); ! 1480: } ! 1481: default: ! 1482: sorry ("conversion of %s as PT parameter", ! 1483: tree_code_name [(int) TREE_CODE (type)]); ! 1484: abort (); ! 1485: } ! 1486: } ! 1487: ! 1488: static void ! 1489: build_overload_identifier (name) ! 1490: tree name; ! 1491: { ! 1492: if (IDENTIFIER_TEMPLATE (name)) ! 1493: { ! 1494: tree template, parmlist, arglist, tname; ! 1495: int i, nparms; ! 1496: template = IDENTIFIER_TEMPLATE (name); ! 1497: arglist = TREE_VALUE (template); ! 1498: template = TREE_PURPOSE (template); ! 1499: tname = DECL_NAME (template); ! 1500: parmlist = DECL_ARGUMENTS (template); ! 1501: nparms = TREE_VEC_LENGTH (parmlist); ! 1502: OB_PUTC ('t'); ! 1503: icat (IDENTIFIER_LENGTH (tname)); ! 1504: OB_PUTID (tname); ! 1505: icat (nparms); ! 1506: for (i = 0; i < nparms; i++) ! 1507: { ! 1508: tree parm = TREE_VEC_ELT (parmlist, i); ! 1509: tree arg = TREE_VEC_ELT (arglist, i); ! 1510: if (TREE_CODE (parm) == IDENTIFIER_NODE) ! 1511: { ! 1512: /* This parameter is a type. */ ! 1513: OB_PUTC ('Z'); ! 1514: build_overload_name (arg, 0, 0); ! 1515: } ! 1516: else ! 1517: { ! 1518: /* It's a PARM_DECL. */ ! 1519: build_overload_name (TREE_TYPE (parm), 0, 0); ! 1520: build_overload_value (parm, arg); ! 1521: } ! 1522: } ! 1523: } ! 1524: else ! 1525: { ! 1526: icat (IDENTIFIER_LENGTH (name)); ! 1527: OB_PUTID (name); ! 1528: } ! 1529: } ! 1530: ! 1531: /* Given a list of parameters in PARMTYPES, create an unambiguous ! 1532: overload string. Should distinguish any type that C (or C++) can ! 1533: distinguish. I.e., pointers to functions are treated correctly. ! 1534: ! 1535: Caller must deal with whether a final `e' goes on the end or not. ! 1536: ! 1537: Any default conversions must take place before this function ! 1538: is called. ! 1539: ! 1540: BEGIN and END control initialization and finalization of the ! 1541: obstack where we build the string. */ ! 1542: ! 1543: char * ! 1544: build_overload_name (parmtypes, begin, end) ! 1545: tree parmtypes; ! 1546: int begin, end; ! 1547: { ! 1548: int just_one; ! 1549: tree parmtype; ! 1550: ! 1551: if (begin) OB_INIT (); ! 1552: ! 1553: if (just_one = (TREE_CODE (parmtypes) != TREE_LIST)) ! 1554: { ! 1555: parmtype = parmtypes; ! 1556: goto only_one; ! 1557: } ! 1558: ! 1559: while (parmtypes) ! 1560: { ! 1561: parmtype = TREE_VALUE (parmtypes); ! 1562: ! 1563: only_one: ! 1564: ! 1565: if (! nofold) ! 1566: { ! 1567: if (! just_one) ! 1568: /* Every argument gets counted. */ ! 1569: typevec[maxtype++] = parmtype; ! 1570: ! 1571: if (TREE_USED (parmtype)) ! 1572: { ! 1573: if (! just_one && parmtype == typevec[maxtype-2]) ! 1574: nrepeats++; ! 1575: else ! 1576: { ! 1577: if (nrepeats) ! 1578: flush_repeats (parmtype); ! 1579: if (! just_one && TREE_CHAIN (parmtypes) ! 1580: && parmtype == TREE_VALUE (TREE_CHAIN (parmtypes))) ! 1581: nrepeats++; ! 1582: else ! 1583: { ! 1584: int tindex = 0; ! 1585: ! 1586: while (typevec[tindex] != parmtype) ! 1587: tindex++; ! 1588: OB_PUTC ('T'); ! 1589: icat (tindex); ! 1590: if (tindex > 9) ! 1591: OB_PUTC ('_'); ! 1592: } ! 1593: } ! 1594: goto next; ! 1595: } ! 1596: if (nrepeats) ! 1597: flush_repeats (typevec[maxtype-2]); ! 1598: if (! just_one ! 1599: /* Only cache types which take more than one character. */ ! 1600: && (parmtype != TYPE_MAIN_VARIANT (parmtype) ! 1601: || (TREE_CODE (parmtype) != INTEGER_TYPE ! 1602: && TREE_CODE (parmtype) != REAL_TYPE))) ! 1603: TREE_USED (parmtype) = 1; ! 1604: } ! 1605: ! 1606: if (TREE_READONLY (parmtype)) ! 1607: OB_PUTC ('C'); ! 1608: if (TREE_CODE (parmtype) == INTEGER_TYPE ! 1609: && TYPE_MAIN_VARIANT (parmtype) == unsigned_type (TYPE_MAIN_VARIANT (parmtype))) ! 1610: OB_PUTC ('U'); ! 1611: if (TYPE_VOLATILE (parmtype)) ! 1612: OB_PUTC ('V'); ! 1613: ! 1614: switch (TREE_CODE (parmtype)) ! 1615: { ! 1616: case OFFSET_TYPE: ! 1617: OB_PUTC ('O'); ! 1618: build_overload_name (TYPE_OFFSET_BASETYPE (parmtype), 0, 0); ! 1619: OB_PUTC ('_'); ! 1620: build_overload_name (TREE_TYPE (parmtype), 0, 0); ! 1621: break; ! 1622: ! 1623: case REFERENCE_TYPE: ! 1624: OB_PUTC ('R'); ! 1625: goto more; ! 1626: ! 1627: case ARRAY_TYPE: ! 1628: #if PARM_CAN_BE_ARRAY_TYPE ! 1629: { ! 1630: tree length; ! 1631: ! 1632: OB_PUTC ('A'); ! 1633: length = array_type_nelts (parmtype); ! 1634: if (TREE_CODE (length) == INTEGER_CST) ! 1635: icat (TREE_INT_CST_LOW (length) + 1); ! 1636: OB_PUTC ('_'); ! 1637: goto more; ! 1638: } ! 1639: #else ! 1640: OB_PUTC ('P'); ! 1641: goto more; ! 1642: #endif ! 1643: ! 1644: case POINTER_TYPE: ! 1645: OB_PUTC ('P'); ! 1646: more: ! 1647: build_overload_name (TREE_TYPE (parmtype), 0, 0); ! 1648: break; ! 1649: ! 1650: case FUNCTION_TYPE: ! 1651: case METHOD_TYPE: ! 1652: { ! 1653: tree firstarg = TYPE_ARG_TYPES (parmtype); ! 1654: /* Otherwise have to implement reentrant typevecs, ! 1655: unmark and remark types, etc. */ ! 1656: int old_nofold = nofold; ! 1657: nofold = 1; ! 1658: ! 1659: if (nrepeats) ! 1660: flush_repeats (typevec[maxtype-1]); ! 1661: ! 1662: /* @@ It may be possible to pass a function type in ! 1663: which is not preceded by a 'P'. */ ! 1664: if (TREE_CODE (parmtype) == FUNCTION_TYPE) ! 1665: { ! 1666: OB_PUTC ('F'); ! 1667: if (firstarg == NULL_TREE) ! 1668: OB_PUTC ('e'); ! 1669: else if (firstarg == void_list_node) ! 1670: OB_PUTC ('v'); ! 1671: else ! 1672: build_overload_name (firstarg, 0, 0); ! 1673: } ! 1674: else ! 1675: { ! 1676: int constp = TYPE_READONLY (TREE_TYPE (TREE_VALUE (firstarg))); ! 1677: int volatilep = TYPE_VOLATILE (TREE_TYPE (TREE_VALUE (firstarg))); ! 1678: OB_PUTC ('M'); ! 1679: firstarg = TREE_CHAIN (firstarg); ! 1680: ! 1681: build_overload_name (TYPE_METHOD_BASETYPE (parmtype), 0, 0); ! 1682: if (constp) ! 1683: OB_PUTC ('C'); ! 1684: if (volatilep) ! 1685: OB_PUTC ('V'); ! 1686: ! 1687: /* For cfront 2.0 compatability. */ ! 1688: OB_PUTC ('F'); ! 1689: ! 1690: if (firstarg == NULL_TREE) ! 1691: OB_PUTC ('e'); ! 1692: else if (firstarg == void_list_node) ! 1693: OB_PUTC ('v'); ! 1694: else ! 1695: build_overload_name (firstarg, 0, 0); ! 1696: } ! 1697: ! 1698: /* Separate args from return type. */ ! 1699: OB_PUTC ('_'); ! 1700: build_overload_name (TREE_TYPE (parmtype), 0, 0); ! 1701: nofold = old_nofold; ! 1702: break; ! 1703: } ! 1704: ! 1705: case INTEGER_TYPE: ! 1706: parmtype = TYPE_MAIN_VARIANT (parmtype); ! 1707: switch (TYPE_MODE (parmtype)) ! 1708: { ! 1709: case TImode: ! 1710: if (parmtype == long_integer_type_node ! 1711: || parmtype == long_unsigned_type_node) ! 1712: OB_PUTC ('l'); ! 1713: else ! 1714: OB_PUTC ('q'); ! 1715: break; ! 1716: case DImode: ! 1717: if (parmtype == long_integer_type_node ! 1718: || parmtype == long_unsigned_type_node) ! 1719: OB_PUTC ('l'); ! 1720: else if (parmtype == integer_type_node ! 1721: || parmtype == unsigned_type_node) ! 1722: OB_PUTC ('i'); ! 1723: else if (parmtype == short_integer_type_node ! 1724: || parmtype == short_unsigned_type_node) ! 1725: OB_PUTC ('s'); ! 1726: else ! 1727: OB_PUTC ('x'); ! 1728: break; ! 1729: case SImode: ! 1730: if (parmtype == long_integer_type_node ! 1731: || parmtype == long_unsigned_type_node) ! 1732: OB_PUTC ('l'); ! 1733: else if (parmtype == short_integer_type_node ! 1734: || parmtype == short_unsigned_type_node) ! 1735: OB_PUTC ('s'); ! 1736: else ! 1737: OB_PUTC ('i'); ! 1738: break; ! 1739: case HImode: ! 1740: if (parmtype == integer_type_node ! 1741: || parmtype == unsigned_type_node) ! 1742: OB_PUTC ('i'); ! 1743: else ! 1744: OB_PUTC ('s'); ! 1745: break; ! 1746: case QImode: ! 1747: OB_PUTC ('c'); ! 1748: break; ! 1749: default: ! 1750: abort (); ! 1751: } ! 1752: break; ! 1753: ! 1754: case REAL_TYPE: ! 1755: parmtype = TYPE_MAIN_VARIANT (parmtype); ! 1756: if (parmtype == long_double_type_node) ! 1757: OB_PUTC ('r'); ! 1758: else if (parmtype == double_type_node) ! 1759: OB_PUTC ('d'); ! 1760: else if (parmtype == float_type_node) ! 1761: OB_PUTC ('f'); ! 1762: else abort (); ! 1763: break; ! 1764: ! 1765: case VOID_TYPE: ! 1766: if (! just_one) ! 1767: { ! 1768: #if 0 ! 1769: extern tree void_list_node; ! 1770: ! 1771: /* See if anybody is wasting memory. */ ! 1772: assert (parmtypes == void_list_node); ! 1773: #endif ! 1774: /* This is the end of a parameter list. */ ! 1775: if (end) OB_FINISH (); ! 1776: return (char *)obstack_base (&scratch_obstack); ! 1777: } ! 1778: OB_PUTC ('v'); ! 1779: break; ! 1780: ! 1781: case ERROR_MARK: /* not right, but nothing is anyway */ ! 1782: break; ! 1783: ! 1784: /* have to do these */ ! 1785: case UNION_TYPE: ! 1786: case RECORD_TYPE: ! 1787: if (! just_one) ! 1788: /* Make this type signature look incompatible ! 1789: with AT&T. */ ! 1790: OB_PUTC ('G'); ! 1791: goto common; ! 1792: case ENUMERAL_TYPE: ! 1793: common: ! 1794: { ! 1795: tree name = TYPE_NAME (parmtype); ! 1796: int i = 1; ! 1797: ! 1798: if (TREE_CODE (name) == TYPE_DECL) ! 1799: { ! 1800: tree context = name; ! 1801: while (DECL_CONTEXT (context)) ! 1802: { ! 1803: i += 1; ! 1804: context = DECL_CONTEXT (context); ! 1805: if (TREE_CODE_CLASS (TREE_CODE (context)) == 't') ! 1806: context = TYPE_NAME (context); ! 1807: } ! 1808: name = DECL_NAME (name); ! 1809: } ! 1810: assert (TREE_CODE (name) == IDENTIFIER_NODE); ! 1811: if (i > 1) ! 1812: { ! 1813: OB_PUTC ('Q'); ! 1814: icat (i); ! 1815: build_overload_nested_name (TYPE_NAME (parmtype)); ! 1816: } ! 1817: else ! 1818: build_overload_identifier (name); ! 1819: break; ! 1820: } ! 1821: ! 1822: case UNKNOWN_TYPE: ! 1823: /* This will take some work. */ ! 1824: OB_PUTC ('?'); ! 1825: break; ! 1826: ! 1827: case TEMPLATE_TYPE_PARM: ! 1828: case TEMPLATE_CONST_PARM: ! 1829: case UNINSTANTIATED_P_TYPE: ! 1830: /* We don't ever want this output, but it's inconvenient not to ! 1831: be able to build the string. This should cause assembler ! 1832: errors we'll notice. */ ! 1833: { ! 1834: static int n; ! 1835: sprintf (digit_buffer, " *%d", n++); ! 1836: OB_PUTCP (digit_buffer); ! 1837: } ! 1838: break; ! 1839: ! 1840: default: ! 1841: abort (); ! 1842: } ! 1843: ! 1844: next: ! 1845: if (just_one) break; ! 1846: parmtypes = TREE_CHAIN (parmtypes); ! 1847: } ! 1848: if (! just_one) ! 1849: { ! 1850: if (nrepeats) ! 1851: flush_repeats (typevec[maxtype-1]); ! 1852: ! 1853: /* To get here, parms must end with `...'. */ ! 1854: OB_PUTC ('e'); ! 1855: } ! 1856: ! 1857: if (end) OB_FINISH (); ! 1858: return (char *)obstack_base (&scratch_obstack); ! 1859: } ! 1860: ! 1861: /* Generate an identifier that encodes the (ANSI) exception TYPE. */ ! 1862: ! 1863: /* This should be part of `ansi_opname', or at least be defined by the std. */ ! 1864: #define EXCEPTION_NAME_PREFIX "__ex" ! 1865: #define EXCEPTION_NAME_LENGTH 4 ! 1866: ! 1867: tree ! 1868: cplus_exception_name (type) ! 1869: tree type; ! 1870: { ! 1871: OB_INIT (); ! 1872: OB_PUTS (EXCEPTION_NAME_PREFIX); ! 1873: return get_identifier (build_overload_name (type, 0, 1)); ! 1874: } ! 1875: ! 1876: /* Change the name of a function definition so that it may be ! 1877: overloaded. NAME is the name of the function to overload, ! 1878: PARMS is the parameter list (which determines what name the ! 1879: final function obtains). ! 1880: ! 1881: FOR_METHOD is 1 if this overload is being performed ! 1882: for a method, rather than a function type. It is 2 if ! 1883: this overload is being performed for a constructor. */ ! 1884: tree ! 1885: build_decl_overload (name, parms, for_method) ! 1886: char *name; ! 1887: tree parms; ! 1888: int for_method; ! 1889: { ! 1890: OB_INIT (); ! 1891: if (for_method != 2) ! 1892: OB_PUTCP (name); ! 1893: /* Otherwise, we can divine that this is a constructor, ! 1894: and figure out its name without any extra encoding. */ ! 1895: ! 1896: OB_PUTC2 ('_', '_'); ! 1897: if (for_method) ! 1898: { ! 1899: #if 0 ! 1900: /* We can get away without doing this. */ ! 1901: OB_PUTC ('M'); ! 1902: #endif ! 1903: parms = temp_tree_cons (NULL_TREE, TREE_TYPE (TREE_VALUE (parms)), TREE_CHAIN (parms)); ! 1904: } ! 1905: else ! 1906: OB_PUTC ('F'); ! 1907: ! 1908: if (parms == NULL_TREE) ! 1909: OB_PUTC2 ('e', '\0'); ! 1910: else if (parms == void_list_node) ! 1911: OB_PUTC2 ('v', '\0'); ! 1912: else ! 1913: { ! 1914: ALLOCATE_TYPEVEC (parms); ! 1915: nofold = 0; ! 1916: if (for_method) ! 1917: { ! 1918: build_overload_name (TREE_VALUE (parms), 0, 0); ! 1919: ! 1920: typevec[maxtype++] = TREE_VALUE (parms); ! 1921: TREE_USED (TREE_VALUE (parms)) = 1; ! 1922: ! 1923: if (TREE_CHAIN (parms)) ! 1924: build_overload_name (TREE_CHAIN (parms), 0, 1); ! 1925: else ! 1926: OB_PUTC2 ('e', '\0'); ! 1927: } ! 1928: else ! 1929: build_overload_name (parms, 0, 1); ! 1930: DEALLOCATE_TYPEVEC (parms); ! 1931: } ! 1932: return get_identifier (obstack_base (&scratch_obstack)); ! 1933: } ! 1934: ! 1935: /* Build an overload name for the type expression TYPE. */ ! 1936: tree ! 1937: build_typename_overload (type) ! 1938: tree type; ! 1939: { ! 1940: OB_INIT (); ! 1941: OB_PUTID (ansi_opname[TYPE_EXPR]); ! 1942: ! 1943: #if 0 ! 1944: /* We can get away without doing this--it really gets ! 1945: overloaded later. */ ! 1946: OB_PUTC2 ('_', '_'); ! 1947: OB_PUTC ('M'); ! 1948: #endif ! 1949: nofold = 1; ! 1950: build_overload_name (type, 0, 1); ! 1951: return get_identifier (obstack_base (&scratch_obstack)); ! 1952: } ! 1953: ! 1954: #define T_DESC_FORMAT "TD$" ! 1955: #define I_DESC_FORMAT "ID$" ! 1956: #define M_DESC_FORMAT "MD$" ! 1957: ! 1958: /* Build an overload name for the type expression TYPE. */ ! 1959: tree ! 1960: build_t_desc_overload (type) ! 1961: tree type; ! 1962: { ! 1963: int i = sizeof (T_DESC_FORMAT) - 1; ! 1964: ! 1965: OB_INIT (); ! 1966: OB_PUTS (T_DESC_FORMAT); ! 1967: nofold = 1; ! 1968: ! 1969: #if 0 ! 1970: /* Use a different format if the type isn't defined yet. */ ! 1971: if (TYPE_SIZE (type) == NULL_TREE) ! 1972: { ! 1973: char *p; ! 1974: int changed; ! 1975: ! 1976: for (p = tname; *p; p++) ! 1977: if (isupper (*p)) ! 1978: { ! 1979: changed = 1; ! 1980: *p = tolower (*p); ! 1981: } ! 1982: /* If there's no change, we have an innappropriate T_DESC_FORMAT. */ ! 1983: assert (changed != 0); ! 1984: } ! 1985: #endif ! 1986: ! 1987: build_overload_name (type, 0, 1); ! 1988: return get_identifier (obstack_base (&scratch_obstack)); ! 1989: } ! 1990: ! 1991: /* Top-level interface to explicit overload requests. Allow NAME ! 1992: to be overloaded. Error if NAME is already declared for the current ! 1993: scope. Warning if function is redundanly overloaded. */ ! 1994: ! 1995: void ! 1996: declare_overloaded (name) ! 1997: tree name; ! 1998: { ! 1999: #ifdef NO_AUTO_OVERLOAD ! 2000: if (is_overloaded (name)) ! 2001: warning ("function `%s' already declared overloaded", ! 2002: IDENTIFIER_POINTER (name)); ! 2003: else if (IDENTIFIER_GLOBAL_VALUE (name)) ! 2004: error ("overloading function `%s' that is already defined", ! 2005: IDENTIFIER_POINTER (name)); ! 2006: else ! 2007: { ! 2008: TREE_OVERLOADED (name) = 1; ! 2009: IDENTIFIER_GLOBAL_VALUE (name) = build_tree_list (name, NULL_TREE); ! 2010: TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (name)) = unknown_type_node; ! 2011: } ! 2012: #else ! 2013: if (current_lang_name == lang_name_cplusplus) ! 2014: { ! 2015: if (0) ! 2016: warning ("functions are implicitly overloaded in C++"); ! 2017: } ! 2018: else if (current_lang_name == lang_name_c) ! 2019: error ("overloading function `%s' cannot be done in C language context"); ! 2020: else ! 2021: abort (); ! 2022: #endif ! 2023: } ! 2024: ! 2025: #ifdef NO_AUTO_OVERLOAD ! 2026: /* Check to see if NAME is overloaded. For first approximation, ! 2027: check to see if its TREE_OVERLOADED is set. This is used on ! 2028: IDENTIFIER nodes. */ ! 2029: int ! 2030: is_overloaded (name) ! 2031: tree name; ! 2032: { ! 2033: /* @@ */ ! 2034: return (TREE_OVERLOADED (name) ! 2035: && (! IDENTIFIER_CLASS_VALUE (name) || current_class_type == 0) ! 2036: && ! IDENTIFIER_LOCAL_VALUE (name)); ! 2037: } ! 2038: #endif ! 2039: ! 2040: /* Given a tree_code CODE, and some arguments (at least one), ! 2041: attempt to use an overloaded operator on the arguments. ! 2042: ! 2043: For unary operators, only the first argument need be checked. ! 2044: For binary operators, both arguments may need to be checked. ! 2045: ! 2046: Member functions can convert class references to class pointers, ! 2047: for one-level deep indirection. More than that is not supported. ! 2048: Operators [](), ()(), and ->() must be member functions. ! 2049: ! 2050: We call function call building calls with nonzero complain if ! 2051: they are our only hope. This is true when we see a vanilla operator ! 2052: applied to something of aggregate type. If this fails, we are free to ! 2053: return `error_mark_node', because we will have reported the error. ! 2054: ! 2055: Operators NEW and DELETE overload in funny ways: operator new takes ! 2056: a single `size' parameter, and operator delete takes a pointer to the ! 2057: storage being deleted. When overloading these operators, success is ! 2058: assumed. If there is a failure, report an error message and return ! 2059: `error_mark_node'. */ ! 2060: ! 2061: /* NOSTRICT */ ! 2062: tree ! 2063: build_opfncall (code, flags, xarg1, xarg2, arg3) ! 2064: enum tree_code code; ! 2065: tree xarg1, xarg2; ! 2066: tree arg3; ! 2067: { ! 2068: tree rval = 0; ! 2069: tree arg1, arg2; ! 2070: tree type1, type2, fnname; ! 2071: tree fields1 = 0, parms = 0; ! 2072: tree global_fn; ! 2073: int try_second; ! 2074: int binary_is_unary; ! 2075: ! 2076: if (xarg1 == error_mark_node) ! 2077: return error_mark_node; ! 2078: ! 2079: if (code == COND_EXPR) ! 2080: { ! 2081: if (TREE_CODE (xarg2) == ERROR_MARK ! 2082: || TREE_CODE (arg3) == ERROR_MARK) ! 2083: return error_mark_node; ! 2084: } ! 2085: if (code == COMPONENT_REF) ! 2086: if (TREE_CODE (TREE_TYPE (xarg1)) == POINTER_TYPE) ! 2087: return rval; ! 2088: ! 2089: /* First, see if we can work with the first argument */ ! 2090: type1 = TREE_TYPE (xarg1); ! 2091: ! 2092: /* Some tree codes have length > 1, but we really only want to ! 2093: overload them if their first argument has a user defined type. */ ! 2094: switch (code) ! 2095: { ! 2096: case PREINCREMENT_EXPR: ! 2097: code = POSTINCREMENT_EXPR; ! 2098: binary_is_unary = 1; ! 2099: try_second = 0; ! 2100: break; ! 2101: ! 2102: case POSTDECREMENT_EXPR: ! 2103: code = PREDECREMENT_EXPR; ! 2104: binary_is_unary = 1; ! 2105: try_second = 0; ! 2106: break; ! 2107: ! 2108: case PREDECREMENT_EXPR: ! 2109: case POSTINCREMENT_EXPR: ! 2110: case COMPONENT_REF: ! 2111: binary_is_unary = 1; ! 2112: try_second = 0; ! 2113: break; ! 2114: ! 2115: /* ARRAY_REFs and CALL_EXPRs must overload successfully. ! 2116: If they do not, return error_mark_node instead of NULL_TREE. */ ! 2117: case ARRAY_REF: ! 2118: if (xarg2 == error_mark_node) ! 2119: return error_mark_node; ! 2120: case CALL_EXPR: ! 2121: rval = error_mark_node; ! 2122: binary_is_unary = 0; ! 2123: try_second = 0; ! 2124: break; ! 2125: ! 2126: case NEW_EXPR: ! 2127: { ! 2128: /* For operators `new' (`delete'), only check visibility ! 2129: if we are in a constructor (destructor), and we are ! 2130: allocating for that constructor's (destructor's) type. */ ! 2131: ! 2132: fnname = ansi_opname[NEW_EXPR]; ! 2133: if (flags & LOOKUP_GLOBAL) ! 2134: return build_overload_call (fnname, tree_cons (NULL_TREE, xarg2, arg3), ! 2135: flags & LOOKUP_COMPLAIN, 0); ! 2136: ! 2137: if (current_function_decl == NULL_TREE ! 2138: || !DECL_CONSTRUCTOR_P (current_function_decl) ! 2139: || current_class_type != TYPE_MAIN_VARIANT (type1)) ! 2140: flags = LOOKUP_COMPLAIN; ! 2141: rval = build_method_call (build1 (NOP_EXPR, xarg1, error_mark_node), ! 2142: fnname, tree_cons (NULL_TREE, xarg2, arg3), ! 2143: NULL_TREE, flags); ! 2144: if (rval == error_mark_node) ! 2145: /* User might declare fancy operator new, but invoke it ! 2146: like standard one. */ ! 2147: return rval; ! 2148: ! 2149: TREE_TYPE (rval) = xarg1; ! 2150: TREE_CALLS_NEW (rval) = 1; ! 2151: return rval; ! 2152: } ! 2153: break; ! 2154: ! 2155: case DELETE_EXPR: ! 2156: { ! 2157: /* See comment above. */ ! 2158: ! 2159: fnname = ansi_opname[DELETE_EXPR]; ! 2160: if (flags & LOOKUP_GLOBAL) ! 2161: return build_overload_call (fnname, build_tree_list (NULL_TREE, xarg1), ! 2162: flags & LOOKUP_COMPLAIN, 0); ! 2163: ! 2164: if (current_function_decl == NULL_TREE ! 2165: || !DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (current_function_decl)) ! 2166: || current_class_type != TYPE_MAIN_VARIANT (type1)) ! 2167: flags = LOOKUP_COMPLAIN; ! 2168: rval = build_method_call (build1 (NOP_EXPR, TREE_TYPE (xarg1), error_mark_node), ! 2169: fnname, build_tree_list (NULL_TREE, xarg1), ! 2170: NULL_TREE, flags); ! 2171: /* This happens when the user mis-declares `operator delete'. ! 2172: Should now be impossible. */ ! 2173: assert (rval != error_mark_node); ! 2174: TREE_TYPE (rval) = void_type_node; ! 2175: return rval; ! 2176: } ! 2177: break; ! 2178: ! 2179: default: ! 2180: binary_is_unary = 0; ! 2181: try_second = tree_code_length [(int) code] == 2; ! 2182: if (try_second && xarg2 == error_mark_node) ! 2183: return error_mark_node; ! 2184: break; ! 2185: } ! 2186: ! 2187: if (try_second && xarg2 == error_mark_node) ! 2188: return error_mark_node; ! 2189: ! 2190: /* What ever it was, we do not know how to deal with it. */ ! 2191: if (type1 == NULL_TREE) ! 2192: return rval; ! 2193: ! 2194: if (TREE_CODE (type1) == OFFSET_TYPE) ! 2195: type1 = TREE_TYPE (type1); ! 2196: ! 2197: if (TREE_CODE (type1) == REFERENCE_TYPE) ! 2198: { ! 2199: arg1 = convert_from_reference (xarg1); ! 2200: type1 = TREE_TYPE (arg1); ! 2201: } ! 2202: else ! 2203: { ! 2204: arg1 = xarg1; ! 2205: } ! 2206: ! 2207: if (!IS_AGGR_TYPE (type1)) ! 2208: { ! 2209: /* Try to fail. First, fail if unary */ ! 2210: if (! try_second) ! 2211: return rval; ! 2212: /* Second, see if second argument is non-aggregate. */ ! 2213: type2 = TREE_TYPE (xarg2); ! 2214: if (TREE_CODE (type2) == OFFSET_TYPE) ! 2215: type2 = TREE_TYPE (type2); ! 2216: if (TREE_CODE (type2) == REFERENCE_TYPE) ! 2217: { ! 2218: arg2 = convert_from_reference (xarg2); ! 2219: type2 = TREE_TYPE (arg2); ! 2220: } ! 2221: else ! 2222: { ! 2223: arg2 = xarg2; ! 2224: } ! 2225: ! 2226: if (!IS_AGGR_TYPE (type2)) ! 2227: return rval; ! 2228: try_second = 0; ! 2229: } ! 2230: ! 2231: if (try_second) ! 2232: { ! 2233: /* First arg may succeed; see whether second should. */ ! 2234: type2 = TREE_TYPE (xarg2); ! 2235: if (TREE_CODE (type2) == OFFSET_TYPE) ! 2236: type2 = TREE_TYPE (type2); ! 2237: if (TREE_CODE (type2) == REFERENCE_TYPE) ! 2238: { ! 2239: arg2 = convert_from_reference (xarg2); ! 2240: type2 = TREE_TYPE (arg2); ! 2241: } ! 2242: else ! 2243: { ! 2244: arg2 = xarg2; ! 2245: } ! 2246: ! 2247: if (! IS_AGGR_TYPE (type2)) ! 2248: try_second = 0; ! 2249: } ! 2250: ! 2251: if (type1 == unknown_type_node ! 2252: || (try_second && TREE_TYPE (xarg2) == unknown_type_node)) ! 2253: { ! 2254: /* This will not be implemented in the forseeable future. */ ! 2255: return rval; ! 2256: } ! 2257: ! 2258: if (code == MODIFY_EXPR) ! 2259: fnname = ansi_assopname[(int)arg3]; ! 2260: else ! 2261: fnname = ansi_opname[code]; ! 2262: ! 2263: global_fn = IDENTIFIER_GLOBAL_VALUE (fnname); ! 2264: ! 2265: /* This is the last point where we will accept failure. This ! 2266: may be too eager if we wish an overloaded operator not to match, ! 2267: but would rather a normal operator be called on a type-converted ! 2268: argument. */ ! 2269: ! 2270: if (IS_AGGR_TYPE (type1)) ! 2271: fields1 = lookup_fnfields (TYPE_BINFO (type1), fnname, 0); ! 2272: ! 2273: if (fields1 == NULL_TREE && global_fn == NULL_TREE) ! 2274: return rval; ! 2275: ! 2276: /* If RVAL winds up being `error_mark_node', we will return ! 2277: that... There is no way that normal semantics of these ! 2278: operators will succeed. */ ! 2279: ! 2280: /* This argument may be an uncommited OFFSET_REF. This is ! 2281: the case for example when dealing with static class members ! 2282: which are referenced from their class name rather than ! 2283: from a class instance. */ ! 2284: if (TREE_CODE (xarg1) == OFFSET_REF ! 2285: && TREE_CODE (TREE_OPERAND (xarg1, 1)) == VAR_DECL) ! 2286: xarg1 = TREE_OPERAND (xarg1, 1); ! 2287: if (try_second && xarg2 && TREE_CODE (xarg2) == OFFSET_REF ! 2288: && TREE_CODE (TREE_OPERAND (xarg2, 1)) == VAR_DECL) ! 2289: xarg2 = TREE_OPERAND (xarg2, 1); ! 2290: ! 2291: if (global_fn) ! 2292: flags |= LOOKUP_GLOBAL; ! 2293: ! 2294: if (code == CALL_EXPR) ! 2295: { ! 2296: /* This can only be a member function. */ ! 2297: return build_method_call (xarg1, fnname, xarg2, ! 2298: NULL_TREE, LOOKUP_NORMAL); ! 2299: } ! 2300: else if (tree_code_length[(int) code] == 1 || binary_is_unary) ! 2301: { ! 2302: parms = NULL_TREE; ! 2303: rval = build_method_call (xarg1, fnname, NULL_TREE, NULL_TREE, flags); ! 2304: } ! 2305: else if (code == COND_EXPR) ! 2306: { ! 2307: parms = tree_cons (0, xarg2, build_tree_list (0, arg3)); ! 2308: rval = build_method_call (xarg1, fnname, parms, NULL_TREE, flags); ! 2309: } ! 2310: else if (code == METHOD_CALL_EXPR) ! 2311: { ! 2312: /* must be a member function. */ ! 2313: parms = tree_cons (NULL_TREE, xarg2, arg3); ! 2314: return build_method_call (xarg1, fnname, parms, NULL_TREE, LOOKUP_NORMAL); ! 2315: } ! 2316: else if (fields1) ! 2317: { ! 2318: parms = build_tree_list (NULL_TREE, xarg2); ! 2319: rval = build_method_call (xarg1, fnname, parms, NULL_TREE, flags); ! 2320: } ! 2321: else ! 2322: { ! 2323: parms = tree_cons (NULL_TREE, xarg1, ! 2324: build_tree_list (NULL_TREE, xarg2)); ! 2325: rval = build_overload_call (fnname, parms, flags & LOOKUP_COMPLAIN, 0); ! 2326: } ! 2327: ! 2328: /* If we did not win, do not lose yet, since type conversion may work. */ ! 2329: if (TREE_CODE (rval) == ERROR_MARK) ! 2330: { ! 2331: if (flags & LOOKUP_COMPLAIN) ! 2332: return rval; ! 2333: return 0; ! 2334: } ! 2335: ! 2336: return rval; ! 2337: } ! 2338: ! 2339: /* This function takes an identifier, ID, and attempts to figure out what ! 2340: it means. There are a number of possible scenarios, presented in increasing ! 2341: order of hair: ! 2342: ! 2343: 1) not in a class's scope ! 2344: 2) in class's scope, member name of the class's method ! 2345: 3) in class's scope, but not a member name of the class ! 2346: 4) in class's scope, member name of a class's variable ! 2347: ! 2348: NAME is $1 from the bison rule. It is an IDENTIFIER_NODE. ! 2349: VALUE is $$ from the bison rule. It is the value returned by lookup_name ($1) ! 2350: yychar is the pending input character (suitably encoded :-). ! 2351: ! 2352: As a last ditch, try to look up the name as a label and return that ! 2353: address. ! 2354: ! 2355: Values which are declared as being of REFERENCE_TYPE are ! 2356: automatically dereferenced here (as a hack to make the ! 2357: compiler faster). */ ! 2358: ! 2359: tree ! 2360: hack_identifier (value, name, yychar) ! 2361: tree value, name; ! 2362: { ! 2363: tree type; ! 2364: ! 2365: if (TREE_CODE (value) == ERROR_MARK) ! 2366: { ! 2367: if (current_class_name) ! 2368: { ! 2369: tree fields = lookup_fnfields (TYPE_BINFO (current_class_type), name, 0); ! 2370: if (fields) ! 2371: { ! 2372: tree fndecl; ! 2373: ! 2374: fndecl = TREE_VALUE (fields); ! 2375: assert (TREE_CODE (fndecl) == FUNCTION_DECL); ! 2376: if (DECL_CHAIN (fndecl) == NULL_TREE) ! 2377: { ! 2378: warning ("methods cannot be converted to function pointers"); ! 2379: return fndecl; ! 2380: } ! 2381: else ! 2382: { ! 2383: error ("ambiguous request for method pointer `%s'", ! 2384: IDENTIFIER_POINTER (name)); ! 2385: return error_mark_node; ! 2386: } ! 2387: } ! 2388: } ! 2389: if (flag_labels_ok && IDENTIFIER_LABEL_VALUE (name)) ! 2390: { ! 2391: return IDENTIFIER_LABEL_VALUE (name); ! 2392: } ! 2393: return error_mark_node; ! 2394: } ! 2395: ! 2396: type = TREE_TYPE (value); ! 2397: if (TREE_CODE (value) == FIELD_DECL) ! 2398: { ! 2399: if (current_class_decl == NULL_TREE) ! 2400: { ! 2401: error ("request for member `%s' in static member function", ! 2402: IDENTIFIER_POINTER (DECL_NAME (value))); ! 2403: return error_mark_node; ! 2404: } ! 2405: TREE_USED (current_class_decl) = 1; ! 2406: if (yychar == '(') ! 2407: if (! ((TYPE_LANG_SPECIFIC (type) ! 2408: && TYPE_OVERLOADS_CALL_EXPR (type)) ! 2409: || (TREE_CODE (type) == REFERENCE_TYPE ! 2410: && TYPE_LANG_SPECIFIC (TREE_TYPE (type)) ! 2411: && TYPE_OVERLOADS_CALL_EXPR (TREE_TYPE (type)))) ! 2412: && TREE_CODE (type) != FUNCTION_TYPE ! 2413: && TREE_CODE (type) != METHOD_TYPE ! 2414: && (TREE_CODE (type) != POINTER_TYPE ! 2415: || (TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE ! 2416: && TREE_CODE (TREE_TYPE (type)) != METHOD_TYPE))) ! 2417: { ! 2418: error ("component `%s' is not a method", ! 2419: IDENTIFIER_POINTER (name)); ! 2420: return error_mark_node; ! 2421: } ! 2422: /* Mark so that if we are in a constructor, and then find that ! 2423: this field was initialized by a base initializer, ! 2424: we can emit an error message. */ ! 2425: TREE_USED (value) = 1; ! 2426: return build_component_ref (C_C_D, name, 0, 1); ! 2427: } ! 2428: ! 2429: if (TREE_CODE (value) == TREE_LIST) ! 2430: { ! 2431: tree t = value; ! 2432: while (t && TREE_CODE (t) == TREE_LIST) ! 2433: { ! 2434: assemble_external (TREE_VALUE (t)); ! 2435: TREE_USED (t) = 1; ! 2436: t = TREE_CHAIN (t); ! 2437: } ! 2438: } ! 2439: else ! 2440: { ! 2441: assemble_external (value); ! 2442: TREE_USED (value) = 1; ! 2443: } ! 2444: ! 2445: if (TREE_CODE_CLASS (TREE_CODE (value)) == 'd' && TREE_NONLOCAL (value)) ! 2446: { ! 2447: if (DECL_CLASS_CONTEXT (value) != current_class_type) ! 2448: { ! 2449: tree path; ! 2450: enum visibility_type visibility; ! 2451: ! 2452: get_base_distance (DECL_CLASS_CONTEXT (value), ! 2453: current_class_type, 0, &path); ! 2454: visibility = compute_visibility (path, value); ! 2455: if (visibility != visibility_public) ! 2456: { ! 2457: if (TREE_CODE (value) == VAR_DECL) ! 2458: error ("static member `%s' is from private base class", ! 2459: IDENTIFIER_POINTER (name)); ! 2460: else ! 2461: error ("enum `%s' is from private base class", ! 2462: IDENTIFIER_POINTER (name)); ! 2463: return error_mark_node; ! 2464: } ! 2465: } ! 2466: if (TREE_CODE (value) == VAR_DECL && ! TREE_USED (value)) ! 2467: { ! 2468: if (TREE_EXTERNAL (value)) ! 2469: assemble_external (value); ! 2470: TREE_USED (value) = 1; ! 2471: } ! 2472: return value; ! 2473: } ! 2474: if (TREE_CODE (value) == TREE_LIST && TREE_NONLOCAL_FLAG (value)) ! 2475: { ! 2476: if (type == 0) ! 2477: { ! 2478: error ("request for member `%s' is ambiguous in multiple inheritance lattice", ! 2479: IDENTIFIER_POINTER (name)); ! 2480: return error_mark_node; ! 2481: } ! 2482: ! 2483: return value; ! 2484: } ! 2485: ! 2486: if (TREE_CODE (type) == REFERENCE_TYPE) ! 2487: { ! 2488: assert (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == PARM_DECL); ! 2489: if (DECL_REFERENCE_SLOT (value)) ! 2490: return DECL_REFERENCE_SLOT (value); ! 2491: } ! 2492: return value; ! 2493: } ! 2494: ! 2495: /* NONWRAPPER is nonzero if this call is not to be wrapped. ! 2496: TYPE is the type that the wrapper belongs to (in case ! 2497: it should be non-virtual). ! 2498: DECL is the function will will be (not be) wrapped. */ ! 2499: tree ! 2500: hack_wrapper (nonwrapper, type, decl) ! 2501: int nonwrapper; ! 2502: tree type, decl; ! 2503: { ! 2504: if (type == NULL_TREE || is_aggr_typedef (type, 1)) ! 2505: { ! 2506: if (type) ! 2507: type = TREE_TYPE (type); ! 2508: ! 2509: switch (nonwrapper) ! 2510: { ! 2511: case 0: ! 2512: return build_nt (WRAPPER_EXPR, type, decl); ! 2513: case 1: ! 2514: return build_nt (ANTI_WRAPPER_EXPR, type, decl); ! 2515: case 2: ! 2516: return build_nt (WRAPPER_EXPR, type, ! 2517: build_nt (COND_EXPR, decl, NULL_TREE, NULL_TREE)); ! 2518: default: ! 2519: assert (0 <= nonwrapper && nonwrapper <= 2); ! 2520: } ! 2521: } ! 2522: return error_mark_node; ! 2523: } ! 2524: ! 2525: /* Given an object OF, and a type conversion operator COMPONENT ! 2526: build a call to the conversion operator, if a call is requested, ! 2527: or return the address (as a pointer to member function) if one is not. ! 2528: ! 2529: OF can be a TYPE_DECL or any kind of datum that would normally ! 2530: be passed to `build_component_ref'. It may also be NULL_TREE, ! 2531: in which case `current_class_type' and `current_class_decl' ! 2532: provide default values. ! 2533: ! 2534: BASETYPE_PATH, if non-null, is the path of basetypes ! 2535: to go through before we get the the instance of interest. ! 2536: ! 2537: PROTECT says whether we apply C++ scoping rules or not. */ ! 2538: tree ! 2539: build_component_type_expr (of, component, basetype_path, protect) ! 2540: tree of, component, basetype_path; ! 2541: int protect; ! 2542: { ! 2543: tree cname = NULL_TREE; ! 2544: tree tmp, last; ! 2545: tree name; ! 2546: int flags = protect ? LOOKUP_NORMAL : LOOKUP_COMPLAIN; ! 2547: ! 2548: assert (IS_AGGR_TYPE (TREE_TYPE (of))); ! 2549: assert (TREE_CODE (component) == TYPE_EXPR); ! 2550: ! 2551: tmp = TREE_OPERAND (component, 0); ! 2552: last = NULL_TREE; ! 2553: ! 2554: while (tmp) ! 2555: { ! 2556: switch (TREE_CODE (tmp)) ! 2557: { ! 2558: case CALL_EXPR: ! 2559: if (last) ! 2560: TREE_OPERAND (last, 0) = TREE_OPERAND (tmp, 0); ! 2561: else ! 2562: TREE_OPERAND (component, 0) = TREE_OPERAND (tmp, 0); ! 2563: if (TREE_OPERAND (tmp, 0) ! 2564: && TREE_OPERAND (tmp, 0) != void_list_node) ! 2565: { ! 2566: error ("operator <typename> requires empty parameter list"); ! 2567: TREE_OPERAND (tmp, 0) = NULL_TREE; ! 2568: } ! 2569: last = groktypename (build_tree_list (TREE_TYPE (component), ! 2570: TREE_OPERAND (component, 0))); ! 2571: name = build_typename_overload (last); ! 2572: TREE_TYPE (name) = last; ! 2573: ! 2574: if (of && TREE_CODE (of) != TYPE_DECL) ! 2575: return build_method_call (of, name, NULL_TREE, NULL_TREE, flags); ! 2576: else if (of) ! 2577: { ! 2578: tree this_this; ! 2579: ! 2580: if (current_class_decl == NULL_TREE) ! 2581: { ! 2582: error ("object required for `operator <typename>' call"); ! 2583: return error_mark_node; ! 2584: } ! 2585: ! 2586: this_this = convert_pointer_to (TREE_TYPE (of), current_class_decl); ! 2587: return build_method_call (this_this, name, NULL_TREE, ! 2588: NULL_TREE, flags | LOOKUP_NONVIRTUAL); ! 2589: } ! 2590: else if (current_class_decl) ! 2591: return build_method_call (tmp, name, NULL_TREE, NULL_TREE, flags); ! 2592: ! 2593: error ("object required for `operator <typename>' call"); ! 2594: return error_mark_node; ! 2595: ! 2596: case INDIRECT_REF: ! 2597: case ADDR_EXPR: ! 2598: case ARRAY_REF: ! 2599: break; ! 2600: ! 2601: case SCOPE_REF: ! 2602: assert (cname == 0); ! 2603: cname = TREE_OPERAND (tmp, 0); ! 2604: tmp = TREE_OPERAND (tmp, 1); ! 2605: break; ! 2606: ! 2607: default: ! 2608: abort (); ! 2609: } ! 2610: last = tmp; ! 2611: tmp = TREE_OPERAND (tmp, 0); ! 2612: } ! 2613: ! 2614: last = groktypename (build_tree_list (TREE_TYPE (component), TREE_OPERAND (component, 0))); ! 2615: name = build_typename_overload (last); ! 2616: TREE_TYPE (name) = last; ! 2617: if (of && TREE_CODE (of) == TYPE_DECL) ! 2618: { ! 2619: if (cname == NULL_TREE) ! 2620: { ! 2621: cname = DECL_NAME (of); ! 2622: of = NULL_TREE; ! 2623: } ! 2624: else assert (cname == DECL_NAME (of)); ! 2625: } ! 2626: ! 2627: if (of) ! 2628: { ! 2629: tree this_this; ! 2630: ! 2631: if (current_class_decl == NULL_TREE) ! 2632: { ! 2633: error ("object required for `operator <typename>' call"); ! 2634: return error_mark_node; ! 2635: } ! 2636: ! 2637: this_this = convert_pointer_to (TREE_TYPE (of), current_class_decl); ! 2638: return build_component_ref (this_this, name, 0, protect); ! 2639: } ! 2640: else if (cname) ! 2641: return build_offset_ref (cname, name); ! 2642: else if (current_class_name) ! 2643: return build_offset_ref (current_class_name, name); ! 2644: ! 2645: error ("object required for `operator <typename>' member reference"); ! 2646: return error_mark_node; ! 2647: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.