|
|
1.1 ! root 1: /* Call-backs for C++ error reporting. ! 2: This code is non-reentrant. ! 3: Copyright (C) 1993 Free Software Foundation, Inc. ! 4: ! 5: This file is part of GNU CC. ! 6: ! 7: GNU CC is free software; you can redistribute it and/or modify ! 8: it under the terms of the GNU General Public License as published by ! 9: the Free Software Foundation; either version 2, or (at your option) ! 10: any later version. ! 11: ! 12: GNU CC is distributed in the hope that it will be useful, ! 13: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 15: GNU General Public License for more details. ! 16: ! 17: You should have received a copy of the GNU General Public License ! 18: along with GNU CC; see the file COPYING. If not, write to ! 19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 20: ! 21: #include "config.h" ! 22: #include "tree.h" ! 23: #include "cp-tree.h" ! 24: #include "obstack.h" ! 25: #include <ctype.h> ! 26: ! 27: typedef char* cp_printer (); ! 28: ! 29: #define A args_as_string ! 30: #define C code_as_string ! 31: #define D decl_as_string ! 32: #define E expr_as_string ! 33: #define L language_as_string ! 34: #define O op_as_string ! 35: #define P parm_as_string ! 36: #define T type_as_string ! 37: ! 38: #define _ (cp_printer *) 0 ! 39: cp_printer * cp_printers[256] = ! 40: { ! 41: /*0 1 2 3 4 5 6 7 8 9 A B C D E F */ ! 42: _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x00 */ ! 43: _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x10 */ ! 44: _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x20 */ ! 45: _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x30 */ ! 46: _, A, _, C, D, E, _, _, _, _, _, _, L, _, _, O, /* 0x40 */ ! 47: P, _, _, _, T, _, _, _, _, _, _, _, _, _, _, _, /* 0x50 */ ! 48: _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x60 */ ! 49: _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* 0x70 */ ! 50: }; ! 51: #undef C ! 52: #undef D ! 53: #undef E ! 54: #undef L ! 55: #undef O ! 56: #undef P ! 57: #undef T ! 58: #undef _ ! 59: ! 60: #define obstack_chunk_alloc xmalloc ! 61: #define obstack_chunk_free free ! 62: ! 63: /* Obstack where we build text strings for overloading, etc. */ ! 64: static struct obstack scratch_obstack; ! 65: static char *scratch_firstobj; ! 66: ! 67: # define OB_INIT() (scratch_firstobj ? (obstack_free (&scratch_obstack, scratch_firstobj), 0) : 0) ! 68: # define OB_PUTC(C) (obstack_1grow (&scratch_obstack, (C))) ! 69: # define OB_PUTC2(C1,C2) \ ! 70: (obstack_1grow (&scratch_obstack, (C1)), obstack_1grow (&scratch_obstack, (C2))) ! 71: # define OB_PUTS(S) (obstack_grow (&scratch_obstack, (S), sizeof (S) - 1)) ! 72: # define OB_PUTID(ID) \ ! 73: (obstack_grow (&scratch_obstack, IDENTIFIER_POINTER (ID), \ ! 74: IDENTIFIER_LENGTH (ID))) ! 75: # define OB_PUTCP(S) (obstack_grow (&scratch_obstack, (S), strlen (S))) ! 76: # define OB_FINISH() (obstack_1grow (&scratch_obstack, '\0')) ! 77: # define OB_PUTI(CST) do { sprintf (digit_buffer, "%d", (CST)); \ ! 78: OB_PUTCP (digit_buffer); } while (0) ! 79: # define OB_UNPUT(N) obstack_blank (&scratch_obstack, - (N)); ! 80: ! 81: # define NEXT_CODE(t) (TREE_CODE (TREE_TYPE (t))) ! 82: ! 83: static void dump_type (), dump_decl (), dump_function_decl (); ! 84: static void dump_expr (), dump_unary_op (), dump_binary_op (); ! 85: static void dump_aggr_type (), dump_type_prefix (), dump_type_suffix (); ! 86: static void dump_function_name (); ! 87: ! 88: void ! 89: init_error () ! 90: { ! 91: gcc_obstack_init (&scratch_obstack); ! 92: scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0); ! 93: } ! 94: ! 95: enum pad { none, before, after }; ! 96: ! 97: static void ! 98: dump_readonly_or_volatile (t, p) ! 99: tree t; ! 100: enum pad p; ! 101: { ! 102: if (TYPE_READONLY (t) || TYPE_VOLATILE (t)) ! 103: { ! 104: if (p == before) OB_PUTC (' '); ! 105: if (TYPE_READONLY (t)) ! 106: OB_PUTS ("const"); ! 107: if (TYPE_READONLY (t) && TYPE_VOLATILE (t)) ! 108: OB_PUTC (' '); ! 109: if (TYPE_VOLATILE (t)) ! 110: OB_PUTS ("volatile"); ! 111: if (p == after) OB_PUTC (' '); ! 112: } ! 113: } ! 114: ! 115: /* This must be large enough to hold any printed integer or floating-point ! 116: value. */ ! 117: static char digit_buffer[128]; ! 118: ! 119: /* Dump into the obstack a human-readable equivalent of TYPE. */ ! 120: static void ! 121: dump_type (t, v) ! 122: tree t; ! 123: int v; /* verbose? */ ! 124: { ! 125: if (t == NULL_TREE) ! 126: return; ! 127: ! 128: if (TYPE_PTRMEMFUNC_P (t)) ! 129: goto offset_type; ! 130: ! 131: switch (TREE_CODE (t)) ! 132: { ! 133: case ERROR_MARK: ! 134: OB_PUTS ("{error}"); ! 135: break; ! 136: ! 137: case UNKNOWN_TYPE: ! 138: OB_PUTS ("{unknown type}"); ! 139: break; ! 140: ! 141: case TREE_LIST: ! 142: /* i.e. function taking no arguments */ ! 143: if (t != void_list_node) ! 144: { ! 145: dump_type (TREE_VALUE (t), v); ! 146: /* Can this happen other than for default arguments? */ ! 147: if (TREE_PURPOSE (t) && v) ! 148: { ! 149: OB_PUTS (" = "); ! 150: dump_expr (TREE_PURPOSE (t)); ! 151: } ! 152: if (TREE_CHAIN (t)) ! 153: { ! 154: if (TREE_CHAIN (t) != void_list_node) ! 155: { ! 156: OB_PUTC2 (',', ' '); ! 157: dump_type (TREE_CHAIN (t), v); ! 158: } ! 159: } ! 160: else OB_PUTS (" ..."); ! 161: } ! 162: break; ! 163: ! 164: case IDENTIFIER_NODE: ! 165: OB_PUTID (t); ! 166: break; ! 167: ! 168: case TREE_VEC: ! 169: dump_type (BINFO_TYPE (t), v); ! 170: break; ! 171: ! 172: case RECORD_TYPE: ! 173: case UNION_TYPE: ! 174: case ENUMERAL_TYPE: ! 175: if (TYPE_LANG_SPECIFIC (t) ! 176: && (IS_SIGNATURE_POINTER (t) || IS_SIGNATURE_REFERENCE (t))) ! 177: { ! 178: if (TYPE_READONLY (t) | TYPE_VOLATILE (t)) ! 179: dump_readonly_or_volatile (t); ! 180: dump_type (SIGNATURE_TYPE (t), v); ! 181: if (IS_SIGNATURE_POINTER (t)) ! 182: OB_PUTC ('*'); ! 183: else ! 184: OB_PUTC ('&'); ! 185: } ! 186: else ! 187: dump_aggr_type (t, v); ! 188: break; ! 189: ! 190: case TYPE_DECL: ! 191: dump_decl (t, v); ! 192: break; ! 193: ! 194: case INTEGER_TYPE: ! 195: if (!TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)) && TREE_UNSIGNED (t)) ! 196: OB_PUTS ("unsigned "); ! 197: else if (TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)) && !TREE_UNSIGNED (t)) ! 198: OB_PUTS ("signed "); ! 199: ! 200: /* fall through. */ ! 201: case REAL_TYPE: ! 202: case VOID_TYPE: ! 203: case BOOLEAN_TYPE: ! 204: dump_readonly_or_volatile (t, after); ! 205: OB_PUTID (TYPE_IDENTIFIER (t)); ! 206: break; ! 207: ! 208: case TEMPLATE_TYPE_PARM: ! 209: OB_PUTID (TYPE_IDENTIFIER (t)); ! 210: break; ! 211: ! 212: case UNINSTANTIATED_P_TYPE: ! 213: OB_PUTID (DECL_NAME (UPT_TEMPLATE (t))); ! 214: OB_PUTS ("<...>"); ! 215: break; ! 216: ! 217: /* This is not always necessary for pointers and such, but doing this ! 218: reduces code size. */ ! 219: case ARRAY_TYPE: ! 220: case POINTER_TYPE: ! 221: case REFERENCE_TYPE: ! 222: case OFFSET_TYPE: ! 223: offset_type: ! 224: case FUNCTION_TYPE: ! 225: case METHOD_TYPE: ! 226: dump_type_prefix (t, v); ! 227: dump_type_suffix (t, v); ! 228: break; ! 229: ! 230: default: ! 231: sorry ("`%s' not supported by dump_type", ! 232: tree_code_name[(int) TREE_CODE (t)]); ! 233: } ! 234: } ! 235: ! 236: static char * ! 237: aggr_variety (t) ! 238: tree t; ! 239: { ! 240: if (TREE_CODE (t) == ENUMERAL_TYPE) ! 241: return "enum"; ! 242: else if (TREE_CODE (t) == UNION_TYPE) ! 243: return "union"; ! 244: else if (TYPE_LANG_SPECIFIC (t) && CLASSTYPE_DECLARED_CLASS (t)) ! 245: return "class"; ! 246: else if (TYPE_LANG_SPECIFIC (t) && IS_SIGNATURE (t)) ! 247: return "signature"; ! 248: else ! 249: return "struct"; ! 250: } ! 251: ! 252: /* Print out a class declaration, in the form `class foo'. */ ! 253: static void ! 254: dump_aggr_type (t, v) ! 255: tree t; ! 256: int v; /* verbose? */ ! 257: { ! 258: tree name; ! 259: char *variety = aggr_variety (t); ! 260: ! 261: dump_readonly_or_volatile (t, after); ! 262: ! 263: if (v > 0) ! 264: { ! 265: OB_PUTCP (variety); ! 266: OB_PUTC (' '); ! 267: } ! 268: ! 269: name = TYPE_NAME (t); ! 270: ! 271: if (DECL_CONTEXT (name)) ! 272: { ! 273: /* FUNCTION_DECL or RECORD_TYPE */ ! 274: dump_decl (DECL_CONTEXT (name), 0); ! 275: OB_PUTC2 (':', ':'); ! 276: } ! 277: ! 278: /* kludge around wierd behavior on g++.brendan/line1.C */ ! 279: if (TREE_CODE (name) != IDENTIFIER_NODE) ! 280: name = DECL_NAME (name); ! 281: ! 282: if (ANON_AGGRNAME_P (name)) ! 283: { ! 284: OB_PUTS ("{anonymous"); ! 285: if (!v) ! 286: { ! 287: OB_PUTC (' '); ! 288: OB_PUTCP (variety); ! 289: } ! 290: OB_PUTC ('}'); ! 291: } ! 292: else ! 293: OB_PUTID (name); ! 294: } ! 295: ! 296: /* Dump into the obstack the initial part of the output for a given type. ! 297: This is necessary when dealing with things like functions returning ! 298: functions. Examples: ! 299: ! 300: return type of `int (* fee ())()': pointer -> function -> int. Both ! 301: pointer (and reference and offset) and function (and member) types must ! 302: deal with prefix and suffix. ! 303: ! 304: Arrays must also do this for DECL nodes, like int a[], and for things like ! 305: int *[]&. */ ! 306: ! 307: static void ! 308: dump_type_prefix (t, v) ! 309: tree t; ! 310: int v; /* verbosity */ ! 311: { ! 312: if (TYPE_PTRMEMFUNC_P (t)) ! 313: { ! 314: t = TYPE_PTRMEMFUNC_FN_TYPE (t); ! 315: goto offset_type; ! 316: } ! 317: ! 318: switch (TREE_CODE (t)) ! 319: { ! 320: case POINTER_TYPE: ! 321: { ! 322: tree sub = TREE_TYPE (t); ! 323: ! 324: dump_type_prefix (sub, v); ! 325: /* A tree for a member pointer looks like pointer to offset, ! 326: so let the OFFSET_TYPE case handle it. */ ! 327: if (TREE_CODE (sub) != OFFSET_TYPE) ! 328: { ! 329: switch (TREE_CODE (sub)) ! 330: { ! 331: /* We don't want int ( *)() */ ! 332: case FUNCTION_TYPE: ! 333: case METHOD_TYPE: ! 334: break; ! 335: ! 336: case ARRAY_TYPE: ! 337: OB_PUTC2 (' ', '('); ! 338: break; ! 339: ! 340: case POINTER_TYPE: ! 341: /* We don't want "char * *" */ ! 342: if (! (TYPE_READONLY (sub) || TYPE_VOLATILE (sub))) ! 343: break; ! 344: /* But we do want "char *const *" */ ! 345: ! 346: default: ! 347: OB_PUTC (' '); ! 348: } ! 349: OB_PUTC ('*'); ! 350: dump_readonly_or_volatile (t, none); ! 351: } ! 352: } ! 353: break; ! 354: ! 355: case REFERENCE_TYPE: ! 356: { ! 357: tree sub = TREE_TYPE (t); ! 358: dump_type_prefix (sub, v); ! 359: ! 360: switch (TREE_CODE (sub)) ! 361: { ! 362: case ARRAY_TYPE: ! 363: OB_PUTC2 (' ', '('); ! 364: break; ! 365: ! 366: case POINTER_TYPE: ! 367: /* We don't want "char * &" */ ! 368: if (! (TYPE_READONLY (sub) || TYPE_VOLATILE (sub))) ! 369: break; ! 370: /* But we do want "char *const &" */ ! 371: ! 372: default: ! 373: OB_PUTC (' '); ! 374: } ! 375: } ! 376: OB_PUTC ('&'); ! 377: dump_readonly_or_volatile (t, none); ! 378: break; ! 379: ! 380: case OFFSET_TYPE: ! 381: offset_type: ! 382: dump_type_prefix (TREE_TYPE (t), v); ! 383: if (TREE_CODE (t) == OFFSET_TYPE) /* pmfs deal with this in d_t_p */ ! 384: { ! 385: OB_PUTC (' '); ! 386: dump_type (TYPE_OFFSET_BASETYPE (t), 0); ! 387: OB_PUTC2 (':', ':'); ! 388: } ! 389: OB_PUTC ('*'); ! 390: dump_readonly_or_volatile (t, none); ! 391: break; ! 392: ! 393: /* Can only be reached through function pointer -- this would not be ! 394: correct if FUNCTION_DECLs used it. */ ! 395: case FUNCTION_TYPE: ! 396: dump_type_prefix (TREE_TYPE (t), v); ! 397: OB_PUTC2 (' ', '('); ! 398: break; ! 399: ! 400: case METHOD_TYPE: ! 401: dump_type_prefix (TREE_TYPE (t), v); ! 402: OB_PUTC2 (' ', '('); ! 403: dump_aggr_type (TYPE_METHOD_BASETYPE (t), 0); ! 404: OB_PUTC2 (':', ':'); ! 405: break; ! 406: ! 407: case ARRAY_TYPE: ! 408: dump_type_prefix (TREE_TYPE (t), v); ! 409: break; ! 410: ! 411: case ENUMERAL_TYPE: ! 412: case ERROR_MARK: ! 413: case IDENTIFIER_NODE: ! 414: case INTEGER_TYPE: ! 415: case BOOLEAN_TYPE: ! 416: case REAL_TYPE: ! 417: case RECORD_TYPE: ! 418: case TEMPLATE_TYPE_PARM: ! 419: case TREE_LIST: ! 420: case TYPE_DECL: ! 421: case TREE_VEC: ! 422: case UNINSTANTIATED_P_TYPE: ! 423: case UNION_TYPE: ! 424: case UNKNOWN_TYPE: ! 425: case VOID_TYPE: ! 426: dump_type (t, v); ! 427: break; ! 428: ! 429: default: ! 430: sorry ("`%s' not supported by dump_type_prefix", ! 431: tree_code_name[(int) TREE_CODE (t)]); ! 432: } ! 433: } ! 434: ! 435: static void ! 436: dump_type_suffix (t, v) ! 437: tree t; ! 438: int v; /* verbose? */ ! 439: { ! 440: if (TYPE_PTRMEMFUNC_P (t)) ! 441: t = TYPE_PTRMEMFUNC_FN_TYPE (t); ! 442: ! 443: switch (TREE_CODE (t)) ! 444: { ! 445: case POINTER_TYPE: ! 446: case REFERENCE_TYPE: ! 447: case OFFSET_TYPE: ! 448: if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE) ! 449: OB_PUTC (')'); ! 450: dump_type_suffix (TREE_TYPE (t), v); ! 451: break; ! 452: ! 453: /* Can only be reached through function pointer */ ! 454: case FUNCTION_TYPE: ! 455: case METHOD_TYPE: ! 456: { ! 457: tree arg; ! 458: OB_PUTC2 (')', '('); ! 459: arg = TYPE_ARG_TYPES (t); ! 460: if (TREE_CODE (t) == METHOD_TYPE) ! 461: arg = TREE_CHAIN (arg); ! 462: ! 463: if (arg) ! 464: dump_type (arg, v); ! 465: else ! 466: OB_PUTS ("..."); ! 467: OB_PUTC (')'); ! 468: if (TREE_CODE (t) == METHOD_TYPE) ! 469: dump_readonly_or_volatile ! 470: (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))), before); ! 471: dump_type_suffix (TREE_TYPE (t), v); ! 472: break; ! 473: } ! 474: ! 475: case ARRAY_TYPE: ! 476: OB_PUTC ('['); ! 477: if (TYPE_DOMAIN (t)) ! 478: OB_PUTI (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) + 1); ! 479: OB_PUTC (']'); ! 480: dump_type_suffix (TREE_TYPE (t), v); ! 481: break; ! 482: ! 483: case ENUMERAL_TYPE: ! 484: case ERROR_MARK: ! 485: case IDENTIFIER_NODE: ! 486: case INTEGER_TYPE: ! 487: case BOOLEAN_TYPE: ! 488: case REAL_TYPE: ! 489: case RECORD_TYPE: ! 490: case TEMPLATE_TYPE_PARM: ! 491: case TREE_LIST: ! 492: case TYPE_DECL: ! 493: case TREE_VEC: ! 494: case UNINSTANTIATED_P_TYPE: ! 495: case UNION_TYPE: ! 496: case UNKNOWN_TYPE: ! 497: case VOID_TYPE: ! 498: break; ! 499: ! 500: default: ! 501: sorry ("`%s' not supported by dump_type_suffix", ! 502: tree_code_name[(int) TREE_CODE (t)]); ! 503: } ! 504: } ! 505: ! 506: /* Return a function declaration which corresponds to the IDENTIFIER_NODE ! 507: argument. */ ! 508: tree ! 509: ident_fndecl (t) ! 510: tree t; ! 511: { ! 512: tree n = lookup_name (t, 0); ! 513: ! 514: if (TREE_CODE (n) == FUNCTION_DECL) ! 515: return n; ! 516: else if (TREE_CODE (n) == TREE_LIST ! 517: && TREE_CODE (TREE_VALUE (n)) == FUNCTION_DECL) ! 518: return TREE_VALUE (n); ! 519: ! 520: my_friendly_abort (66); ! 521: return NULL_TREE; ! 522: } ! 523: ! 524: #ifndef NO_DOLLAR_IN_LABEL ! 525: # define GLOBAL_THING "_GLOBAL_$" ! 526: #else ! 527: # ifndef NO_DOT_IN_LABEL ! 528: # define GLOBAL_THING "_GLOBAL_." ! 529: # else ! 530: # define GLOBAL_THING "_GLOBAL__" ! 531: # endif ! 532: #endif ! 533: ! 534: #define GLOBAL_IORD_P(NODE) \ ! 535: !strncmp(IDENTIFIER_POINTER(NODE),GLOBAL_THING,sizeof(GLOBAL_THING)-1) ! 536: ! 537: void ! 538: dump_global_iord (t) ! 539: tree t; ! 540: { ! 541: char *name = IDENTIFIER_POINTER (t); ! 542: ! 543: OB_PUTS ("(static "); ! 544: if (name [sizeof (GLOBAL_THING) - 1] == 'I') ! 545: OB_PUTS ("initializers"); ! 546: else if (name [sizeof (GLOBAL_THING) - 1] == 'D') ! 547: OB_PUTS ("destructors"); ! 548: else ! 549: my_friendly_abort (352); ! 550: ! 551: OB_PUTS (" for "); ! 552: OB_PUTCP (input_filename); ! 553: OB_PUTC (')'); ! 554: } ! 555: ! 556: static void ! 557: dump_decl (t, v) ! 558: tree t; ! 559: int v; /* verbosity */ ! 560: { ! 561: if (t == NULL_TREE) ! 562: return; ! 563: ! 564: switch (TREE_CODE (t)) ! 565: { ! 566: case ERROR_MARK: ! 567: OB_PUTS (" /* decl error */ "); ! 568: break; ! 569: ! 570: case TYPE_DECL: ! 571: { ! 572: /* Don't say 'typedef class A' */ ! 573: tree type = TREE_TYPE (t); ! 574: if (((IS_AGGR_TYPE (type) && ! TYPE_PTRMEMFUNC_P (type)) ! 575: || TREE_CODE (type) == ENUMERAL_TYPE) ! 576: && type == TYPE_MAIN_VARIANT (type)) ! 577: { ! 578: dump_type (type, v); ! 579: break; ! 580: } ! 581: } ! 582: if (v > 0) ! 583: OB_PUTS ("typedef "); ! 584: goto general; ! 585: break; ! 586: ! 587: case VAR_DECL: ! 588: if (VTABLE_NAME_P (DECL_NAME (t))) ! 589: { ! 590: OB_PUTS ("vtable for "); ! 591: dump_type (DECL_CONTEXT (t), v); ! 592: break; ! 593: } ! 594: /* else fall through */ ! 595: case FIELD_DECL: ! 596: case PARM_DECL: ! 597: general: ! 598: if (v > 0) ! 599: { ! 600: dump_type_prefix (TREE_TYPE (t), v); ! 601: OB_PUTC (' '); ! 602: } ! 603: /* DECL_CLASS_CONTEXT isn't being set in some cases. Hmm... */ ! 604: if (DECL_CONTEXT (t) ! 605: && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (t))) == 't') ! 606: { ! 607: dump_type (DECL_CONTEXT (t), 0); ! 608: OB_PUTC2 (':', ':'); ! 609: } ! 610: if (DECL_NAME (t)) ! 611: dump_decl (DECL_NAME (t), v); ! 612: else ! 613: OB_PUTS ("{anon}"); ! 614: if (v > 0) ! 615: dump_type_suffix (TREE_TYPE (t), v); ! 616: break; ! 617: ! 618: case ARRAY_REF: ! 619: dump_decl (TREE_OPERAND (t, 0), v); ! 620: OB_PUTC ('['); ! 621: dump_decl (TREE_OPERAND (t, 1), v); ! 622: OB_PUTC (']'); ! 623: break; ! 624: ! 625: /* So that we can do dump_decl in dump_aggr_type and have it work for ! 626: both class and function scope. */ ! 627: case RECORD_TYPE: ! 628: case UNION_TYPE: ! 629: case ENUMERAL_TYPE: ! 630: dump_type (t, v); ! 631: break; ! 632: ! 633: case TYPE_EXPR: ! 634: my_friendly_abort (69); ! 635: break; ! 636: ! 637: /* These special cases are duplicated here so that other functions ! 638: can feed identifiers to cp_error and get them demangled properly. */ ! 639: case IDENTIFIER_NODE: ! 640: if (DESTRUCTOR_NAME_P (t)) ! 641: { ! 642: OB_PUTC ('~'); ! 643: dump_decl (DECL_NAME (ident_fndecl (t)), 0); ! 644: } ! 645: else if (IDENTIFIER_TYPENAME_P (t)) ! 646: { ! 647: OB_PUTS ("operator "); ! 648: /* Not exactly IDENTIFIER_TYPE_VALUE. */ ! 649: dump_type (TREE_TYPE (t), 0); ! 650: break; ! 651: } ! 652: else if (IDENTIFIER_OPNAME_P (t)) ! 653: { ! 654: char *name_string = operator_name_string (t); ! 655: OB_PUTS ("operator "); ! 656: OB_PUTCP (name_string); ! 657: } ! 658: else ! 659: OB_PUTID (t); ! 660: break; ! 661: ! 662: case FUNCTION_DECL: ! 663: if (GLOBAL_IORD_P (DECL_ASSEMBLER_NAME (t))) ! 664: dump_global_iord (DECL_ASSEMBLER_NAME (t)); ! 665: else ! 666: dump_function_decl (t, v); ! 667: break; ! 668: ! 669: case TEMPLATE_DECL: ! 670: { ! 671: tree args = DECL_TEMPLATE_PARMS (t); ! 672: int i, len = args ? TREE_VEC_LENGTH (args) : 0; ! 673: OB_PUTS ("template <"); ! 674: for (i = 0; i < len; i++) ! 675: { ! 676: tree arg = TREE_VEC_ELT (args, i); ! 677: tree defval = TREE_PURPOSE (arg); ! 678: arg = TREE_VALUE (arg); ! 679: if (TREE_CODE (arg) == TYPE_DECL) ! 680: { ! 681: OB_PUTS ("class "); ! 682: OB_PUTID (DECL_NAME (arg)); ! 683: } ! 684: else ! 685: dump_decl (arg, 1); ! 686: ! 687: if (defval) ! 688: { ! 689: OB_PUTS (" = "); ! 690: dump_decl (defval, 1); ! 691: } ! 692: ! 693: OB_PUTC2 (',', ' '); ! 694: } ! 695: if (len != 0) ! 696: OB_UNPUT (2); ! 697: OB_PUTC2 ('>', ' '); ! 698: ! 699: if (DECL_TEMPLATE_IS_CLASS (t)) ! 700: { ! 701: OB_PUTS ("class "); ! 702: OB_PUTID (DECL_NAME (t)); ! 703: } ! 704: else switch (NEXT_CODE (t)) ! 705: { ! 706: case METHOD_TYPE: ! 707: case FUNCTION_TYPE: ! 708: dump_function_decl (t, v); ! 709: break; ! 710: ! 711: default: ! 712: my_friendly_abort (353); ! 713: } ! 714: } ! 715: break; ! 716: ! 717: case LABEL_DECL: ! 718: OB_PUTID (DECL_NAME (t)); ! 719: break; ! 720: ! 721: case CONST_DECL: ! 722: if (NEXT_CODE (t) == ENUMERAL_TYPE) ! 723: goto general; ! 724: else ! 725: dump_expr (DECL_INITIAL (t), 0); ! 726: break; ! 727: ! 728: default: ! 729: sorry ("`%s' not supported by dump_decl", ! 730: tree_code_name[(int) TREE_CODE (t)]); ! 731: } ! 732: } ! 733: ! 734: /* Pretty printing for announce_function. T is the declaration of the ! 735: function we are interested in seeing. V is non-zero if we should print ! 736: the type that this function returns. */ ! 737: ! 738: static void ! 739: dump_function_decl (t, v) ! 740: tree t; ! 741: int v; ! 742: { ! 743: tree name = DECL_ASSEMBLER_NAME (t); ! 744: tree fntype = TREE_TYPE (t); ! 745: tree parmtypes = TYPE_ARG_TYPES (fntype); ! 746: tree cname = NULL_TREE; ! 747: ! 748: /* Friends have DECL_CLASS_CONTEXT set, but not DECL_CONTEXT. */ ! 749: if (DECL_CONTEXT (t)) ! 750: cname = DECL_CLASS_CONTEXT (t); ! 751: /* this is for partially instantiated template methods */ ! 752: else if (TREE_CODE (fntype) == METHOD_TYPE) ! 753: cname = TREE_TYPE (TREE_VALUE (parmtypes)); ! 754: ! 755: v = (v > 0); ! 756: ! 757: if (v) ! 758: { ! 759: if (DECL_STATIC_FUNCTION_P (t)) ! 760: OB_PUTS ("static "); ! 761: ! 762: if (! IDENTIFIER_TYPENAME_P (name) ! 763: && ! DECL_CONSTRUCTOR_P (t) ! 764: && ! DESTRUCTOR_NAME_P (name)) ! 765: { ! 766: dump_type_prefix (TREE_TYPE (fntype), 1); ! 767: OB_PUTC (' '); ! 768: } ! 769: } ! 770: ! 771: if (cname) ! 772: { ! 773: dump_type (cname, 0); ! 774: OB_PUTC2 (':', ':'); ! 775: if (TREE_CODE (fntype) == METHOD_TYPE && parmtypes) ! 776: parmtypes = TREE_CHAIN (parmtypes); ! 777: if (DECL_CONSTRUCTOR_FOR_VBASE_P (t)) ! 778: /* Skip past "in_charge" identifier. */ ! 779: parmtypes = TREE_CHAIN (parmtypes); ! 780: } ! 781: ! 782: if (DESTRUCTOR_NAME_P (name)) ! 783: parmtypes = TREE_CHAIN (parmtypes); ! 784: ! 785: dump_function_name (t); ! 786: ! 787: OB_PUTC ('('); ! 788: ! 789: if (parmtypes) ! 790: dump_type (parmtypes, v); ! 791: else ! 792: OB_PUTS ("..."); ! 793: ! 794: OB_PUTC (')'); ! 795: ! 796: if (v && ! IDENTIFIER_TYPENAME_P (name)) ! 797: dump_type_suffix (TREE_TYPE (fntype), 1); ! 798: ! 799: if (TREE_CODE (fntype) == METHOD_TYPE) ! 800: { ! 801: if (IS_SIGNATURE (cname)) ! 802: /* We look at the type pointed to by the `optr' field of `this.' */ ! 803: dump_readonly_or_volatile ! 804: (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_VALUE (TYPE_ARG_TYPES (fntype))))), before); ! 805: else ! 806: dump_readonly_or_volatile ! 807: (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))), before); ! 808: } ! 809: } ! 810: ! 811: /* Handle the function name for a FUNCTION_DECL node, grokking operators ! 812: and destructors properly. */ ! 813: static void ! 814: dump_function_name (t) ! 815: tree t; ! 816: { ! 817: tree name = DECL_NAME (t); ! 818: ! 819: /* There ought to be a better way to find out whether or not something is ! 820: a destructor. */ ! 821: if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (t))) ! 822: { ! 823: OB_PUTC ('~'); ! 824: dump_decl (name, 0); ! 825: } ! 826: else if (IDENTIFIER_TYPENAME_P (name)) ! 827: { ! 828: /* This cannot use the hack that the operator's return ! 829: type is stashed off of its name because it may be ! 830: used for error reporting. In the case of conflicting ! 831: declarations, both will have the same name, yet ! 832: the types will be different, hence the TREE_TYPE field ! 833: of the first name will be clobbered by the second. */ ! 834: OB_PUTS ("operator "); ! 835: dump_type (TREE_TYPE (TREE_TYPE (t)), 0); ! 836: } ! 837: else if (IDENTIFIER_OPNAME_P (name)) ! 838: { ! 839: char *name_string = operator_name_string (name); ! 840: OB_PUTS ("operator "); ! 841: OB_PUTCP (name_string); ! 842: } ! 843: else ! 844: dump_decl (name, 0); ! 845: } ! 846: ! 847: static void ! 848: dump_char (c) ! 849: char c; ! 850: { ! 851: switch (c) ! 852: { ! 853: case TARGET_NEWLINE: ! 854: OB_PUTS ("\\n"); ! 855: break; ! 856: case TARGET_TAB: ! 857: OB_PUTS ("\\t"); ! 858: break; ! 859: case TARGET_VT: ! 860: OB_PUTS ("\\v"); ! 861: break; ! 862: case TARGET_BS: ! 863: OB_PUTS ("\\b"); ! 864: break; ! 865: case TARGET_CR: ! 866: OB_PUTS ("\\r"); ! 867: break; ! 868: case TARGET_FF: ! 869: OB_PUTS ("\\f"); ! 870: break; ! 871: case TARGET_BELL: ! 872: OB_PUTS ("\\a"); ! 873: break; ! 874: case '\\': ! 875: OB_PUTS ("\\\\"); ! 876: break; ! 877: case '\'': ! 878: OB_PUTS ("\\'"); ! 879: break; ! 880: case '\"': ! 881: OB_PUTS ("\\\""); ! 882: break; ! 883: default: ! 884: if (isprint (c)) ! 885: OB_PUTC (c); ! 886: else ! 887: { ! 888: sprintf (digit_buffer, "\\%03o", (int) c); ! 889: OB_PUTCP (digit_buffer); ! 890: } ! 891: } ! 892: } ! 893: ! 894: /* Print out a list of initializers (subr of dump_expr) */ ! 895: static void ! 896: dump_expr_list (l) ! 897: tree l; ! 898: { ! 899: while (l) ! 900: { ! 901: dump_expr (TREE_VALUE (l), 0); ! 902: if (TREE_CHAIN (l)) ! 903: OB_PUTC2 (',', ' '); ! 904: l = TREE_CHAIN (l); ! 905: } ! 906: } ! 907: ! 908: /* Print out an expression */ ! 909: static void ! 910: dump_expr (t, nop) ! 911: tree t; ! 912: int nop; /* suppress parens */ ! 913: { ! 914: switch (TREE_CODE (t)) ! 915: { ! 916: case VAR_DECL: ! 917: case PARM_DECL: ! 918: case FIELD_DECL: ! 919: case CONST_DECL: ! 920: case FUNCTION_DECL: ! 921: dump_decl (t, -1); ! 922: break; ! 923: ! 924: case INTEGER_CST: ! 925: { ! 926: tree type = TREE_TYPE (t); ! 927: my_friendly_assert (type != 0, 81); ! 928: ! 929: /* If it's an enum, output its tag, rather than its value. */ ! 930: if (TREE_CODE (type) == ENUMERAL_TYPE) ! 931: { ! 932: char *p = enum_name_string (t, type); ! 933: OB_PUTCP (p); ! 934: } ! 935: else if (type == char_type_node ! 936: || type == signed_char_type_node ! 937: || type == unsigned_char_type_node) ! 938: { ! 939: OB_PUTC ('\''); ! 940: dump_char (TREE_INT_CST_LOW (t)); ! 941: OB_PUTC ('\''); ! 942: } ! 943: else if (TREE_INT_CST_HIGH (t) ! 944: != (TREE_INT_CST_LOW (t) >> (HOST_BITS_PER_WIDE_INT - 1))) ! 945: { ! 946: tree val = t; ! 947: if (TREE_INT_CST_HIGH (val) < 0) ! 948: { ! 949: OB_PUTC ('-'); ! 950: val = build_int_2 (~TREE_INT_CST_LOW (val), ! 951: -TREE_INT_CST_HIGH (val)); ! 952: } ! 953: /* Would "%x%0*x" or "%x%*0x" get zero-padding on all ! 954: systems? */ ! 955: { ! 956: static char format[10]; /* "%x%09999x\0" */ ! 957: if (!format[0]) ! 958: sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4); ! 959: sprintf (digit_buffer, format, TREE_INT_CST_HIGH (val), ! 960: TREE_INT_CST_LOW (val)); ! 961: OB_PUTCP (digit_buffer); ! 962: } ! 963: } ! 964: else ! 965: OB_PUTI (TREE_INT_CST_LOW (t)); ! 966: } ! 967: break; ! 968: ! 969: case REAL_CST: ! 970: #ifndef REAL_IS_NOT_DOUBLE ! 971: sprintf (digit_buffer, "%g", TREE_REAL_CST (t)); ! 972: #else ! 973: { ! 974: unsigned char *p = (unsigned char *) &TREE_REAL_CST (t); ! 975: int i; ! 976: strcpy (digit_buffer, "0x"); ! 977: for (i = 0; i < sizeof TREE_REAL_CST (t); i++) ! 978: sprintf (digit_buffer + 2 + 2*i, "%02x", *p++); ! 979: } ! 980: #endif ! 981: OB_PUTCP (digit_buffer); ! 982: break; ! 983: ! 984: case STRING_CST: ! 985: { ! 986: char *p = TREE_STRING_POINTER (t); ! 987: int len = TREE_STRING_LENGTH (t) - 1; ! 988: int i; ! 989: ! 990: OB_PUTC ('\"'); ! 991: for (i = 0; i < len; i++) ! 992: dump_char (p[i]); ! 993: OB_PUTC ('\"'); ! 994: } ! 995: break; ! 996: ! 997: case COMPOUND_EXPR: ! 998: dump_binary_op (",", t); ! 999: break; ! 1000: ! 1001: case COND_EXPR: ! 1002: OB_PUTC ('('); ! 1003: dump_expr (TREE_OPERAND (t, 0), 0); ! 1004: OB_PUTS (" ? "); ! 1005: dump_expr (TREE_OPERAND (t, 1), 0); ! 1006: OB_PUTS (" : "); ! 1007: dump_expr (TREE_OPERAND (t, 2), 0); ! 1008: OB_PUTC (')'); ! 1009: break; ! 1010: ! 1011: case SAVE_EXPR: ! 1012: if (TREE_HAS_CONSTRUCTOR (t)) ! 1013: { ! 1014: OB_PUTS ("new "); ! 1015: dump_type (TREE_TYPE (TREE_TYPE (t)), 0); ! 1016: PARM_DECL_EXPR (t) = 1; ! 1017: } ! 1018: else ! 1019: { ! 1020: sorry ("operand of SAVE_EXPR not understood"); ! 1021: goto error; ! 1022: } ! 1023: break; ! 1024: ! 1025: case NEW_EXPR: ! 1026: OB_PUTID (TYPE_IDENTIFIER (TREE_TYPE (t))); ! 1027: OB_PUTC ('('); ! 1028: dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1))); ! 1029: OB_PUTC (')'); ! 1030: break; ! 1031: ! 1032: case CALL_EXPR: ! 1033: { ! 1034: tree fn = TREE_OPERAND (t, 0); ! 1035: tree args = TREE_OPERAND (t, 1); ! 1036: ! 1037: if (TREE_CODE (fn) == ADDR_EXPR) ! 1038: fn = TREE_OPERAND (fn, 0); ! 1039: ! 1040: if (NEXT_CODE (fn) == METHOD_TYPE) ! 1041: { ! 1042: tree ob = TREE_VALUE (args); ! 1043: if (TREE_CODE (ob) == ADDR_EXPR) ! 1044: { ! 1045: dump_expr (TREE_OPERAND (ob, 0), 0); ! 1046: OB_PUTC ('.'); ! 1047: } ! 1048: else if (TREE_CODE (ob) != PARM_DECL ! 1049: || strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this")) ! 1050: { ! 1051: dump_expr (ob, 0); ! 1052: OB_PUTC2 ('-', '>'); ! 1053: } ! 1054: args = TREE_CHAIN (args); ! 1055: } ! 1056: dump_expr (fn, 0); ! 1057: OB_PUTC('('); ! 1058: dump_expr_list (args); ! 1059: OB_PUTC (')'); ! 1060: } ! 1061: break; ! 1062: ! 1063: case WITH_CLEANUP_EXPR: ! 1064: /* Note that this only works for G++ cleanups. If somebody ! 1065: builds a general cleanup, there's no way to represent it. */ ! 1066: dump_expr (TREE_OPERAND (t, 0), 0); ! 1067: break; ! 1068: ! 1069: case TARGET_EXPR: ! 1070: /* Note that this only works for G++ target exprs. If somebody ! 1071: builds a general TARGET_EXPR, there's no way to represent that ! 1072: it initializes anything other that the parameter slot for the ! 1073: default argument. Note we may have cleared out the first ! 1074: operand in expand_expr, so don't go killing ourselves. */ ! 1075: if (TREE_OPERAND (t, 1)) ! 1076: dump_expr (TREE_OPERAND (t, 1), 0); ! 1077: break; ! 1078: ! 1079: case MODIFY_EXPR: ! 1080: case PLUS_EXPR: ! 1081: case MINUS_EXPR: ! 1082: case MULT_EXPR: ! 1083: case TRUNC_DIV_EXPR: ! 1084: case TRUNC_MOD_EXPR: ! 1085: case MIN_EXPR: ! 1086: case MAX_EXPR: ! 1087: case LSHIFT_EXPR: ! 1088: case RSHIFT_EXPR: ! 1089: case BIT_IOR_EXPR: ! 1090: case BIT_XOR_EXPR: ! 1091: case BIT_AND_EXPR: ! 1092: case BIT_ANDTC_EXPR: ! 1093: case TRUTH_ANDIF_EXPR: ! 1094: case TRUTH_ORIF_EXPR: ! 1095: case LT_EXPR: ! 1096: case LE_EXPR: ! 1097: case GT_EXPR: ! 1098: case GE_EXPR: ! 1099: case EQ_EXPR: ! 1100: case NE_EXPR: ! 1101: dump_binary_op (opname_tab[(int) TREE_CODE (t)], t); ! 1102: break; ! 1103: ! 1104: case CEIL_DIV_EXPR: ! 1105: case FLOOR_DIV_EXPR: ! 1106: case ROUND_DIV_EXPR: ! 1107: dump_binary_op ("/", t); ! 1108: break; ! 1109: ! 1110: case CEIL_MOD_EXPR: ! 1111: case FLOOR_MOD_EXPR: ! 1112: case ROUND_MOD_EXPR: ! 1113: dump_binary_op ("%", t); ! 1114: break; ! 1115: ! 1116: case COMPONENT_REF: ! 1117: { ! 1118: tree ob = TREE_OPERAND (t, 0); ! 1119: if (TREE_CODE (ob) == INDIRECT_REF) ! 1120: { ! 1121: ob = TREE_OPERAND (ob, 0); ! 1122: if (TREE_CODE (ob) != PARM_DECL ! 1123: || strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this")) ! 1124: { ! 1125: dump_expr (ob, 0); ! 1126: OB_PUTC2 ('-', '>'); ! 1127: } ! 1128: } ! 1129: else ! 1130: { ! 1131: dump_expr (ob, 0); ! 1132: OB_PUTC ('.'); ! 1133: } ! 1134: dump_expr (TREE_OPERAND (t, 1), 1); ! 1135: } ! 1136: break; ! 1137: ! 1138: case CONVERT_EXPR: ! 1139: dump_unary_op ("+", t, nop); ! 1140: break; ! 1141: ! 1142: case ADDR_EXPR: ! 1143: if (TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL ! 1144: || TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST) ! 1145: dump_expr (TREE_OPERAND (t, 0), 0); ! 1146: else ! 1147: dump_unary_op ("&", t, nop); ! 1148: break; ! 1149: ! 1150: case INDIRECT_REF: ! 1151: if (TREE_HAS_CONSTRUCTOR (t)) ! 1152: { ! 1153: t = TREE_OPERAND (t, 0); ! 1154: my_friendly_assert (TREE_CODE (t) == CALL_EXPR, 237); ! 1155: dump_expr (TREE_OPERAND (t, 0), 0); ! 1156: OB_PUTC ('('); ! 1157: dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1))); ! 1158: OB_PUTC (')'); ! 1159: } ! 1160: else ! 1161: { ! 1162: if (NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE) ! 1163: dump_expr (TREE_OPERAND (t, 0), nop); ! 1164: else ! 1165: dump_unary_op ("*", t, nop); ! 1166: } ! 1167: break; ! 1168: ! 1169: case NEGATE_EXPR: ! 1170: case BIT_NOT_EXPR: ! 1171: case TRUTH_NOT_EXPR: ! 1172: case PREDECREMENT_EXPR: ! 1173: case PREINCREMENT_EXPR: ! 1174: dump_unary_op (opname_tab [(int)TREE_CODE (t)], t, nop); ! 1175: break; ! 1176: ! 1177: case POSTDECREMENT_EXPR: ! 1178: case POSTINCREMENT_EXPR: ! 1179: OB_PUTC ('('); ! 1180: dump_expr (TREE_OPERAND (t, 0), 0); ! 1181: OB_PUTCP (opname_tab[(int)TREE_CODE (t)]); ! 1182: OB_PUTC (')'); ! 1183: break; ! 1184: ! 1185: case NON_LVALUE_EXPR: ! 1186: /* FIXME: This is a KLUDGE workaround for a parsing problem. There ! 1187: should be another level of INDIRECT_REF so that I don't have to do ! 1188: this. */ ! 1189: if (NEXT_CODE (t) == POINTER_TYPE) ! 1190: { ! 1191: tree next = TREE_TYPE (TREE_TYPE (t)); ! 1192: ! 1193: while (TREE_CODE (next) == POINTER_TYPE) ! 1194: next = TREE_TYPE (next); ! 1195: ! 1196: if (TREE_CODE (next) == FUNCTION_TYPE) ! 1197: { ! 1198: if (!nop) OB_PUTC ('('); ! 1199: OB_PUTC ('*'); ! 1200: dump_expr (TREE_OPERAND (t, 0), 1); ! 1201: if (!nop) OB_PUTC (')'); ! 1202: break; ! 1203: } ! 1204: /* else FALLTHRU */ ! 1205: } ! 1206: dump_expr (TREE_OPERAND (t, 0), 0); ! 1207: break; ! 1208: ! 1209: case NOP_EXPR: ! 1210: dump_expr (TREE_OPERAND (t, 0), nop); ! 1211: break; ! 1212: ! 1213: case CONSTRUCTOR: ! 1214: OB_PUTC ('{'); ! 1215: dump_expr_list (CONSTRUCTOR_ELTS (t), 0); ! 1216: OB_PUTC ('}'); ! 1217: break; ! 1218: ! 1219: case OFFSET_REF: ! 1220: { ! 1221: tree ob = TREE_OPERAND (t, 0); ! 1222: if (TREE_CODE (ob) == NOP_EXPR ! 1223: && TREE_OPERAND (ob, 0) == error_mark_node ! 1224: && TREE_CODE (TREE_OPERAND (t, 1)) == FUNCTION_DECL) ! 1225: /* A::f */ ! 1226: dump_expr (TREE_OPERAND (t, 1), 0); ! 1227: else ! 1228: { ! 1229: sorry ("operand of OFFSET_REF not understood"); ! 1230: goto error; ! 1231: } ! 1232: break; ! 1233: } ! 1234: ! 1235: case TREE_LIST: ! 1236: if (TREE_VALUE (t) && TREE_CODE (TREE_VALUE (t)) == FUNCTION_DECL) ! 1237: { ! 1238: OB_PUTID (DECL_NAME (TREE_VALUE (t))); ! 1239: break; ! 1240: } ! 1241: /* else fall through */ ! 1242: ! 1243: /* This list is incomplete, but should suffice for now. ! 1244: It is very important that `sorry' does not call ! 1245: `report_error_function'. That could cause an infinite loop. */ ! 1246: default: ! 1247: sorry ("`%s' not supported by dump_expr", ! 1248: tree_code_name[(int) TREE_CODE (t)]); ! 1249: ! 1250: /* fall through to ERROR_MARK... */ ! 1251: case ERROR_MARK: ! 1252: error: ! 1253: OB_PUTCP ("{error}"); ! 1254: break; ! 1255: } ! 1256: } ! 1257: ! 1258: static void ! 1259: dump_binary_op (opstring, t) ! 1260: char *opstring; ! 1261: tree t; ! 1262: { ! 1263: OB_PUTC ('('); ! 1264: dump_expr (TREE_OPERAND (t, 0), 1); ! 1265: OB_PUTC (' '); ! 1266: OB_PUTCP (opstring); ! 1267: OB_PUTC (' '); ! 1268: dump_expr (TREE_OPERAND (t, 1), 1); ! 1269: OB_PUTC (')'); ! 1270: } ! 1271: ! 1272: static void ! 1273: dump_unary_op (opstring, t, nop) ! 1274: char *opstring; ! 1275: tree t; ! 1276: int nop; ! 1277: { ! 1278: if (!nop) OB_PUTC ('('); ! 1279: OB_PUTCP (opstring); ! 1280: dump_expr (TREE_OPERAND (t, 0), 1); ! 1281: if (!nop) OB_PUTC (')'); ! 1282: } ! 1283: ! 1284: char * ! 1285: fndecl_as_string (cname, fndecl, print_ret_type_p) ! 1286: tree cname, fndecl; ! 1287: int print_ret_type_p; ! 1288: { ! 1289: return decl_as_string (fndecl, print_ret_type_p); ! 1290: } ! 1291: ! 1292: /* Same, but handtype a _TYPE. ! 1293: Called from convert_to_reference, mangle_class_name_for_template, ! 1294: build_unary_op, and GNU_xref_decl. */ ! 1295: char * ! 1296: type_as_string (typ, v) ! 1297: tree typ; ! 1298: int v; ! 1299: { ! 1300: OB_INIT (); ! 1301: ! 1302: dump_type (typ, v); ! 1303: ! 1304: OB_FINISH (); ! 1305: ! 1306: return (char *)obstack_base (&scratch_obstack); ! 1307: } ! 1308: ! 1309: char * ! 1310: expr_as_string (decl, v) ! 1311: tree decl; ! 1312: int v; ! 1313: { ! 1314: OB_INIT (); ! 1315: ! 1316: dump_expr (decl, 1); ! 1317: ! 1318: OB_FINISH (); ! 1319: ! 1320: return (char *)obstack_base (&scratch_obstack); ! 1321: } ! 1322: ! 1323: /* A cross between type_as_string and fndecl_as_string. ! 1324: Only called from substitute_nice_name. */ ! 1325: char * ! 1326: decl_as_string (decl, v) ! 1327: tree decl; ! 1328: int v; ! 1329: { ! 1330: OB_INIT (); ! 1331: ! 1332: dump_decl (decl, v); ! 1333: ! 1334: OB_FINISH (); ! 1335: ! 1336: return (char *)obstack_base (&scratch_obstack); ! 1337: } ! 1338: ! 1339: char * ! 1340: cp_file_of (t) ! 1341: tree t; ! 1342: { ! 1343: if (TREE_CODE (t) == PARM_DECL) ! 1344: return DECL_SOURCE_FILE (DECL_CONTEXT (t)); ! 1345: else if (TREE_CODE_CLASS (TREE_CODE (t)) == 't') ! 1346: return DECL_SOURCE_FILE (TYPE_NAME (t)); ! 1347: else ! 1348: return DECL_SOURCE_FILE (t); ! 1349: } ! 1350: ! 1351: int ! 1352: cp_line_of (t) ! 1353: tree t; ! 1354: { ! 1355: int line = 0; ! 1356: if (TREE_CODE (t) == PARM_DECL) ! 1357: line = DECL_SOURCE_LINE (DECL_CONTEXT (t)); ! 1358: if (TREE_CODE (t) == TYPE_DECL && DECL_ARTIFICIAL (t)) ! 1359: t = TREE_TYPE (t); ! 1360: ! 1361: if (TREE_CODE_CLASS (TREE_CODE (t)) == 't') ! 1362: { ! 1363: if (IS_AGGR_TYPE (t)) ! 1364: line = CLASSTYPE_SOURCE_LINE (t); ! 1365: else ! 1366: line = DECL_SOURCE_LINE (TYPE_NAME (t)); ! 1367: } ! 1368: else ! 1369: line = DECL_SOURCE_LINE (t); ! 1370: ! 1371: if (line == 0) ! 1372: return lineno; ! 1373: ! 1374: return line; ! 1375: } ! 1376: ! 1377: char * ! 1378: code_as_string (c, v) ! 1379: enum tree_code c; ! 1380: int v; ! 1381: { ! 1382: return tree_code_name [c]; ! 1383: } ! 1384: ! 1385: char * ! 1386: language_as_string (c, v) ! 1387: enum languages c; ! 1388: int v; ! 1389: { ! 1390: switch (c) ! 1391: { ! 1392: case lang_c: ! 1393: return "C"; ! 1394: ! 1395: case lang_cplusplus: ! 1396: return "C++"; ! 1397: ! 1398: default: ! 1399: my_friendly_abort (355); ! 1400: return 0; ! 1401: } ! 1402: } ! 1403: ! 1404: /* Return the proper printed version of a parameter to a C++ function. */ ! 1405: char * ! 1406: parm_as_string (p, v) ! 1407: int p, v; ! 1408: { ! 1409: if (p < 0) ! 1410: return "`this'"; ! 1411: ! 1412: sprintf (digit_buffer, "%d", p+1); ! 1413: return digit_buffer; ! 1414: } ! 1415: ! 1416: char * ! 1417: op_as_string (p, v) ! 1418: enum tree_code p; ! 1419: int v; ! 1420: { ! 1421: static char buf[] = "operator "; ! 1422: ! 1423: if (p == 0) ! 1424: return "{unknown}"; ! 1425: ! 1426: strcpy (buf + 9, opname_tab [p]); ! 1427: return buf; ! 1428: } ! 1429: ! 1430: char * ! 1431: args_as_string (p, v) ! 1432: tree p; ! 1433: int v; ! 1434: { ! 1435: if (p == NULL_TREE) ! 1436: return "..."; ! 1437: ! 1438: return type_as_string (p, v); ! 1439: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.