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

unix.superglobalmegacorp.com

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