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