Annotation of gcc/cp/error.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.