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