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

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

unix.superglobalmegacorp.com

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