Annotation of gcc/cp-method.c, revision 1.1.1.1

1.1       root        1: /* Handle the hair of processing (but not expanding) inline functions.
                      2:    Also manage function and varaible name overloading.
                      3:    Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
                      4:    Contributed by Michael Tiemann ([email protected])
                      5: 
                      6:    This file is part of GNU CC.
                      7:    
                      8: GNU CC is free software; you can redistribute it and/or modify
                      9: it under the terms of the GNU General Public License as published by
                     10: the Free Software Foundation; either version 2, or (at your option)
                     11: any later version.
                     12: 
                     13: GNU CC is distributed in the hope that it will be useful,
                     14: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     15: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     16: GNU General Public License for more details.
                     17: 
                     18: You should have received a copy of the GNU General Public License
                     19: along with GNU CC; see the file COPYING.  If not, write to
                     20: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
                     21: 
                     22: 
                     23: #ifndef PARM_CAN_BE_ARRAY_TYPE
                     24: #define PARM_CAN_BE_ARRAY_TYPE 1
                     25: #endif
                     26: 
                     27: /* Handle method declarations.  */
                     28: #include <stdio.h>
                     29: #include <string.h>
                     30: #include "config.h"
                     31: #include "tree.h"
                     32: #include "cp-tree.h"
                     33: #include "cp-class.h"
                     34: #include "assert.h"
                     35: #include "obstack.h"
                     36: 
                     37: #define obstack_chunk_alloc xmalloc
                     38: #define obstack_chunk_free free
                     39: 
                     40: extern int xmalloc ();
                     41: extern void free ();
                     42: 
                     43: /* TREE_LIST of the current inline functions that need to be
                     44:    processed.  */
                     45: struct pending_inline *pending_inlines;
                     46: 
                     47: /* Obstack where we build text strings for overloading, etc.  */
                     48: static struct obstack scratch_obstack;
                     49: static char *scratch_firstobj;
                     50: 
                     51: # define OB_INIT() (scratch_firstobj ? (obstack_free (&scratch_obstack, scratch_firstobj), 0) : 0)
                     52: # define OB_PUTC(C) (obstack_1grow (&scratch_obstack, (C)))
                     53: # define OB_PUTC2(C1,C2)       \
                     54:   (obstack_1grow (&scratch_obstack, (C1)), obstack_1grow (&scratch_obstack, (C2)))
                     55: # define OB_PUTS(S) (obstack_grow (&scratch_obstack, (S), sizeof (S) - 1))
                     56: # define OB_PUTID(ID)  \
                     57:   (obstack_grow (&scratch_obstack, IDENTIFIER_POINTER (ID),    \
                     58:                 IDENTIFIER_LENGTH (ID)))
                     59: # define OB_PUTCP(S) (obstack_grow (&scratch_obstack, (S), strlen (S)))
                     60: # define OB_FINISH() (obstack_1grow (&scratch_obstack, '\0'))
                     61: 
                     62: /* Counter to help build parameter names in case they were omitted.  */
                     63: static int dummy_name;
                     64: static int in_parmlist;
                     65: 
                     66: /* This points to a safe place to resume processing in case an expression
                     67:    generates an error while we're trying to format it.  */
                     68: static int scratch_error_offset;
                     69: 
                     70: static void dump_type (), dump_decl ();
                     71: static void dump_init (), dump_unary_op (), dump_binary_op ();
                     72: 
                     73: tree wrapper_name, wrapper_pred_name, anti_wrapper_name;
                     74: 
                     75: #ifdef NO_AUTO_OVERLOAD
                     76: int is_overloaded ();
                     77: #endif
                     78: 
                     79: void
                     80: init_method ()
                     81: {
                     82:   char buf[sizeof (ANTI_WRAPPER_NAME_FORMAT) + 8];
                     83:   sprintf (buf, WRAPPER_NAME_FORMAT, "");
                     84:   wrapper_name = get_identifier (buf);
                     85:   sprintf (buf, WRAPPER_PRED_NAME_FORMAT, "");
                     86:   wrapper_pred_name = get_identifier (buf);
                     87:   sprintf (buf, ANTI_WRAPPER_NAME_FORMAT, "");
                     88:   anti_wrapper_name = get_identifier (buf);
                     89:   gcc_obstack_init (&scratch_obstack);
                     90:   scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0);
                     91: }
                     92: 
                     93: /* Return a pointer to the end of the new text in INLINE_BUFFER.
                     94:    We cannot use `fatal' or `error' in here because that
                     95:    might cause an infinite loop.  */
                     96: static char *
                     97: new_text_len (s)
                     98:      char *s;
                     99: {
                    100:   while (*s++) ;
                    101:   return s - 1;
                    102: }
                    103: 
                    104: tree
                    105: make_anon_parm_name ()
                    106: {
                    107:   char buf[32];
                    108: 
                    109:   sprintf (buf, ANON_PARMNAME_FORMAT, dummy_name++);
                    110:   return get_identifier (buf);
                    111: }
                    112: 
                    113: void
                    114: clear_anon_parm_name ()
                    115: {
                    116:   /* recycle these names.  */
                    117:   dummy_name = 0;
                    118: }
                    119: 
                    120: static void
                    121: dump_readonly_or_volatile (t)
                    122:      tree t;
                    123: {
                    124:   if (TYPE_READONLY (t))
                    125:     OB_PUTS ("const ");
                    126:   if (TYPE_VOLATILE (t))
                    127:     OB_PUTS ("volatile ");
                    128: }
                    129: 
                    130: static void
                    131: dump_aggr_type (t)
                    132:      tree t;
                    133: {
                    134:   tree name;
                    135:   char *aggr_string;
                    136:   char *context_string = 0;
                    137: 
                    138:   if (TYPE_READONLY (t))
                    139:     OB_PUTS ("const ");
                    140:   if (TYPE_VOLATILE (t))
                    141:     OB_PUTS ("volatile ");
                    142:   if (TREE_CODE (t) == ENUMERAL_TYPE)
                    143:     aggr_string = "enum";
                    144:   else if (TREE_CODE (t) == UNION_TYPE)
                    145:     aggr_string = "union";
                    146:   else if (TYPE_LANG_SPECIFIC (t) && CLASSTYPE_DECLARED_CLASS (t))
                    147:     aggr_string = "class";
                    148:   else
                    149:     aggr_string = "struct";
                    150: 
                    151:   name = TYPE_NAME (t);
                    152: 
                    153:   if (TREE_CODE (name) == TYPE_DECL)
                    154:     {
                    155:       if (DECL_LANG_SPECIFIC (name) && DECL_CLASS_CONTEXT (name))
                    156:        context_string = TYPE_NAME_STRING (DECL_CLASS_CONTEXT (name));
                    157:       name = DECL_NAME (name);
                    158:     }
                    159: 
                    160:   obstack_grow (&scratch_obstack, aggr_string, strlen (aggr_string));
                    161:   OB_PUTC (' ');
                    162:   if (context_string)
                    163:     {
                    164:       obstack_grow (&scratch_obstack, context_string, strlen (context_string)-1);
                    165:       OB_PUTC2 (':', ':');
                    166:     }
                    167:   OB_PUTID (name);
                    168: }
                    169: 
                    170: /* This must be large enough to hold any anonymous parm name.  */
                    171: static char anon_buffer[sizeof (ANON_PARMNAME_FORMAT) + 20];
                    172: /* This must be large enough to hold any printed integer or floatingpoint value.  */
                    173: static char digit_buffer[128];
                    174: 
                    175: static void
                    176: dump_type_prefix (t, p)
                    177:      tree t;
                    178:      int *p;
                    179: {
                    180:   int old_p = 0;
                    181:   int print_struct = 1;
                    182:   tree name;
                    183: 
                    184:   if (t == NULL_TREE)
                    185:     return;
                    186: 
                    187:   switch (TREE_CODE (t))
                    188:     {
                    189:     case ERROR_MARK:
                    190:       sprintf (anon_buffer, ANON_PARMNAME_FORMAT, dummy_name++);
                    191:       OB_PUTCP (anon_buffer);
                    192:       break;
                    193: 
                    194:     case UNKNOWN_TYPE:
                    195:       OB_PUTS ("<unknown type>");
                    196:       return;
                    197: 
                    198:     case TREE_LIST:
                    199:       dump_type (TREE_VALUE (t), &old_p);
                    200:       if (TREE_CHAIN (t))
                    201:        {
                    202:          if (TREE_CHAIN (t) != void_list_node)
                    203:            {
                    204:              OB_PUTC (',');
                    205:              dump_type (TREE_CHAIN (t), &old_p);
                    206:            }
                    207:        }
                    208:       else OB_PUTS ("...");
                    209:       return;
                    210: 
                    211:     case POINTER_TYPE:
                    212:       *p += 1;
                    213:       dump_type_prefix (TREE_TYPE (t), p);
                    214:       while (*p)
                    215:        {
                    216:          OB_PUTC ('*');
                    217:          *p -= 1;
                    218:        }
                    219:       if (TYPE_READONLY (t))
                    220:        OB_PUTS ("const ");
                    221:       if (TYPE_VOLATILE (t))
                    222:        OB_PUTS ("volatile ");
                    223:       return;
                    224: 
                    225:     case OFFSET_TYPE:
                    226:       {
                    227:        tree type = TREE_TYPE (t);
                    228:        if (TREE_CODE (type) == FUNCTION_TYPE)
                    229:          {
                    230:            type = TREE_TYPE (type);
                    231:            if (in_parmlist)
                    232:              OB_PUTS ("auto ");
                    233:          }
                    234: 
                    235:        dump_type_prefix (type, &old_p);
                    236: 
                    237:        OB_PUTC ('(');
                    238:        dump_type (TYPE_OFFSET_BASETYPE (t), &old_p);
                    239:        OB_PUTC2 (':', ':');
                    240:        while (*p)
                    241:          {
                    242:            OB_PUTC ('*');
                    243:            *p -= 1;
                    244:          }
                    245:        if (TYPE_READONLY (t) | TYPE_VOLATILE (t))
                    246:          dump_readonly_or_volatile (t);
                    247:        return;
                    248:       }
                    249: 
                    250:     case METHOD_TYPE:
                    251:       {
                    252:        tree type = TREE_TYPE (t);
                    253:        if (in_parmlist)
                    254:          OB_PUTS ("auto ");
                    255: 
                    256:        dump_type_prefix (type, &old_p);
                    257: 
                    258:        OB_PUTC ('(');
                    259:        dump_type (TYPE_METHOD_BASETYPE (t), &old_p);
                    260:        OB_PUTC2 (':', ':');
                    261:        while (*p)
                    262:          {
                    263:            OB_PUTC ('*');
                    264:            *p -= 1;
                    265:          }
                    266:        if (TYPE_READONLY (t) | TYPE_VOLATILE (t))
                    267:          dump_readonly_or_volatile (t);
                    268:        return;
                    269:       }
                    270: 
                    271:     case REFERENCE_TYPE:
                    272:       dump_type_prefix (TREE_TYPE (t), p);
                    273:       OB_PUTC ('&');
                    274:       if (TYPE_READONLY (t) | TYPE_VOLATILE (t))
                    275:        dump_readonly_or_volatile (t);
                    276:       return;
                    277: 
                    278:     case ARRAY_TYPE:
                    279:       if (TYPE_READONLY (t) | TYPE_VOLATILE (t))
                    280:        dump_readonly_or_volatile (t);
                    281:       dump_type_prefix (TREE_TYPE (t), p);
                    282:       return;
                    283: 
                    284:     case FUNCTION_TYPE:
                    285:       if (in_parmlist)
                    286:        OB_PUTS ("auto ");
                    287:       dump_type_prefix (TREE_TYPE (t), &old_p);
                    288:       OB_PUTC ('(');
                    289:       while (*p)
                    290:        {
                    291:          OB_PUTC ('*');
                    292:          *p -= 1;
                    293:        }
                    294:       if (TYPE_READONLY (t) | TYPE_VOLATILE (t))
                    295:        dump_readonly_or_volatile (t);
                    296:       return;
                    297: 
                    298:     case IDENTIFIER_NODE:
                    299:       OB_PUTID (t);
                    300:       OB_PUTC (' ');
                    301:       break;
                    302: 
                    303:     case RECORD_TYPE:
                    304:     case UNION_TYPE:
                    305:     case ENUMERAL_TYPE:
                    306:       dump_aggr_type (t);
                    307:       break;
                    308: 
                    309:     case TYPE_DECL:
                    310:       if (TYPE_READONLY (t))
                    311:        OB_PUTS ("const ");
                    312:       if (TYPE_VOLATILE (t))
                    313:        OB_PUTS ("volatile ");
                    314:       OB_PUTID (DECL_NAME (t));
                    315:       OB_PUTC (' ');
                    316:       break;
                    317: 
                    318:     case INTEGER_TYPE:
                    319: #if 0
                    320:       /* Normally, `unsigned' is part of the deal.  Not so if it comes
                    321:         with `const' or `volatile'.  */
                    322:       if (TYPE_MAIN_VARIANT (t) == unsigned_type (TYPE_MAIN_VARIANT (t))
                    323:          && (TYPE_READONLY (t) || TYPE_VOLATILE (t)))
                    324:        OB_PUTS ("unsigned ");
                    325: #endif
                    326:       /* fall through.  */
                    327:     case REAL_TYPE:
                    328:     case VOID_TYPE:
                    329:       if (TYPE_READONLY (t))
                    330:        OB_PUTS ("const ");
                    331:       if (TYPE_VOLATILE (t))
                    332:        OB_PUTS ("volatile ");
                    333:       OB_PUTID (DECL_NAME (TYPE_NAME (t)));
                    334:       OB_PUTC (' ');
                    335:       break;
                    336: 
                    337:     default:
                    338:       abort ();
                    339:     }
                    340: }
                    341: 
                    342: static void
                    343: dump_type_suffix (t, p)
                    344:      tree t;
                    345:      int *p;
                    346: {
                    347:   int old_p = 0;
                    348: 
                    349:   if (t == NULL_TREE)
                    350:     return;
                    351: 
                    352:   switch (TREE_CODE (t))
                    353:     {
                    354:     case ERROR_MARK:
                    355:       sprintf (anon_buffer, ANON_PARMNAME_FORMAT, dummy_name++);
                    356:       OB_PUTCP (anon_buffer);
                    357:       break;
                    358: 
                    359:     case UNKNOWN_TYPE:
                    360:       return;
                    361: 
                    362:     case POINTER_TYPE:
                    363:       dump_type_suffix (TREE_TYPE (t), p);
                    364:       return;
                    365: 
                    366:     case OFFSET_TYPE:
                    367:       {
                    368:        tree type = TREE_TYPE (t);
                    369: 
                    370:        OB_PUTC (')');
                    371:        if (TREE_CODE (type) == FUNCTION_TYPE)
                    372:          {
                    373: #if 0
                    374:            tree next_arg = TREE_CHAIN (TYPE_ARG_TYPES (type));
                    375:            OB_PUTC ('(');
                    376:            if (next_arg)
                    377:              {
                    378:                if (next_arg != void_list_node)
                    379:                  {
                    380:                    in_parmlist++;
                    381:                    dump_type (next_arg, &old_p);
                    382:                    in_parmlist--;
                    383:                  }
                    384:              }
                    385:            else OB_PUTS ("...");
                    386:            OB_PUTC (')');
                    387:            dump_type_suffix (TREE_TYPE (type), p);
                    388: #else
                    389:            abort ();
                    390: #endif
                    391:          }
                    392:        return;
                    393:       }
                    394: 
                    395:     case METHOD_TYPE:
                    396:       {
                    397:        tree next_arg;
                    398:        OB_PUTC (')');
                    399:        next_arg = TREE_CHAIN (TYPE_ARG_TYPES (t));
                    400:        OB_PUTC ('(');
                    401:        if (next_arg)
                    402:          {
                    403:            if (next_arg != void_list_node)
                    404:              {
                    405:                in_parmlist++;
                    406:                dump_type (next_arg, &old_p);
                    407:                in_parmlist--;
                    408:              }
                    409:          }
                    410:        else OB_PUTS ("...");
                    411:        OB_PUTC (')');
                    412:        dump_readonly_or_volatile (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))));
                    413:        dump_type_suffix (TREE_TYPE (t), p);
                    414:        return;
                    415:       }
                    416: 
                    417:     case REFERENCE_TYPE:
                    418:       dump_type_suffix (TREE_TYPE (t), p);
                    419:       return;
                    420: 
                    421:     case ARRAY_TYPE:
                    422:       dump_type_suffix (TREE_TYPE (t), p);
                    423:       OB_PUTC2 ('[', ']');
                    424:       return;
                    425: 
                    426:     case FUNCTION_TYPE:
                    427:       OB_PUTC2 (')', '(');
                    428:       if (TYPE_ARG_TYPES (t) && TYPE_ARG_TYPES (t) != void_list_node)
                    429:        {
                    430:          in_parmlist++;
                    431:          dump_type (TYPE_ARG_TYPES (t), &old_p);
                    432:          in_parmlist--;
                    433:        }
                    434:       OB_PUTC (')');
                    435:       dump_type_suffix (TREE_TYPE (t), p);
                    436:       return;
                    437: 
                    438:     case IDENTIFIER_NODE:
                    439:     case RECORD_TYPE:
                    440:     case UNION_TYPE:
                    441:     case ENUMERAL_TYPE:
                    442:     case TYPE_DECL:
                    443:     case INTEGER_TYPE:
                    444:     case REAL_TYPE:
                    445:     case VOID_TYPE:
                    446:       return;
                    447: 
                    448:     default:
                    449:       abort ();
                    450:     }
                    451: }
                    452: 
                    453: static void
                    454: dump_type (t, p)
                    455:      tree t;
                    456:      int *p;
                    457: {
                    458:   int old_p = 0;
                    459:   int print_struct = 1;
                    460: 
                    461:   if (t == NULL_TREE)
                    462:     return;
                    463: 
                    464:   switch (TREE_CODE (t))
                    465:     {
                    466:     case ERROR_MARK:
                    467:       sprintf (anon_buffer, ANON_PARMNAME_FORMAT, dummy_name++);
                    468:       OB_PUTCP (anon_buffer);
                    469:       break;
                    470: 
                    471:     case UNKNOWN_TYPE:
                    472:       OB_PUTS ("<unknown type>");
                    473:       return;
                    474: 
                    475:     case TREE_LIST:
                    476:       dump_type (TREE_VALUE (t), &old_p);
                    477:       if (TREE_CHAIN (t))
                    478:        {
                    479:          if (TREE_CHAIN (t) != void_list_node)
                    480:            {
                    481:              OB_PUTC (',');
                    482:              dump_type (TREE_CHAIN (t), &old_p);
                    483:            }
                    484:        }
                    485:       else OB_PUTS ("...");
                    486:       return;
                    487: 
                    488:     case POINTER_TYPE:
                    489:       if (TYPE_READONLY (t) | TYPE_VOLATILE (t))
                    490:        dump_readonly_or_volatile (t);
                    491:       *p += 1;
                    492:       dump_type (TREE_TYPE (t), p);
                    493:       while (*p)
                    494:        {
                    495:          OB_PUTC ('*');
                    496:          *p -= 1;
                    497:        }
                    498:       return;
                    499: 
                    500:     case REFERENCE_TYPE:
                    501:       if (TYPE_READONLY (t) | TYPE_VOLATILE (t))
                    502:        dump_readonly_or_volatile (t);
                    503:       dump_type (TREE_TYPE (t), p);
                    504:       OB_PUTC ('&');
                    505:       return;
                    506: 
                    507:     case ARRAY_TYPE:
                    508:       if (TYPE_READONLY (t) | TYPE_VOLATILE (t))
                    509:        dump_readonly_or_volatile (t);
                    510:       dump_type (TREE_TYPE (t), p);
                    511:       OB_PUTC2 ('[', ']');
                    512:       return;
                    513: 
                    514:     case OFFSET_TYPE:
                    515:     case METHOD_TYPE:
                    516:     case FUNCTION_TYPE:
                    517:       dump_type_prefix (t, p);
                    518:       dump_type_suffix (t, p);
                    519:       return;
                    520: 
                    521:     case IDENTIFIER_NODE:
                    522:       OB_PUTID (t);
                    523:       OB_PUTC (' ');
                    524:       break;
                    525: 
                    526:     case RECORD_TYPE:
                    527:     case UNION_TYPE:
                    528:     case ENUMERAL_TYPE:
                    529:       dump_aggr_type (t);
                    530:       break;
                    531: 
                    532:     case TYPE_DECL:
                    533:       if (TYPE_READONLY (t) | TYPE_VOLATILE (t))
                    534:        dump_readonly_or_volatile (t);
                    535:       OB_PUTID (DECL_NAME (t));
                    536:       OB_PUTC (' ');
                    537:       break;
                    538: 
                    539:     case INTEGER_TYPE:
                    540:       /* Normally, `unsigned' is part of the deal.  Not so if it comes
                    541:         with `const' or `volatile'.  */
                    542:       if (TYPE_READONLY (t) | TYPE_VOLATILE (t))
                    543:        dump_readonly_or_volatile (t);
                    544: #if 0
                    545:       if (TYPE_MAIN_VARIANT (t) == unsigned_type (TYPE_MAIN_VARIANT (t))
                    546:          && (TYPE_READONLY (t) | TYPE_VOLATILE (t)))
                    547:        OB_PUTS ("unsigned ");
                    548: #endif
                    549:       OB_PUTID (DECL_NAME (TYPE_NAME (t)));
                    550:       OB_PUTC (' ');
                    551:       break;
                    552: 
                    553:     case REAL_TYPE:
                    554:     case VOID_TYPE:
                    555:       if (TYPE_READONLY (t) | TYPE_VOLATILE (t))
                    556:        dump_readonly_or_volatile (t);
                    557:       OB_PUTID (DECL_NAME (TYPE_NAME (t)));
                    558:       OB_PUTC (' ');
                    559:       break;
                    560: 
                    561:     case TEMPLATE_TYPE_PARM:
                    562:       OB_PUTS ("<template type parm ");
                    563:       OB_PUTID (DECL_NAME (TYPE_NAME (t)));
                    564:       OB_PUTC ('>');
                    565:       break;
                    566: 
                    567:     case UNINSTANTIATED_P_TYPE:
                    568:       OB_PUTID (DECL_NAME (UPT_TEMPLATE (t)));
                    569:       OB_PUTS ("<...>");
                    570:       break;
                    571: 
                    572:     default:
                    573:       abort ();
                    574:     }
                    575: }
                    576: 
                    577: static void
                    578: dump_decl (t)
                    579:      tree t;
                    580: {
                    581:   int p = 0;
                    582: 
                    583:   if (t == NULL_TREE)
                    584:     return;
                    585: 
                    586:   switch (TREE_CODE (t))
                    587:     {
                    588:     case ERROR_MARK:
                    589:       OB_PUTS (" /* decl error */ ");
                    590:       break;
                    591: 
                    592:     case PARM_DECL:
                    593:       dump_type_prefix (TREE_TYPE (t), &p);
                    594:       if (DECL_NAME (t))
                    595:        dump_decl (DECL_NAME (t));
                    596:       else
                    597:        {
                    598:          sprintf (anon_buffer, ANON_PARMNAME_FORMAT, dummy_name++);
                    599:          OB_PUTCP (anon_buffer);
                    600:          break;
                    601:        }
                    602:       dump_type_suffix (TREE_TYPE (t), &p);
                    603:       return;
                    604: 
                    605:     case CALL_EXPR:
                    606:       dump_decl (TREE_OPERAND (t, 0));
                    607:       OB_PUTC ('(');
                    608:       in_parmlist++;
                    609:       dump_decl (TREE_OPERAND (t, 1));
                    610:       in_parmlist--;
                    611:       t = tree_last (TYPE_ARG_TYPES (TREE_TYPE (t)));
                    612:       if (!t || t != void_list_node)
                    613:        OB_PUTS ("...");
                    614:       OB_PUTC (')');
                    615:       return;
                    616: 
                    617:     case ARRAY_REF:
                    618:       dump_decl (TREE_OPERAND (t, 0));
                    619:       OB_PUTC ('[');
                    620:       dump_decl (TREE_OPERAND (t, 1));
                    621:       OB_PUTC (']');
                    622:       return;
                    623: 
                    624:     case TYPE_DECL:
                    625:       OB_PUTID (DECL_NAME (t));
                    626:       OB_PUTC (' ');
                    627:       break;
                    628: 
                    629:     case TYPE_EXPR:
                    630:       abort ();
                    631:       break;
                    632: 
                    633:     case IDENTIFIER_NODE:
                    634:       if (t == ansi_opname[TYPE_EXPR])
                    635:        {
                    636:          OB_PUTS ("operator ");
                    637:          /* Not exactly IDENTIFIER_TYPE_VALUE.  */
                    638:          dump_type (TREE_TYPE (t), &p);
                    639:          return;
                    640:        }
                    641:       else if (IDENTIFIER_OPNAME_P (t))
                    642:        {
                    643:          char *name_string = operator_name_string (t);
                    644:          OB_PUTS ("operator ");
                    645:          OB_PUTCP (name_string);
                    646:          OB_PUTC (' ');
                    647:        }
                    648:       else
                    649:        {
                    650:          OB_PUTID (t);
                    651:          OB_PUTC (' ');
                    652:        }
                    653:       break;
                    654: 
                    655:     case BIT_NOT_EXPR:
                    656:       OB_PUTC2 ('~', ' ');
                    657:       dump_decl (TREE_OPERAND (t, 0));
                    658:       return;
                    659: 
                    660:     case SCOPE_REF:
                    661:       OB_PUTID (TREE_OPERAND (t, 0));
                    662:       OB_PUTC2 (':', ':');
                    663:       dump_decl (TREE_OPERAND (t, 1));
                    664:       return;
                    665: 
                    666:     case INDIRECT_REF:
                    667:       OB_PUTC ('*');
                    668:       dump_decl (TREE_OPERAND (t, 0));
                    669:       return;
                    670: 
                    671:     case ADDR_EXPR:
                    672:       OB_PUTC ('&');
                    673:       dump_decl (TREE_OPERAND (t, 0));
                    674:       return;
                    675: 
                    676:     default:
                    677:       abort ();
                    678:     }
                    679: }
                    680: 
                    681: static void
                    682: dump_init_list (l)
                    683:      tree l;
                    684: {
                    685:   while (l)
                    686:     {
                    687:       dump_init (TREE_VALUE (l));
                    688:       if (TREE_CHAIN (l))
                    689:        OB_PUTC (',');
                    690:       l = TREE_CHAIN (l);
                    691:     }
                    692: }
                    693: 
                    694: static void
                    695: dump_init (t)
                    696:      tree t;
                    697: {
                    698:   int dummy;
                    699: 
                    700:   switch (TREE_CODE (t))
                    701:     {
                    702:     case VAR_DECL:
                    703:     case PARM_DECL:
                    704:       OB_PUTC (' ');
                    705:       OB_PUTID (DECL_NAME (t));
                    706:       OB_PUTC (' ');
                    707:       break;
                    708: 
                    709:     case FUNCTION_DECL:
                    710:       {
                    711:        tree name = DECL_ASSEMBLER_NAME (t);
                    712: 
                    713:        if (DESTRUCTOR_NAME_P (name))
                    714:          {
                    715:            OB_PUTC2 (' ', '~');
                    716:            OB_PUTID (DECL_NAME (t));
                    717:          }
                    718:        else if (IDENTIFIER_TYPENAME_P (name))
                    719:          {
                    720:            dummy = 0;
                    721:            OB_PUTS ("operator ");
                    722:            dump_type (TREE_TYPE (name), &dummy);
                    723:          }
                    724:        else if (IDENTIFIER_OPNAME_P (name))
                    725:          {
                    726:            char *name_string = operator_name_string (name);
                    727:              OB_PUTS ("operator ");
                    728:            OB_PUTCP (name_string);
                    729:            OB_PUTC (' ');
                    730:          }
                    731: #if 0
                    732:        else if (WRAPPER_NAME_P (name))
                    733:          sprintf (inline_bufp, " ()%s", IDENTIFIER_POINTER (DECL_NAME (t)));
                    734:        else if (WRAPPER_PRED_NAME_P (name))
                    735:          sprintf (inline_bufp, " ()?%s", IDENTIFIER_POINTER (DECL_NAME (t)));
                    736:        else if (ANTI_WRAPPER_NAME_P (name))
                    737:          sprintf (inline_bufp, " ~()%s", IDENTIFIER_POINTER (DECL_NAME (t)));
                    738: #endif
                    739:        else
                    740:          {
                    741:            OB_PUTC (' ');
                    742:            OB_PUTID (DECL_NAME (t));
                    743:          }
                    744:        OB_PUTC (' ');
                    745:       }
                    746:       break;
                    747: 
                    748:     case CONST_DECL:
                    749:       dummy = 0;
                    750:       OB_PUTC2 ('(', '(');
                    751:       dump_type (TREE_TYPE (t), &dummy);
                    752:       OB_PUTC (')');
                    753:       dump_init (DECL_INITIAL (t));
                    754:       OB_PUTC (')');
                    755:       return;
                    756: 
                    757:     case INTEGER_CST:
                    758:       sprintf (digit_buffer, " %d ", TREE_INT_CST_LOW (t));
                    759:       OB_PUTCP (digit_buffer);
                    760:       break;
                    761: 
                    762:     case REAL_CST:
                    763:       sprintf (digit_buffer, " %g ", TREE_REAL_CST (t));
                    764:       OB_PUTCP (digit_buffer);
                    765:       break;
                    766: 
                    767:     case STRING_CST:
                    768:       {
                    769:        char *p = TREE_STRING_POINTER (t);
                    770:        int len = TREE_STRING_LENGTH (t) - 1;
                    771:        int i;
                    772: 
                    773:        OB_PUTC ('\"');
                    774:        for (i = 0; i < len; i++)
                    775:          {
                    776:            register char c = p[i];
                    777:            if (c == '\"' || c == '\\')
                    778:              OB_PUTC ('\\');
                    779:            if (c >= ' ' && c < 0177)
                    780:              OB_PUTC (c);
                    781:            else
                    782:              {
                    783:                sprintf (digit_buffer, "\\%03o", c);
                    784:                OB_PUTCP (digit_buffer);
                    785:              }
                    786:          }
                    787:        OB_PUTC ('\"');
                    788:       }
                    789:       return;
                    790: 
                    791:     case COMPOUND_EXPR:
                    792:       dump_binary_op (",", t, 1);
                    793:       break;
                    794: 
                    795:     case COND_EXPR:
                    796:       OB_PUTC ('(');
                    797:       dump_init (TREE_OPERAND (t, 0));
                    798:       OB_PUTS (" ? ");
                    799:       dump_init (TREE_OPERAND (t, 1));
                    800:       OB_PUTS (" : ");
                    801:       dump_init (TREE_OPERAND (t, 2));
                    802:       OB_PUTC (')');
                    803:       return;
                    804: 
                    805:     case SAVE_EXPR:
                    806:       if (TREE_HAS_CONSTRUCTOR (t))
                    807:        {
                    808:          dummy = 0;
                    809:          OB_PUTS ("new ");
                    810:          dump_type (TREE_TYPE (TREE_TYPE (t)), &dummy);
                    811:          PARM_DECL_EXPR (t) = 1;
                    812:        }
                    813:       else
                    814:        {
                    815:          sorry ("operand of SAVE_EXPR not understood");
                    816:          scratch_obstack.next_free
                    817:            = obstack_base (&scratch_obstack) + scratch_error_offset;
                    818:        }
                    819:       return;
                    820: 
                    821:     case NEW_EXPR:
                    822:       OB_PUTID (DECL_NAME (TYPE_NAME (TREE_TYPE (t))));
                    823:       OB_PUTC ('(');
                    824:       dump_init_list (TREE_CHAIN (TREE_OPERAND (t, 1)));
                    825:       OB_PUTC (')');
                    826:       return;
                    827: 
                    828:     case CALL_EXPR:
                    829:       OB_PUTC ('(');
                    830:       dump_init (TREE_OPERAND (t, 0));
                    831:       dump_init_list (TREE_OPERAND (t, 1));
                    832:       OB_PUTC (')');
                    833:       return;
                    834: 
                    835:     case WITH_CLEANUP_EXPR:
                    836:       /* Note that this only works for G++ cleanups.  If somebody
                    837:         builds a general cleanup, there's no way to represent it.  */
                    838:       dump_init (TREE_OPERAND (t, 0));
                    839:       return;
                    840: 
                    841:     case TARGET_EXPR:
                    842:       /* Note that this only works for G++ target exprs.  If somebody
                    843:         builds a general TARGET_EXPR, there's no way to represent that
                    844:         it initializes anything other that the parameter slot for the
                    845:         default argument.  */
                    846:       dump_init (TREE_OPERAND (t, 1));
                    847:       return;
                    848: 
                    849:     case MODIFY_EXPR:
                    850:     case PLUS_EXPR:
                    851:     case MINUS_EXPR:
                    852:     case MULT_EXPR:
                    853:     case TRUNC_DIV_EXPR:
                    854:     case TRUNC_MOD_EXPR:
                    855:     case MIN_EXPR:
                    856:     case MAX_EXPR:
                    857:     case LSHIFT_EXPR:
                    858:     case RSHIFT_EXPR:
                    859:     case BIT_IOR_EXPR:
                    860:     case BIT_XOR_EXPR:
                    861:     case BIT_AND_EXPR:
                    862:     case BIT_ANDTC_EXPR:
                    863:     case TRUTH_ANDIF_EXPR:
                    864:     case TRUTH_ORIF_EXPR:
                    865:     case LT_EXPR:
                    866:     case LE_EXPR:
                    867:     case GT_EXPR:
                    868:     case GE_EXPR:
                    869:     case EQ_EXPR:
                    870:     case NE_EXPR:
                    871:       dump_binary_op (opname_tab[(int) TREE_CODE (t)], t,
                    872:                      strlen (opname_tab[(int) TREE_CODE (t)]));
                    873:       return;
                    874: 
                    875:     case CEIL_DIV_EXPR:
                    876:     case FLOOR_DIV_EXPR:
                    877:     case ROUND_DIV_EXPR:
                    878:       dump_binary_op ("/", t, 1);
                    879:       return;
                    880: 
                    881:     case CEIL_MOD_EXPR:
                    882:     case FLOOR_MOD_EXPR:
                    883:     case ROUND_MOD_EXPR:
                    884:       dump_binary_op ("%", t, 1);
                    885:       return;
                    886: 
                    887:     case COMPONENT_REF:
                    888:       dump_binary_op (".", t, 1);
                    889:       return;
                    890: 
                    891:     case CONVERT_EXPR:
                    892:       dump_unary_op ("+", t, 1);
                    893:       return;
                    894: 
                    895:     case ADDR_EXPR:
                    896:       if (TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
                    897:          || TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST)
                    898:        dump_init (TREE_OPERAND (t, 0));
                    899:       else
                    900:        dump_unary_op ("&", t, 1);
                    901:       return;
                    902: 
                    903:     case INDIRECT_REF:
                    904:       dump_unary_op ("*", t, 1);
                    905:       return;
                    906: 
                    907:     case NEGATE_EXPR:
                    908:     case BIT_NOT_EXPR:
                    909:     case TRUTH_NOT_EXPR:
                    910:     case PREDECREMENT_EXPR:
                    911:     case PREINCREMENT_EXPR:
                    912:       dump_unary_op (opname_tab [(int)TREE_CODE (t)], t,
                    913:                     strlen (opname_tab[(int) TREE_CODE (t)]));
                    914:       return;
                    915: 
                    916:     case POSTDECREMENT_EXPR:
                    917:     case POSTINCREMENT_EXPR:
                    918:       OB_PUTC ('(');
                    919:       dump_init (TREE_OPERAND (t, 0));
                    920:       OB_PUTCP (opname_tab[(int)TREE_CODE (t)]);
                    921:       OB_PUTC (')');
                    922:       return;
                    923: 
                    924:     case NOP_EXPR:
                    925:       dummy = 0;
                    926:       OB_PUTC2 ('(', '(');
                    927:       dump_type (TREE_TYPE (t), &dummy);
                    928:       OB_PUTC (')');
                    929:       dump_init (TREE_OPERAND (t, 0));
                    930:       OB_PUTC (')');
                    931:       return;
                    932: 
                    933:     case CONSTRUCTOR:
                    934:       OB_PUTC ('{');
                    935:       dump_init_list (CONSTRUCTOR_ELTS (t));
                    936:       OB_PUTC ('}');
                    937:       return;
                    938: 
                    939:       /*  This list is incomplete, but should suffice for now.
                    940:          It is very important that `sorry' does not call
                    941:          `report_error_function'.  That could cause an infinite loop.  */
                    942:     default:
                    943:       sorry ("`%s' not supported for default parameters",
                    944:             tree_code_name[(int) TREE_CODE (t)]);
                    945: 
                    946:       /* fall through to ERROR_MARK...  */
                    947:     case ERROR_MARK:
                    948:       scratch_obstack.next_free
                    949:        = obstack_base (&scratch_obstack) + scratch_error_offset;
                    950:       return;
                    951:     }
                    952: }
                    953: 
                    954: static void
                    955: dump_binary_op (opstring, t, len)
                    956:      char *opstring;
                    957:      tree t;
                    958:      int len;
                    959: {
                    960:   OB_PUTC ('(');
                    961:   dump_init (TREE_OPERAND (t, 0));
                    962:   OB_PUTC (' ');
                    963:   OB_PUTCP (opstring);
                    964:   OB_PUTC (' ');
                    965:   dump_init (TREE_OPERAND (t, 1));
                    966:   OB_PUTC (')');
                    967: }
                    968: 
                    969: static void
                    970: dump_unary_op (opstring, t, len)
                    971:      char *opstring;
                    972:      tree t;
                    973:      int len;
                    974: {
                    975:   OB_PUTC ('(');
                    976:   OB_PUTC (' ');
                    977:   OB_PUTCP (opstring);
                    978:   OB_PUTC (' ');
                    979:   dump_init (TREE_OPERAND (t, 0));
                    980:   OB_PUTC (')');
                    981: }
                    982: 
                    983: /* Pretty printing for announce_function.  CNAME is the TYPE_DECL for
                    984:    the class that FNDECL belongs to, if we could not figure that out
                    985:    from FNDECL itself.  FNDECL is the declaration of the function we
                    986:    are interested in seeing.  PRINT_RET_TYPE_P is non-zero if we
                    987:    should print the type that this function returns.  */
                    988: 
                    989: char *
                    990: fndecl_as_string (cname, fndecl, print_ret_type_p)
                    991:      tree cname, fndecl;
                    992:      int print_ret_type_p;
                    993: {
                    994:   tree name = DECL_ASSEMBLER_NAME (fndecl);
                    995:   tree fntype = TREE_TYPE (fndecl);
                    996:   tree parmtypes = TYPE_ARG_TYPES (fntype);
                    997:   int p = 0;
                    998:   int spaces = 0;
                    999: 
                   1000:   OB_INIT ();
                   1001: 
                   1002:   if (DECL_CLASS_CONTEXT (fndecl))
                   1003:     cname = TYPE_NAME (DECL_CLASS_CONTEXT (fndecl));
                   1004: 
                   1005:   if (print_ret_type_p && ! IDENTIFIER_TYPENAME_P (name))
                   1006:     {
                   1007:       dump_type_prefix (TREE_TYPE (fntype), &p);
                   1008:       OB_PUTC (' ');
                   1009:     }
                   1010:   if (DECL_STATIC_FUNCTION_P (fndecl))
                   1011:       OB_PUTS ("static ");
                   1012:     
                   1013:   if (cname)
                   1014:     {
                   1015:       dump_type (cname, &p);
                   1016:       *((char *) obstack_next_free (&scratch_obstack) - 1) = ':';
                   1017:       OB_PUTC (':');
                   1018:       if (TREE_CODE (fntype) == METHOD_TYPE && parmtypes)
                   1019:        parmtypes = TREE_CHAIN (parmtypes);
                   1020:       if (DECL_CONSTRUCTOR_FOR_VBASE_P (fndecl))
                   1021:        /* Skip past "in_charge" identifier.  */
                   1022:        parmtypes = TREE_CHAIN (parmtypes);
                   1023:     }
                   1024: 
                   1025:   if (DESTRUCTOR_NAME_P (name))
                   1026:     {
                   1027:       OB_PUTC ('~');
                   1028:       parmtypes = TREE_CHAIN (parmtypes);
                   1029:       dump_decl (DECL_NAME (fndecl));
                   1030:     }
                   1031:   else if (IDENTIFIER_TYPENAME_P (name))
                   1032:     {
                   1033:       /* This cannot use the hack that the operator's return
                   1034:         type is stashed off of its name because it may be
                   1035:         used for error reporting.  In the case of conflicting
                   1036:         declarations, both will have the same name, yet
                   1037:         the types will be different, hence the TREE_TYPE field
                   1038:         of the first name will be clobbered by the second.  */
                   1039:       OB_PUTS ("operator ");
                   1040:       dump_type (TREE_TYPE (TREE_TYPE (fndecl)), &p);
                   1041:     }
                   1042:   else if (IDENTIFIER_OPNAME_P (name))
                   1043:     {
                   1044:       char *name_string = operator_name_string (name);
                   1045:       OB_PUTS ("operator ");
                   1046:       OB_PUTCP (name_string);
                   1047:       OB_PUTC (' ');
                   1048:     }
                   1049:   else if (DECL_CONSTRUCTOR_P (fndecl))
                   1050:     {
                   1051: #ifdef SOS
                   1052:       if (TYPE_DYNAMIC (IDENTIFIER_TYPE_VALUE (cname)))
                   1053:        {
                   1054:          OB_PUTS ("dynamic ");
                   1055:          parmtypes = TREE_CHAIN (parmtypes);
                   1056:        }
                   1057: #endif
                   1058:       dump_decl (DECL_NAME (fndecl));
                   1059:     }
                   1060:   else
                   1061:     {
                   1062: #if 0
                   1063:       if (WRAPPER_NAME_P (name))
                   1064:        OB_PUTC2 ('(', ')');
                   1065:       if (WRAPPER_PRED_NAME_P (name))
                   1066:        OB_PUTS ("()?");
                   1067:       else if (ANTI_WRAPPER_NAME_P (name))
                   1068:        OB_PUTS ("~()");
                   1069: #endif
                   1070:       dump_decl (DECL_NAME (fndecl));
                   1071:     }
                   1072: 
                   1073:   OB_PUTC ('(');
                   1074:   if (parmtypes)
                   1075:     {
                   1076:       in_parmlist++;
                   1077:       if (parmtypes != void_list_node)
                   1078:        spaces = 2;
                   1079:       while (parmtypes && parmtypes != void_list_node)
                   1080:        {
                   1081:          char *last_space;
                   1082:          dump_type (TREE_VALUE (parmtypes), &p);
                   1083:          last_space = (char *)obstack_next_free (&scratch_obstack);
                   1084:          while (last_space[-1] == ' ')
                   1085:            last_space--;
                   1086:          scratch_obstack.next_free = last_space;
                   1087:          if (TREE_PURPOSE (parmtypes))
                   1088:            {
                   1089:              scratch_error_offset = obstack_object_size (&scratch_obstack);
                   1090:              OB_PUTS (" (= ");
                   1091:              dump_init (TREE_PURPOSE (parmtypes));
                   1092:              OB_PUTC (')');
                   1093:            }
                   1094:          OB_PUTC2 (',', ' ');
                   1095:          parmtypes = TREE_CHAIN (parmtypes);
                   1096:        }
                   1097:       in_parmlist--;
                   1098:     }
                   1099:   
                   1100:   if (parmtypes)
                   1101:     {
                   1102:       if (spaces)
                   1103:        scratch_obstack.next_free = obstack_next_free (&scratch_obstack)-spaces;
                   1104:     }
                   1105:   else
                   1106:     OB_PUTS ("...");
                   1107: 
                   1108:   OB_PUTC (')');
                   1109: 
                   1110:   if (print_ret_type_p && ! IDENTIFIER_TYPENAME_P (name))
                   1111:     dump_type_suffix (TREE_TYPE (fntype), &p);
                   1112: 
                   1113:   if (TREE_CODE (fntype) == METHOD_TYPE)
                   1114:     dump_readonly_or_volatile (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))));
                   1115: 
                   1116:   OB_FINISH ();
                   1117:   
                   1118:   return (char *)obstack_base (&scratch_obstack);
                   1119: }
                   1120: 
                   1121: /* Same, but handtype a _TYPE.  */
                   1122: char *
                   1123: type_as_string (buf, typ)
                   1124:      char *buf;
                   1125:      tree typ;
                   1126: {
                   1127:   int p = 0;
                   1128:   int spaces = 0;
                   1129: 
                   1130:   OB_INIT ();
                   1131: 
                   1132:   dump_type(typ,&p);
                   1133: 
                   1134:   OB_FINISH ();
                   1135: 
                   1136:   return (char *)obstack_base (&scratch_obstack);
                   1137: }
                   1138: 
                   1139: /* Move inline function defintions out of structure so that they
                   1140:    can be processed normally.  CNAME is the name of the class
                   1141:    we are working from, METHOD_LIST is the list of method lists
                   1142:    of the structure.  We delete friend methods here, after
                   1143:    saving away their inline function definitions (if any).  */
                   1144: 
                   1145: void
                   1146: do_inline_function_hair (type, friend_list)
                   1147:      tree type, friend_list;
                   1148: {
                   1149:   tree cname = TYPE_IDENTIFIER (type);
                   1150:   tree method = TYPE_METHODS (type);
                   1151: 
                   1152:   if (method && TREE_CODE (method) == TREE_VEC)
                   1153:     {
                   1154:       if (TREE_VEC_ELT (method, 0))
                   1155:        method = TREE_VEC_ELT (method, 0);
                   1156:       else
                   1157:        method = TREE_VEC_ELT (method, 1);
                   1158:     }
                   1159: 
                   1160:   while (method)
                   1161:     {
                   1162:       /* Do inline member functions.  */
                   1163:       struct pending_inline *info = DECL_PENDING_INLINE_INFO (method);
                   1164:       if (info)
                   1165:        {
                   1166:          tree args;
                   1167: 
                   1168:          assert (info->fndecl == method);
                   1169:          args = DECL_ARGUMENTS (method);
                   1170:          while (args)
                   1171:            {
                   1172:              DECL_CONTEXT (args) = method;
                   1173:              args = TREE_CHAIN (args);
                   1174:            }
                   1175: 
                   1176:          /* Allow this decl to be seen in global scope */
                   1177:          IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (method)) = method;
                   1178:        }
                   1179:       method = TREE_CHAIN (method);
                   1180:     }
                   1181:   while (friend_list)
                   1182:     {
                   1183:       tree fndecl = TREE_VALUE (friend_list);
                   1184:       struct pending_inline *info = DECL_PENDING_INLINE_INFO (fndecl);
                   1185:       if (info)
                   1186:        {
                   1187:          tree args;
                   1188: 
                   1189:          assert (info->fndecl == fndecl);
                   1190:          args = DECL_ARGUMENTS (fndecl);
                   1191:          while (args)
                   1192:            {
                   1193:              DECL_CONTEXT (args) = fndecl;
                   1194:              args = TREE_CHAIN (args);
                   1195:            }
                   1196: 
                   1197:          /* Allow this decl to be seen in global scope */
                   1198:          IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (fndecl)) = fndecl;
                   1199:        }
                   1200: 
                   1201:       friend_list = TREE_CHAIN (friend_list);
                   1202:     }
                   1203: }
                   1204: 
                   1205: /* Report a argument type mismatch between the best declared function
                   1206:    we could find and the current argument list that we have.  */
                   1207: void
                   1208: report_type_mismatch (cp, parmtypes, name_kind, err_name)
                   1209:      struct candidate *cp;
                   1210:      tree parmtypes;
                   1211:      char *name_kind, *err_name;
                   1212: {
                   1213:   int i = cp->u.bad_arg;
                   1214:   tree ttf, tta;
                   1215:   char *tmp_firstobj;
                   1216: 
                   1217:   switch (i)
                   1218:     {
                   1219:     case -4:
                   1220:       assert (TREE_CODE (cp->function) == TEMPLATE_DECL);
                   1221:       error ("type unification failed for function template `%s'", err_name);
                   1222:       return;
                   1223: 
                   1224:     case -3:
                   1225:       if (TYPE_READONLY (TREE_TYPE (TREE_VALUE (parmtypes))))
                   1226:        error ("call to const %s `%s' with non-const object", name_kind, err_name);
                   1227:       else
                   1228:        error ("call to non-const %s `%s' with const object", name_kind, err_name);
                   1229:       return;
                   1230:     case -2:
                   1231:       error ("too few arguments for %s `%s'", name_kind, err_name);
                   1232:       return;
                   1233:     case -1:
                   1234:       error ("too many arguments for %s `%s'", name_kind, err_name);
                   1235:       return;
                   1236:     case 0:
                   1237:       if (TREE_CODE (TREE_TYPE (cp->function)) == METHOD_TYPE)
                   1238:        {
                   1239:          /* Happens when we have an ambiguous base class.  */
                   1240:          assert (get_binfo (DECL_CLASS_CONTEXT (cp->function),
                   1241:                             TREE_TYPE (TREE_TYPE (TREE_VALUE (parmtypes))), 1) == error_mark_node);
                   1242:          return;
                   1243:        }
                   1244:     }
                   1245: 
                   1246:   ttf = TYPE_ARG_TYPES (TREE_TYPE (cp->function));
                   1247:   tta = parmtypes;
                   1248: 
                   1249:   while (i-- > 0)
                   1250:     {
                   1251:       ttf = TREE_CHAIN (ttf);
                   1252:       tta = TREE_CHAIN (tta);
                   1253:     }
                   1254: 
                   1255:   OB_INIT ();
                   1256:   OB_PUTS ("bad argument ");
                   1257:   sprintf (digit_buffer, "%d",
                   1258:           cp->u.bad_arg - (TREE_CODE (TREE_TYPE (cp->function)) == METHOD_TYPE));
                   1259:   OB_PUTCP (digit_buffer);
                   1260:   OB_PUTS (" for function `");
                   1261: 
                   1262:   tmp_firstobj = scratch_firstobj;
                   1263:   scratch_firstobj = 0;
                   1264:   fndecl_as_string (0, cp->function, 0);
                   1265:   scratch_firstobj = tmp_firstobj;
                   1266: 
                   1267:   /* We know that the last char written is next_free-1.  */
                   1268:   ((char *) obstack_next_free (&scratch_obstack))[-1] = '\'';
                   1269:   OB_PUTS (" (type was ");
                   1270: 
                   1271:   /* Reset `i' so that type printing routines do the right thing.  */
                   1272:   if (tta)
                   1273:     {
                   1274:       enum tree_code code = TREE_CODE (TREE_TYPE (TREE_VALUE (tta)));
                   1275:       if (code == ERROR_MARK)
                   1276:        OB_PUTS ("(failed type instatiation)");
                   1277:       else
                   1278:        {
                   1279:          i = (code == FUNCTION_TYPE || code == METHOD_TYPE);
                   1280:          dump_type (TREE_TYPE (TREE_VALUE (tta)), &i);
                   1281:        }
                   1282:     }
                   1283:   else OB_PUTS ("void");
                   1284:   OB_PUTC (')');
                   1285:   OB_FINISH ();
                   1286: 
                   1287:   tmp_firstobj = (char *)alloca (obstack_object_size (&scratch_obstack));
                   1288:   bcopy (obstack_base (&scratch_obstack), tmp_firstobj,
                   1289:         obstack_object_size (&scratch_obstack));
                   1290:   error (tmp_firstobj);
                   1291: }
                   1292: 
                   1293: /* Here is where overload code starts.  */
                   1294: 
                   1295: /* Array of types seen so far in top-level call to `build_overload_name'.
                   1296:    Allocated and deallocated by caller.  */
                   1297: static tree *typevec;
                   1298: 
                   1299: /* Number of types interned by `build_overload_name' so far.  */
                   1300: static int maxtype;
                   1301: 
                   1302: /* Number of occurances of last type seen.  */
                   1303: static int nrepeats;
                   1304: 
                   1305: /* Nonzero if we should not try folding parameter types.  */
                   1306: static int nofold;
                   1307: 
                   1308: #define ALLOCATE_TYPEVEC(PARMTYPES) \
                   1309:   do { maxtype = 0, nrepeats = 0; \
                   1310:        typevec = (tree *)alloca (list_length (PARMTYPES) * sizeof (tree)); } while (0)
                   1311: 
                   1312: #define DEALLOCATE_TYPEVEC(PARMTYPES) \
                   1313:   do { tree t = (PARMTYPES); \
                   1314:        while (t) { TREE_USED (TREE_VALUE (t)) = 0; t = TREE_CHAIN (t); } \
                   1315:   } while (0)
                   1316: 
                   1317: /* Code to concatenate an asciified integer to a string,
                   1318:    and return the end of the string.  */
                   1319: static
                   1320: #ifdef __GNUC__
                   1321: __inline
                   1322: #endif
                   1323: char *
                   1324: icat (i)
                   1325:      int i;
                   1326: {
                   1327:   if (i < 0)
                   1328:     {
                   1329:       OB_PUTC ('m');
                   1330:       i = -i;
                   1331:     }
                   1332:   if (i < 10)
                   1333:     OB_PUTC ('0' + i);
                   1334:   else
                   1335:     {
                   1336:       icat (i / 10);
                   1337:       OB_PUTC ('0' + (i % 10));
                   1338:     }
                   1339: }
                   1340: 
                   1341: static
                   1342: #ifdef __GNUC__
                   1343: __inline
                   1344: #endif
                   1345: void
                   1346: flush_repeats (type)
                   1347:      tree type;
                   1348: {
                   1349:   int tindex = 0;
                   1350:   char *rval;
                   1351: 
                   1352:   while (typevec[tindex] != type)
                   1353:     tindex++;
                   1354: 
                   1355:   if (nrepeats > 1)
                   1356:     {
                   1357:       OB_PUTC ('N');
                   1358:       icat (nrepeats);
                   1359:       if (nrepeats > 9)
                   1360:        OB_PUTC ('_');
                   1361:     }
                   1362:   else
                   1363:     OB_PUTC ('T');
                   1364:   nrepeats = 0;
                   1365:   icat (tindex);
                   1366:   if (tindex > 9)
                   1367:     OB_PUTC ('_');
                   1368: }
                   1369: 
                   1370: static void build_overload_identifier ();
                   1371: 
                   1372: static void
                   1373: build_overload_nested_name (context)
                   1374:      tree context;
                   1375: {
                   1376:   tree name = DECL_ASSEMBLER_NAME (context);
                   1377:   if (DECL_CONTEXT (context))
                   1378:     {
                   1379:       context = DECL_CONTEXT (context);
                   1380:       if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')
                   1381:        context = TYPE_NAME (context);
                   1382:       build_overload_nested_name (context);
                   1383:     }
                   1384:   build_overload_identifier (name);
                   1385: }
                   1386: 
                   1387: static void
                   1388: build_overload_value (type, value)
                   1389:      tree type, value;
                   1390: {
                   1391:   char buf[40];
                   1392:   while (TREE_CODE (value) == NON_LVALUE_EXPR)
                   1393:     value = TREE_OPERAND (value, 0);
                   1394:   assert (TREE_CODE (type) == PARM_DECL);
                   1395:   type = TREE_TYPE (type);
                   1396:   switch (TREE_CODE (type))
                   1397:     {
                   1398:     case INTEGER_TYPE:
                   1399:     case ENUMERAL_TYPE:
                   1400:       {
                   1401:        assert (TREE_CODE (value) == INTEGER_CST);
                   1402:        if (TYPE_MODE (value) == DImode)
                   1403:          {
                   1404:            if (tree_int_cst_lt (value, integer_zero_node))
                   1405:              {
                   1406:                OB_PUTC ('m');
                   1407:                value = build_int_2 (~ TREE_INT_CST_LOW (value),
                   1408:                                     - TREE_INT_CST_HIGH (value));
                   1409:              }
                   1410:            if (TREE_INT_CST_HIGH (value) != (TREE_INT_CST_LOW (value) >> 31))
                   1411:              {
                   1412:                /* need to print a DImode value in decimal */
                   1413:                sorry ("conversion of long long as PT parameter");
                   1414:              }
                   1415:            /* else fall through to print in smaller mode */
                   1416:          }
                   1417:        /* SImode or smaller */
                   1418:        icat (TREE_INT_CST_LOW (value));
                   1419:        return;
                   1420:       }
                   1421: #ifndef REAL_IS_NOT_DOUBLE
                   1422:     case REAL_TYPE:
                   1423:       {
                   1424:        REAL_VALUE_TYPE val;
                   1425:        char *bufp = digit_buffer;
                   1426: 
                   1427:        assert (TREE_CODE (value) == REAL_CST);
                   1428:        val = TREE_REAL_CST (value);
                   1429:        if (val < 0)
                   1430:          {
                   1431:            val = -val;
                   1432:            *bufp++ = 'm';
                   1433:          }
                   1434:        sprintf (bufp, "%e", val);
                   1435:        bufp = strchr (bufp, 'e');
                   1436:        if (!bufp)
                   1437:          strcat (buf, "e0");
                   1438:        else
                   1439:          {
                   1440:            char *p;
                   1441:            bufp++;
                   1442:            if (*bufp == '-')
                   1443:              {
                   1444:                *bufp++ = 'm';
                   1445:              }
                   1446:            p = bufp;
                   1447:            if (*p == '+')
                   1448:              p++;
                   1449:            while (*p == '0')
                   1450:              p++;
                   1451:            if (*p == 0)
                   1452:              {
                   1453:                *bufp++ = '0';
                   1454:                *bufp = 0;
                   1455:              }
                   1456:            else if (p != bufp)
                   1457:              {
                   1458:                while (*p)
                   1459:                  *bufp++ = *p++;
                   1460:                *bufp = 0;
                   1461:              }
                   1462:          }
                   1463:        OB_PUTCP (buf);
                   1464:        return;
                   1465:       }
                   1466: #endif
                   1467:     case POINTER_TYPE:
                   1468:       value = TREE_OPERAND (value, 0);
                   1469:       if (TREE_CODE (value) == VAR_DECL)
                   1470:        {
                   1471:          assert (DECL_NAME (value) != 0);
                   1472:          build_overload_identifier (DECL_NAME (value));
                   1473:          return;
                   1474:        }
                   1475:       else
                   1476:        {
                   1477:          debug_tree (type);
                   1478:          debug_tree (value);
                   1479:          abort ();
                   1480:        }
                   1481:     default:
                   1482:       sorry ("conversion of %s as PT parameter",
                   1483:             tree_code_name [(int) TREE_CODE (type)]);
                   1484:       abort ();
                   1485:     }
                   1486: }
                   1487: 
                   1488: static void
                   1489: build_overload_identifier (name)
                   1490:      tree name;
                   1491: {
                   1492:   if (IDENTIFIER_TEMPLATE (name))
                   1493:     {
                   1494:       tree template, parmlist, arglist, tname;
                   1495:       int i, nparms;
                   1496:       template = IDENTIFIER_TEMPLATE (name);
                   1497:       arglist = TREE_VALUE (template);
                   1498:       template = TREE_PURPOSE (template);
                   1499:       tname = DECL_NAME (template);
                   1500:       parmlist = DECL_ARGUMENTS (template);
                   1501:       nparms = TREE_VEC_LENGTH (parmlist);
                   1502:       OB_PUTC ('t');
                   1503:       icat (IDENTIFIER_LENGTH (tname));
                   1504:       OB_PUTID (tname);
                   1505:       icat (nparms);
                   1506:       for (i = 0; i < nparms; i++)
                   1507:        {
                   1508:          tree parm = TREE_VEC_ELT (parmlist, i);
                   1509:          tree arg = TREE_VEC_ELT (arglist, i);
                   1510:          if (TREE_CODE (parm) == IDENTIFIER_NODE)
                   1511:            {
                   1512:              /* This parameter is a type.  */
                   1513:              OB_PUTC ('Z');
                   1514:              build_overload_name (arg, 0, 0);
                   1515:            }
                   1516:          else
                   1517:            {
                   1518:              /* It's a PARM_DECL.  */
                   1519:              build_overload_name (TREE_TYPE (parm), 0, 0);
                   1520:              build_overload_value (parm, arg);
                   1521:            }
                   1522:        }
                   1523:     }
                   1524:   else
                   1525:     {
                   1526:       icat (IDENTIFIER_LENGTH (name));
                   1527:       OB_PUTID (name);
                   1528:     }
                   1529: }
                   1530: 
                   1531: /* Given a list of parameters in PARMTYPES, create an unambiguous
                   1532:    overload string. Should distinguish any type that C (or C++) can
                   1533:    distinguish. I.e., pointers to functions are treated correctly.
                   1534: 
                   1535:    Caller must deal with whether a final `e' goes on the end or not.
                   1536: 
                   1537:    Any default conversions must take place before this function
                   1538:    is called.
                   1539: 
                   1540:    BEGIN and END control initialization and finalization of the
                   1541:    obstack where we build the string.  */
                   1542: 
                   1543: char *
                   1544: build_overload_name (parmtypes, begin, end)
                   1545:      tree parmtypes;
                   1546:      int begin, end;
                   1547: {
                   1548:   int just_one;
                   1549:   tree parmtype;
                   1550: 
                   1551:   if (begin) OB_INIT ();
                   1552: 
                   1553:   if (just_one = (TREE_CODE (parmtypes) != TREE_LIST))
                   1554:     {
                   1555:       parmtype = parmtypes;
                   1556:       goto only_one;
                   1557:     }
                   1558: 
                   1559:   while (parmtypes)
                   1560:     {
                   1561:       parmtype = TREE_VALUE (parmtypes);
                   1562: 
                   1563:     only_one:
                   1564: 
                   1565:       if (! nofold)
                   1566:        {
                   1567:          if (! just_one)
                   1568:            /* Every argument gets counted.  */
                   1569:            typevec[maxtype++] = parmtype;
                   1570: 
                   1571:          if (TREE_USED (parmtype))
                   1572:            {
                   1573:              if (! just_one && parmtype == typevec[maxtype-2])
                   1574:                nrepeats++;
                   1575:              else
                   1576:                {
                   1577:                  if (nrepeats)
                   1578:                    flush_repeats (parmtype);
                   1579:                  if (! just_one && TREE_CHAIN (parmtypes)
                   1580:                      && parmtype == TREE_VALUE (TREE_CHAIN (parmtypes)))
                   1581:                    nrepeats++;
                   1582:                  else
                   1583:                    {
                   1584:                      int tindex = 0;
                   1585: 
                   1586:                      while (typevec[tindex] != parmtype)
                   1587:                        tindex++;
                   1588:                      OB_PUTC ('T');
                   1589:                      icat (tindex);
                   1590:                      if (tindex > 9)
                   1591:                        OB_PUTC ('_');
                   1592:                    }
                   1593:                }
                   1594:              goto next;
                   1595:            }
                   1596:          if (nrepeats)
                   1597:            flush_repeats (typevec[maxtype-2]);
                   1598:          if (! just_one
                   1599:              /* Only cache types which take more than one character.  */
                   1600:              && (parmtype != TYPE_MAIN_VARIANT (parmtype)
                   1601:                  || (TREE_CODE (parmtype) != INTEGER_TYPE
                   1602:                      && TREE_CODE (parmtype) != REAL_TYPE)))
                   1603:            TREE_USED (parmtype) = 1;
                   1604:        }
                   1605: 
                   1606:       if (TREE_READONLY (parmtype))
                   1607:        OB_PUTC ('C');
                   1608:       if (TREE_CODE (parmtype) == INTEGER_TYPE
                   1609:          && TYPE_MAIN_VARIANT (parmtype) == unsigned_type (TYPE_MAIN_VARIANT (parmtype)))
                   1610:        OB_PUTC ('U');
                   1611:       if (TYPE_VOLATILE (parmtype))
                   1612:        OB_PUTC ('V');
                   1613: 
                   1614:       switch (TREE_CODE (parmtype))
                   1615:        {
                   1616:        case OFFSET_TYPE:
                   1617:          OB_PUTC ('O');
                   1618:          build_overload_name (TYPE_OFFSET_BASETYPE (parmtype), 0, 0);
                   1619:          OB_PUTC ('_');
                   1620:          build_overload_name (TREE_TYPE (parmtype), 0, 0);
                   1621:          break;
                   1622: 
                   1623:        case REFERENCE_TYPE:
                   1624:          OB_PUTC ('R');
                   1625:          goto more;
                   1626: 
                   1627:        case ARRAY_TYPE:
                   1628: #if PARM_CAN_BE_ARRAY_TYPE
                   1629:          {
                   1630:            tree length;
                   1631: 
                   1632:            OB_PUTC ('A');
                   1633:            length = array_type_nelts (parmtype);
                   1634:            if (TREE_CODE (length) == INTEGER_CST)
                   1635:              icat (TREE_INT_CST_LOW (length) + 1);
                   1636:            OB_PUTC ('_');
                   1637:            goto more;
                   1638:          }
                   1639: #else
                   1640:          OB_PUTC ('P');
                   1641:          goto more;
                   1642: #endif
                   1643: 
                   1644:        case POINTER_TYPE:
                   1645:          OB_PUTC ('P');
                   1646:        more:
                   1647:          build_overload_name (TREE_TYPE (parmtype), 0, 0);
                   1648:          break;
                   1649: 
                   1650:        case FUNCTION_TYPE:
                   1651:        case METHOD_TYPE:
                   1652:          {
                   1653:            tree firstarg = TYPE_ARG_TYPES (parmtype);
                   1654:            /* Otherwise have to implement reentrant typevecs,
                   1655:               unmark and remark types, etc.  */
                   1656:            int old_nofold = nofold;
                   1657:            nofold = 1;
                   1658: 
                   1659:            if (nrepeats)
                   1660:              flush_repeats (typevec[maxtype-1]);
                   1661: 
                   1662:            /* @@ It may be possible to pass a function type in
                   1663:               which is not preceded by a 'P'.  */
                   1664:            if (TREE_CODE (parmtype) == FUNCTION_TYPE)
                   1665:              {
                   1666:                OB_PUTC ('F');
                   1667:                if (firstarg == NULL_TREE)
                   1668:                  OB_PUTC ('e');
                   1669:                else if (firstarg == void_list_node)
                   1670:                  OB_PUTC ('v');
                   1671:                else
                   1672:                  build_overload_name (firstarg, 0, 0);
                   1673:              }
                   1674:            else
                   1675:              {
                   1676:                int constp = TYPE_READONLY (TREE_TYPE (TREE_VALUE (firstarg)));
                   1677:                int volatilep = TYPE_VOLATILE (TREE_TYPE (TREE_VALUE (firstarg)));
                   1678:                OB_PUTC ('M');
                   1679:                firstarg = TREE_CHAIN (firstarg);
                   1680: 
                   1681:                build_overload_name (TYPE_METHOD_BASETYPE (parmtype), 0, 0);
                   1682:                if (constp)
                   1683:                  OB_PUTC ('C');
                   1684:                if (volatilep)
                   1685:                  OB_PUTC ('V');
                   1686: 
                   1687:                /* For cfront 2.0 compatability.  */
                   1688:                OB_PUTC ('F');
                   1689: 
                   1690:                if (firstarg == NULL_TREE)
                   1691:                  OB_PUTC ('e');
                   1692:                else if (firstarg == void_list_node)
                   1693:                  OB_PUTC ('v');
                   1694:                else
                   1695:                  build_overload_name (firstarg, 0, 0);
                   1696:              }
                   1697: 
                   1698:            /* Separate args from return type.  */
                   1699:            OB_PUTC ('_');
                   1700:            build_overload_name (TREE_TYPE (parmtype), 0, 0);
                   1701:            nofold = old_nofold;
                   1702:            break;
                   1703:          }
                   1704: 
                   1705:        case INTEGER_TYPE:
                   1706:          parmtype = TYPE_MAIN_VARIANT (parmtype);
                   1707:          switch (TYPE_MODE (parmtype))
                   1708:            {
                   1709:            case TImode:
                   1710:              if (parmtype == long_integer_type_node
                   1711:                  || parmtype == long_unsigned_type_node)
                   1712:                OB_PUTC ('l');
                   1713:              else
                   1714:                OB_PUTC ('q');
                   1715:              break;
                   1716:            case DImode:
                   1717:              if (parmtype == long_integer_type_node
                   1718:                  || parmtype == long_unsigned_type_node)
                   1719:                OB_PUTC ('l');
                   1720:              else if (parmtype == integer_type_node
                   1721:                       || parmtype == unsigned_type_node)
                   1722:                OB_PUTC ('i');
                   1723:              else if (parmtype == short_integer_type_node
                   1724:                       || parmtype == short_unsigned_type_node)
                   1725:                OB_PUTC ('s');
                   1726:              else
                   1727:                OB_PUTC ('x');
                   1728:              break;
                   1729:            case SImode:
                   1730:              if (parmtype == long_integer_type_node
                   1731:                  || parmtype == long_unsigned_type_node)
                   1732:                OB_PUTC ('l');
                   1733:              else if (parmtype == short_integer_type_node
                   1734:                       || parmtype == short_unsigned_type_node)
                   1735:                OB_PUTC ('s');
                   1736:              else
                   1737:                OB_PUTC ('i');
                   1738:              break;
                   1739:            case HImode:
                   1740:              if (parmtype == integer_type_node
                   1741:                  || parmtype == unsigned_type_node)
                   1742:                OB_PUTC ('i');
                   1743:              else
                   1744:                OB_PUTC ('s');
                   1745:              break;
                   1746:            case QImode:
                   1747:              OB_PUTC ('c');
                   1748:              break;
                   1749:            default:
                   1750:              abort ();
                   1751:            }
                   1752:          break;
                   1753: 
                   1754:        case REAL_TYPE:
                   1755:          parmtype = TYPE_MAIN_VARIANT (parmtype);
                   1756:          if (parmtype == long_double_type_node)
                   1757:            OB_PUTC ('r');
                   1758:          else if (parmtype == double_type_node)
                   1759:            OB_PUTC ('d');
                   1760:          else if (parmtype == float_type_node)
                   1761:            OB_PUTC ('f');
                   1762:          else abort ();
                   1763:          break;
                   1764: 
                   1765:        case VOID_TYPE:
                   1766:          if (! just_one)
                   1767:            {
                   1768: #if 0
                   1769:              extern tree void_list_node;
                   1770: 
                   1771:              /* See if anybody is wasting memory.  */
                   1772:              assert (parmtypes == void_list_node);
                   1773: #endif
                   1774:              /* This is the end of a parameter list.  */
                   1775:              if (end) OB_FINISH ();
                   1776:              return (char *)obstack_base (&scratch_obstack);
                   1777:            }
                   1778:          OB_PUTC ('v');
                   1779:          break;
                   1780: 
                   1781:        case ERROR_MARK:        /* not right, but nothing is anyway */
                   1782:          break;
                   1783: 
                   1784:          /* have to do these */
                   1785:        case UNION_TYPE:
                   1786:        case RECORD_TYPE:
                   1787:          if (! just_one)
                   1788:            /* Make this type signature look incompatible
                   1789:               with AT&T.  */
                   1790:            OB_PUTC ('G');
                   1791:          goto common;
                   1792:        case ENUMERAL_TYPE:
                   1793:        common:
                   1794:          {
                   1795:            tree name = TYPE_NAME (parmtype);
                   1796:            int i = 1;
                   1797: 
                   1798:            if (TREE_CODE (name) == TYPE_DECL)
                   1799:              {
                   1800:                tree context = name;
                   1801:                while (DECL_CONTEXT (context))
                   1802:                  {
                   1803:                    i += 1;
                   1804:                    context = DECL_CONTEXT (context);
                   1805:                    if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')
                   1806:                      context = TYPE_NAME (context);
                   1807:                  }
                   1808:                name = DECL_NAME (name);
                   1809:              }
                   1810:            assert (TREE_CODE (name) == IDENTIFIER_NODE);
                   1811:            if (i > 1)
                   1812:              {
                   1813:                OB_PUTC ('Q');
                   1814:                icat (i);
                   1815:                build_overload_nested_name (TYPE_NAME (parmtype));
                   1816:              }
                   1817:            else
                   1818:              build_overload_identifier (name);
                   1819:            break;
                   1820:          }
                   1821: 
                   1822:        case UNKNOWN_TYPE:
                   1823:          /* This will take some work.  */
                   1824:          OB_PUTC ('?');
                   1825:          break;
                   1826: 
                   1827:        case TEMPLATE_TYPE_PARM:
                   1828:        case TEMPLATE_CONST_PARM:
                   1829:         case UNINSTANTIATED_P_TYPE:
                   1830:          /* We don't ever want this output, but it's inconvenient not to
                   1831:             be able to build the string.  This should cause assembler
                   1832:             errors we'll notice.  */
                   1833:          {
                   1834:            static int n;
                   1835:            sprintf (digit_buffer, " *%d", n++);
                   1836:            OB_PUTCP (digit_buffer);
                   1837:          }
                   1838:          break;
                   1839: 
                   1840:        default:
                   1841:          abort ();
                   1842:        }
                   1843: 
                   1844:     next:
                   1845:       if (just_one) break;
                   1846:       parmtypes = TREE_CHAIN (parmtypes);
                   1847:     }
                   1848:   if (! just_one)
                   1849:     {
                   1850:       if (nrepeats)
                   1851:        flush_repeats (typevec[maxtype-1]);
                   1852: 
                   1853:       /* To get here, parms must end with `...'. */
                   1854:       OB_PUTC ('e');
                   1855:     }
                   1856: 
                   1857:   if (end) OB_FINISH ();
                   1858:   return (char *)obstack_base (&scratch_obstack);
                   1859: }
                   1860: 
                   1861: /* Generate an identifier that encodes the (ANSI) exception TYPE. */
                   1862: 
                   1863: /* This should be part of `ansi_opname', or at least be defined by the std.  */
                   1864: #define EXCEPTION_NAME_PREFIX "__ex"
                   1865: #define EXCEPTION_NAME_LENGTH 4
                   1866: 
                   1867: tree
                   1868: cplus_exception_name (type)
                   1869:      tree type;
                   1870: {
                   1871:   OB_INIT ();
                   1872:   OB_PUTS (EXCEPTION_NAME_PREFIX);
                   1873:   return get_identifier (build_overload_name (type, 0, 1));
                   1874: }
                   1875: 
                   1876: /* Change the name of a function definition so that it may be
                   1877:    overloaded. NAME is the name of the function to overload,
                   1878:    PARMS is the parameter list (which determines what name the
                   1879:    final function obtains).
                   1880: 
                   1881:    FOR_METHOD is 1 if this overload is being performed
                   1882:    for a method, rather than a function type.  It is 2 if
                   1883:    this overload is being performed for a constructor.  */
                   1884: tree
                   1885: build_decl_overload (name, parms, for_method)
                   1886:      char *name;
                   1887:      tree parms;
                   1888:      int for_method;
                   1889: {
                   1890:   OB_INIT ();
                   1891:   if (for_method != 2)
                   1892:     OB_PUTCP (name);
                   1893:   /* Otherwise, we can divine that this is a constructor,
                   1894:      and figure out its name without any extra encoding.  */
                   1895: 
                   1896:   OB_PUTC2 ('_', '_');
                   1897:   if (for_method)
                   1898:     {
                   1899: #if 0
                   1900:       /* We can get away without doing this.  */
                   1901:       OB_PUTC ('M');
                   1902: #endif
                   1903:       parms = temp_tree_cons (NULL_TREE, TREE_TYPE (TREE_VALUE (parms)), TREE_CHAIN (parms));
                   1904:     }
                   1905:   else
                   1906:     OB_PUTC ('F');
                   1907: 
                   1908:   if (parms == NULL_TREE)
                   1909:     OB_PUTC2 ('e', '\0');
                   1910:   else if (parms == void_list_node)
                   1911:     OB_PUTC2 ('v', '\0');
                   1912:   else
                   1913:     {
                   1914:       ALLOCATE_TYPEVEC (parms);
                   1915:       nofold = 0;
                   1916:       if (for_method)
                   1917:        {
                   1918:          build_overload_name (TREE_VALUE (parms), 0, 0);
                   1919: 
                   1920:          typevec[maxtype++] = TREE_VALUE (parms);
                   1921:          TREE_USED (TREE_VALUE (parms)) = 1;
                   1922: 
                   1923:          if (TREE_CHAIN (parms))
                   1924:            build_overload_name (TREE_CHAIN (parms), 0, 1);
                   1925:          else
                   1926:            OB_PUTC2 ('e', '\0');
                   1927:        }
                   1928:       else
                   1929:        build_overload_name (parms, 0, 1);
                   1930:       DEALLOCATE_TYPEVEC (parms);
                   1931:     }
                   1932:   return get_identifier (obstack_base (&scratch_obstack));
                   1933: }
                   1934: 
                   1935: /* Build an overload name for the type expression TYPE.  */
                   1936: tree
                   1937: build_typename_overload (type)
                   1938:      tree type;
                   1939: {
                   1940:   OB_INIT ();
                   1941:   OB_PUTID (ansi_opname[TYPE_EXPR]);
                   1942: 
                   1943: #if 0
                   1944:   /* We can get away without doing this--it really gets
                   1945:      overloaded later.  */
                   1946:   OB_PUTC2 ('_', '_');
                   1947:   OB_PUTC ('M');
                   1948: #endif
                   1949:   nofold = 1;
                   1950:   build_overload_name (type, 0, 1);
                   1951:   return get_identifier (obstack_base (&scratch_obstack));
                   1952: }
                   1953: 
                   1954: #define T_DESC_FORMAT "TD$"
                   1955: #define I_DESC_FORMAT "ID$"
                   1956: #define M_DESC_FORMAT "MD$"
                   1957: 
                   1958: /* Build an overload name for the type expression TYPE.  */
                   1959: tree
                   1960: build_t_desc_overload (type)
                   1961:      tree type;
                   1962: {
                   1963:   int i = sizeof (T_DESC_FORMAT) - 1;
                   1964: 
                   1965:   OB_INIT ();
                   1966:   OB_PUTS (T_DESC_FORMAT);
                   1967:   nofold = 1;
                   1968: 
                   1969: #if 0
                   1970:   /* Use a different format if the type isn't defined yet.  */
                   1971:   if (TYPE_SIZE (type) == NULL_TREE)
                   1972:     {
                   1973:       char *p;
                   1974:       int changed;
                   1975: 
                   1976:       for (p = tname; *p; p++)
                   1977:        if (isupper (*p))
                   1978:          {
                   1979:            changed = 1;
                   1980:            *p = tolower (*p);
                   1981:          }
                   1982:       /* If there's no change, we have an innappropriate T_DESC_FORMAT.  */
                   1983:       assert (changed != 0);
                   1984:     }
                   1985: #endif
                   1986: 
                   1987:   build_overload_name (type, 0, 1);
                   1988:   return get_identifier (obstack_base (&scratch_obstack));
                   1989: }
                   1990: 
                   1991: /* Top-level interface to explicit overload requests. Allow NAME
                   1992:    to be overloaded. Error if NAME is already declared for the current
                   1993:    scope. Warning if function is redundanly overloaded. */
                   1994: 
                   1995: void
                   1996: declare_overloaded (name)
                   1997:      tree name;
                   1998: {
                   1999: #ifdef NO_AUTO_OVERLOAD
                   2000:   if (is_overloaded (name))
                   2001:     warning ("function `%s' already declared overloaded",
                   2002:             IDENTIFIER_POINTER (name));
                   2003:   else if (IDENTIFIER_GLOBAL_VALUE (name))
                   2004:     error ("overloading function `%s' that is already defined",
                   2005:           IDENTIFIER_POINTER (name));
                   2006:   else
                   2007:     {
                   2008:       TREE_OVERLOADED (name) = 1;
                   2009:       IDENTIFIER_GLOBAL_VALUE (name) = build_tree_list (name, NULL_TREE);
                   2010:       TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (name)) = unknown_type_node;
                   2011:     }
                   2012: #else
                   2013:   if (current_lang_name == lang_name_cplusplus)
                   2014:     {
                   2015:       if (0)
                   2016:        warning ("functions are implicitly overloaded in C++");
                   2017:     }
                   2018:   else if (current_lang_name == lang_name_c)
                   2019:     error ("overloading function `%s' cannot be done in C language context");
                   2020:   else
                   2021:     abort ();
                   2022: #endif
                   2023: }
                   2024: 
                   2025: #ifdef NO_AUTO_OVERLOAD
                   2026: /* Check to see if NAME is overloaded. For first approximation,
                   2027:    check to see if its TREE_OVERLOADED is set.  This is used on
                   2028:    IDENTIFIER nodes.  */
                   2029: int
                   2030: is_overloaded (name)
                   2031:      tree name;
                   2032: {
                   2033:   /* @@ */
                   2034:   return (TREE_OVERLOADED (name)
                   2035:          && (! IDENTIFIER_CLASS_VALUE (name) || current_class_type == 0)
                   2036:          && ! IDENTIFIER_LOCAL_VALUE (name));
                   2037: }
                   2038: #endif
                   2039: 
                   2040: /* Given a tree_code CODE, and some arguments (at least one),
                   2041:    attempt to use an overloaded operator on the arguments.
                   2042: 
                   2043:    For unary operators, only the first argument need be checked.
                   2044:    For binary operators, both arguments may need to be checked.
                   2045: 
                   2046:    Member functions can convert class references to class pointers,
                   2047:    for one-level deep indirection.  More than that is not supported.
                   2048:    Operators [](), ()(), and ->() must be member functions.
                   2049: 
                   2050:    We call function call building calls with nonzero complain if
                   2051:    they are our only hope.  This is true when we see a vanilla operator
                   2052:    applied to something of aggregate type.  If this fails, we are free to
                   2053:    return `error_mark_node', because we will have reported the error.
                   2054: 
                   2055:    Operators NEW and DELETE overload in funny ways: operator new takes
                   2056:    a single `size' parameter, and operator delete takes a pointer to the
                   2057:    storage being deleted.  When overloading these operators, success is
                   2058:    assumed.  If there is a failure, report an error message and return
                   2059:    `error_mark_node'.  */
                   2060: 
                   2061: /* NOSTRICT */
                   2062: tree
                   2063: build_opfncall (code, flags, xarg1, xarg2, arg3)
                   2064:      enum tree_code code;
                   2065:      tree xarg1, xarg2;
                   2066:      tree arg3;
                   2067: {
                   2068:   tree rval = 0;
                   2069:   tree arg1, arg2;
                   2070:   tree type1, type2, fnname;
                   2071:   tree fields1 = 0, parms = 0;
                   2072:   tree global_fn;
                   2073:   int try_second;
                   2074:   int binary_is_unary;
                   2075: 
                   2076:   if (xarg1 == error_mark_node)
                   2077:     return error_mark_node;
                   2078: 
                   2079:   if (code == COND_EXPR)
                   2080:     {
                   2081:       if (TREE_CODE (xarg2) == ERROR_MARK
                   2082:          || TREE_CODE (arg3) == ERROR_MARK)
                   2083:        return error_mark_node;
                   2084:     }
                   2085:   if (code == COMPONENT_REF)
                   2086:     if (TREE_CODE (TREE_TYPE (xarg1)) == POINTER_TYPE)
                   2087:       return rval;
                   2088: 
                   2089:   /* First, see if we can work with the first argument */
                   2090:   type1 = TREE_TYPE (xarg1);
                   2091: 
                   2092:   /* Some tree codes have length > 1, but we really only want to
                   2093:      overload them if their first argument has a user defined type.  */
                   2094:   switch (code)
                   2095:     {
                   2096:     case PREINCREMENT_EXPR:
                   2097:       code = POSTINCREMENT_EXPR;
                   2098:       binary_is_unary = 1;
                   2099:       try_second = 0;
                   2100:       break;
                   2101: 
                   2102:     case POSTDECREMENT_EXPR:
                   2103:       code = PREDECREMENT_EXPR;
                   2104:       binary_is_unary = 1;
                   2105:       try_second = 0;
                   2106:       break;
                   2107: 
                   2108:     case PREDECREMENT_EXPR:
                   2109:     case POSTINCREMENT_EXPR:
                   2110:     case COMPONENT_REF:
                   2111:       binary_is_unary = 1;
                   2112:       try_second = 0;
                   2113:       break;
                   2114: 
                   2115:       /* ARRAY_REFs and CALL_EXPRs must overload successfully.
                   2116:         If they do not, return error_mark_node instead of NULL_TREE.  */
                   2117:     case ARRAY_REF:
                   2118:       if (xarg2 == error_mark_node)
                   2119:        return error_mark_node;
                   2120:     case CALL_EXPR:
                   2121:       rval = error_mark_node;
                   2122:       binary_is_unary = 0;
                   2123:       try_second = 0;
                   2124:       break;
                   2125: 
                   2126:     case NEW_EXPR:
                   2127:       {
                   2128:        /* For operators `new' (`delete'), only check visibility
                   2129:           if we are in a constructor (destructor), and we are
                   2130:           allocating for that constructor's (destructor's) type.  */
                   2131: 
                   2132:        fnname = ansi_opname[NEW_EXPR];
                   2133:        if (flags & LOOKUP_GLOBAL)
                   2134:          return build_overload_call (fnname, tree_cons (NULL_TREE, xarg2, arg3),
                   2135:                                      flags & LOOKUP_COMPLAIN, 0);
                   2136: 
                   2137:        if (current_function_decl == NULL_TREE
                   2138:            || !DECL_CONSTRUCTOR_P (current_function_decl)
                   2139:            || current_class_type != TYPE_MAIN_VARIANT (type1))
                   2140:          flags = LOOKUP_COMPLAIN;
                   2141:        rval = build_method_call (build1 (NOP_EXPR, xarg1, error_mark_node),
                   2142:                                  fnname, tree_cons (NULL_TREE, xarg2, arg3),
                   2143:                                  NULL_TREE, flags);
                   2144:        if (rval == error_mark_node)
                   2145:          /* User might declare fancy operator new, but invoke it
                   2146:             like standard one.  */
                   2147:          return rval;
                   2148: 
                   2149:        TREE_TYPE (rval) = xarg1;
                   2150:        TREE_CALLS_NEW (rval) = 1;
                   2151:        return rval;
                   2152:       }
                   2153:       break;
                   2154: 
                   2155:     case DELETE_EXPR:
                   2156:       {
                   2157:        /* See comment above.  */
                   2158: 
                   2159:        fnname = ansi_opname[DELETE_EXPR];
                   2160:        if (flags & LOOKUP_GLOBAL)
                   2161:          return build_overload_call (fnname, build_tree_list (NULL_TREE, xarg1),
                   2162:                                      flags & LOOKUP_COMPLAIN, 0);
                   2163: 
                   2164:        if (current_function_decl == NULL_TREE
                   2165:            || !DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (current_function_decl))
                   2166:            || current_class_type != TYPE_MAIN_VARIANT (type1))
                   2167:          flags = LOOKUP_COMPLAIN;
                   2168:        rval = build_method_call (build1 (NOP_EXPR, TREE_TYPE (xarg1), error_mark_node),
                   2169:                                  fnname, build_tree_list (NULL_TREE, xarg1),
                   2170:                                  NULL_TREE, flags);
                   2171:        /* This happens when the user mis-declares `operator delete'.
                   2172:           Should now be impossible.  */
                   2173:        assert (rval != error_mark_node);
                   2174:        TREE_TYPE (rval) = void_type_node;
                   2175:        return rval;
                   2176:       }
                   2177:       break;
                   2178: 
                   2179:     default:
                   2180:       binary_is_unary = 0;
                   2181:       try_second = tree_code_length [(int) code] == 2;
                   2182:       if (try_second && xarg2 == error_mark_node)
                   2183:        return error_mark_node;
                   2184:       break;
                   2185:     }
                   2186: 
                   2187:   if (try_second && xarg2 == error_mark_node)
                   2188:     return error_mark_node;
                   2189: 
                   2190:   /* What ever it was, we do not know how to deal with it.  */
                   2191:   if (type1 == NULL_TREE)
                   2192:     return rval;
                   2193: 
                   2194:   if (TREE_CODE (type1) == OFFSET_TYPE)
                   2195:     type1 = TREE_TYPE (type1);
                   2196: 
                   2197:   if (TREE_CODE (type1) == REFERENCE_TYPE)
                   2198:     {
                   2199:       arg1 = convert_from_reference (xarg1);
                   2200:       type1 = TREE_TYPE (arg1);
                   2201:     }
                   2202:   else
                   2203:     {
                   2204:       arg1 = xarg1;
                   2205:     }
                   2206: 
                   2207:   if (!IS_AGGR_TYPE (type1))
                   2208:     {
                   2209:       /* Try to fail. First, fail if unary */
                   2210:       if (! try_second)
                   2211:        return rval;
                   2212:       /* Second, see if second argument is non-aggregate. */
                   2213:       type2 = TREE_TYPE (xarg2);
                   2214:       if (TREE_CODE (type2) == OFFSET_TYPE)
                   2215:        type2 = TREE_TYPE (type2);
                   2216:       if (TREE_CODE (type2) == REFERENCE_TYPE)
                   2217:        {
                   2218:          arg2 = convert_from_reference (xarg2);
                   2219:          type2 = TREE_TYPE (arg2);
                   2220:        }
                   2221:       else
                   2222:        {
                   2223:          arg2 = xarg2;
                   2224:        }
                   2225: 
                   2226:       if (!IS_AGGR_TYPE (type2))
                   2227:        return rval;
                   2228:       try_second = 0;
                   2229:     }
                   2230: 
                   2231:   if (try_second)
                   2232:     {
                   2233:       /* First arg may succeed; see whether second should.  */
                   2234:       type2 = TREE_TYPE (xarg2);
                   2235:       if (TREE_CODE (type2) == OFFSET_TYPE)
                   2236:        type2 = TREE_TYPE (type2);
                   2237:       if (TREE_CODE (type2) == REFERENCE_TYPE)
                   2238:        {
                   2239:          arg2 = convert_from_reference (xarg2);
                   2240:          type2 = TREE_TYPE (arg2);
                   2241:        }
                   2242:       else
                   2243:        {
                   2244:          arg2 = xarg2;
                   2245:        }
                   2246: 
                   2247:       if (! IS_AGGR_TYPE (type2))
                   2248:        try_second = 0;
                   2249:     }
                   2250: 
                   2251:   if (type1 == unknown_type_node
                   2252:       || (try_second && TREE_TYPE (xarg2) == unknown_type_node))
                   2253:     {
                   2254:       /* This will not be implemented in the forseeable future.  */
                   2255:       return rval;
                   2256:     }
                   2257: 
                   2258:   if (code == MODIFY_EXPR)
                   2259:     fnname = ansi_assopname[(int)arg3];
                   2260:   else
                   2261:     fnname = ansi_opname[code];
                   2262: 
                   2263:   global_fn = IDENTIFIER_GLOBAL_VALUE (fnname);
                   2264: 
                   2265:   /* This is the last point where we will accept failure.  This
                   2266:      may be too eager if we wish an overloaded operator not to match,
                   2267:      but would rather a normal operator be called on a type-converted
                   2268:      argument.  */
                   2269: 
                   2270:   if (IS_AGGR_TYPE (type1))
                   2271:     fields1 = lookup_fnfields (TYPE_BINFO (type1), fnname, 0);
                   2272: 
                   2273:   if (fields1 == NULL_TREE && global_fn == NULL_TREE)
                   2274:     return rval;
                   2275: 
                   2276:   /* If RVAL winds up being `error_mark_node', we will return
                   2277:      that... There is no way that normal semantics of these
                   2278:      operators will succeed.  */
                   2279: 
                   2280:   /* This argument may be an uncommited OFFSET_REF.  This is
                   2281:      the case for example when dealing with static class members
                   2282:      which are referenced from their class name rather than
                   2283:      from a class instance.  */
                   2284:   if (TREE_CODE (xarg1) == OFFSET_REF
                   2285:       && TREE_CODE (TREE_OPERAND (xarg1, 1)) == VAR_DECL)
                   2286:     xarg1 = TREE_OPERAND (xarg1, 1);
                   2287:   if (try_second && xarg2 && TREE_CODE (xarg2) == OFFSET_REF
                   2288:       && TREE_CODE (TREE_OPERAND (xarg2, 1)) == VAR_DECL)
                   2289:     xarg2 = TREE_OPERAND (xarg2, 1);
                   2290: 
                   2291:   if (global_fn)
                   2292:     flags |= LOOKUP_GLOBAL;
                   2293: 
                   2294:   if (code == CALL_EXPR)
                   2295:     {
                   2296:       /* This can only be a member function.  */
                   2297:       return build_method_call (xarg1, fnname, xarg2,
                   2298:                                NULL_TREE, LOOKUP_NORMAL);
                   2299:     }
                   2300:   else if (tree_code_length[(int) code] == 1 || binary_is_unary)
                   2301:     {
                   2302:       parms = NULL_TREE;
                   2303:       rval = build_method_call (xarg1, fnname, NULL_TREE, NULL_TREE, flags);
                   2304:     }
                   2305:   else if (code == COND_EXPR)
                   2306:     {
                   2307:       parms = tree_cons (0, xarg2, build_tree_list (0, arg3));
                   2308:       rval = build_method_call (xarg1, fnname, parms, NULL_TREE, flags);
                   2309:     }
                   2310:   else if (code == METHOD_CALL_EXPR)
                   2311:     {
                   2312:       /* must be a member function.  */
                   2313:       parms = tree_cons (NULL_TREE, xarg2, arg3);
                   2314:       return build_method_call (xarg1, fnname, parms, NULL_TREE, LOOKUP_NORMAL);
                   2315:     }
                   2316:   else if (fields1)
                   2317:     {
                   2318:       parms = build_tree_list (NULL_TREE, xarg2);
                   2319:       rval = build_method_call (xarg1, fnname, parms, NULL_TREE, flags);
                   2320:     }
                   2321:   else
                   2322:     {
                   2323:       parms = tree_cons (NULL_TREE, xarg1,
                   2324:                         build_tree_list (NULL_TREE, xarg2));
                   2325:       rval = build_overload_call (fnname, parms, flags & LOOKUP_COMPLAIN, 0);
                   2326:     }
                   2327: 
                   2328:   /* If we did not win, do not lose yet, since type conversion may work.  */
                   2329:   if (TREE_CODE (rval) == ERROR_MARK)
                   2330:     {
                   2331:       if (flags & LOOKUP_COMPLAIN)
                   2332:        return rval;
                   2333:       return 0;
                   2334:     }
                   2335: 
                   2336:   return rval;
                   2337: }
                   2338: 
                   2339: /* This function takes an identifier, ID, and attempts to figure out what
                   2340:    it means. There are a number of possible scenarios, presented in increasing
                   2341:    order of hair:
                   2342: 
                   2343:    1) not in a class's scope
                   2344:    2) in class's scope, member name of the class's method
                   2345:    3) in class's scope, but not a member name of the class
                   2346:    4) in class's scope, member name of a class's variable
                   2347: 
                   2348:    NAME is $1 from the bison rule. It is an IDENTIFIER_NODE.
                   2349:    VALUE is $$ from the bison rule. It is the value returned by lookup_name ($1)
                   2350:    yychar is the pending input character (suitably encoded :-).
                   2351: 
                   2352:    As a last ditch, try to look up the name as a label and return that
                   2353:    address.
                   2354: 
                   2355:    Values which are declared as being of REFERENCE_TYPE are
                   2356:    automatically dereferenced here (as a hack to make the
                   2357:    compiler faster).  */
                   2358: 
                   2359: tree
                   2360: hack_identifier (value, name, yychar)
                   2361:      tree value, name;
                   2362: {
                   2363:   tree type;
                   2364: 
                   2365:   if (TREE_CODE (value) == ERROR_MARK)
                   2366:     {
                   2367:       if (current_class_name)
                   2368:        {
                   2369:          tree fields = lookup_fnfields (TYPE_BINFO (current_class_type), name, 0);
                   2370:          if (fields)
                   2371:            {
                   2372:              tree fndecl;
                   2373: 
                   2374:              fndecl = TREE_VALUE (fields);
                   2375:              assert (TREE_CODE (fndecl) == FUNCTION_DECL);
                   2376:              if (DECL_CHAIN (fndecl) == NULL_TREE)
                   2377:                {
                   2378:                  warning ("methods cannot be converted to function pointers");
                   2379:                  return fndecl;
                   2380:                }
                   2381:              else
                   2382:                {
                   2383:                  error ("ambiguous request for method pointer `%s'",
                   2384:                         IDENTIFIER_POINTER (name));
                   2385:                  return error_mark_node;
                   2386:                }
                   2387:            }
                   2388:        }
                   2389:       if (flag_labels_ok && IDENTIFIER_LABEL_VALUE (name))
                   2390:        {
                   2391:          return IDENTIFIER_LABEL_VALUE (name);
                   2392:        }
                   2393:       return error_mark_node;
                   2394:     }
                   2395: 
                   2396:   type = TREE_TYPE (value);
                   2397:   if (TREE_CODE (value) == FIELD_DECL)
                   2398:     {
                   2399:       if (current_class_decl == NULL_TREE)
                   2400:        {
                   2401:          error ("request for member `%s' in static member function",
                   2402:                 IDENTIFIER_POINTER (DECL_NAME (value)));
                   2403:          return error_mark_node;
                   2404:        }
                   2405:       TREE_USED (current_class_decl) = 1;
                   2406:       if (yychar == '(')
                   2407:        if (! ((TYPE_LANG_SPECIFIC (type)
                   2408:                && TYPE_OVERLOADS_CALL_EXPR (type))
                   2409:               || (TREE_CODE (type) == REFERENCE_TYPE
                   2410:                   && TYPE_LANG_SPECIFIC (TREE_TYPE (type))
                   2411:                   && TYPE_OVERLOADS_CALL_EXPR (TREE_TYPE (type))))
                   2412:            && TREE_CODE (type) != FUNCTION_TYPE
                   2413:            && TREE_CODE (type) != METHOD_TYPE
                   2414:            && (TREE_CODE (type) != POINTER_TYPE
                   2415:                || (TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE
                   2416:                    && TREE_CODE (TREE_TYPE (type)) != METHOD_TYPE)))
                   2417:          {
                   2418:            error ("component `%s' is not a method",
                   2419:                   IDENTIFIER_POINTER (name));
                   2420:            return error_mark_node;
                   2421:          }
                   2422:       /* Mark so that if we are in a constructor, and then find that
                   2423:         this field was initialized by a base initializer,
                   2424:         we can emit an error message.  */
                   2425:       TREE_USED (value) = 1;
                   2426:       return build_component_ref (C_C_D, name, 0, 1);
                   2427:     }
                   2428: 
                   2429:   if (TREE_CODE (value) == TREE_LIST)
                   2430:     {
                   2431:       tree t = value;
                   2432:       while (t && TREE_CODE (t) == TREE_LIST)
                   2433:        {
                   2434:          assemble_external (TREE_VALUE (t));
                   2435:          TREE_USED (t) = 1;
                   2436:          t = TREE_CHAIN (t);
                   2437:        }
                   2438:     }
                   2439:   else
                   2440:     {
                   2441:       assemble_external (value);
                   2442:       TREE_USED (value) = 1;
                   2443:     }
                   2444: 
                   2445:   if (TREE_CODE_CLASS (TREE_CODE (value)) == 'd' && TREE_NONLOCAL (value))
                   2446:     {
                   2447:       if (DECL_CLASS_CONTEXT (value) != current_class_type)
                   2448:        {
                   2449:          tree path;
                   2450:          enum visibility_type visibility;
                   2451: 
                   2452:          get_base_distance (DECL_CLASS_CONTEXT (value),
                   2453:                             current_class_type, 0, &path);
                   2454:          visibility = compute_visibility (path, value);
                   2455:          if (visibility != visibility_public)
                   2456:            {
                   2457:              if (TREE_CODE (value) == VAR_DECL)
                   2458:                error ("static member `%s' is from private base class",
                   2459:                       IDENTIFIER_POINTER (name));
                   2460:              else
                   2461:                error ("enum `%s' is from private base class",
                   2462:                       IDENTIFIER_POINTER (name));
                   2463:              return error_mark_node;
                   2464:            }
                   2465:        }
                   2466:       if (TREE_CODE (value) == VAR_DECL && ! TREE_USED (value))
                   2467:        {
                   2468:          if (TREE_EXTERNAL (value))
                   2469:            assemble_external (value);
                   2470:          TREE_USED (value) = 1;
                   2471:        }
                   2472:       return value;
                   2473:     }
                   2474:   if (TREE_CODE (value) == TREE_LIST && TREE_NONLOCAL_FLAG (value))
                   2475:     {
                   2476:       if (type == 0)
                   2477:        {
                   2478:          error ("request for member `%s' is ambiguous in multiple inheritance lattice",
                   2479:                 IDENTIFIER_POINTER (name));
                   2480:          return error_mark_node;
                   2481:        }
                   2482: 
                   2483:       return value;
                   2484:     }
                   2485: 
                   2486:   if (TREE_CODE (type) == REFERENCE_TYPE)
                   2487:     {
                   2488:       assert (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == PARM_DECL);
                   2489:       if (DECL_REFERENCE_SLOT (value))
                   2490:        return DECL_REFERENCE_SLOT (value);
                   2491:     }
                   2492:   return value;
                   2493: }
                   2494: 
                   2495: /* NONWRAPPER is nonzero if this call is not to be wrapped.
                   2496:    TYPE is the type that the wrapper belongs to (in case
                   2497:    it should be non-virtual).
                   2498:    DECL is the function will will be (not be) wrapped.  */
                   2499: tree
                   2500: hack_wrapper (nonwrapper, type, decl)
                   2501:      int nonwrapper;
                   2502:      tree type, decl;
                   2503: {
                   2504:   if (type == NULL_TREE || is_aggr_typedef (type, 1))
                   2505:     {
                   2506:       if (type)
                   2507:        type = TREE_TYPE (type);
                   2508: 
                   2509:       switch (nonwrapper)
                   2510:        {
                   2511:        case 0:
                   2512:          return build_nt (WRAPPER_EXPR, type, decl);
                   2513:        case 1:
                   2514:          return build_nt (ANTI_WRAPPER_EXPR, type, decl);
                   2515:        case 2:
                   2516:          return build_nt (WRAPPER_EXPR, type,
                   2517:                           build_nt (COND_EXPR, decl, NULL_TREE, NULL_TREE));
                   2518:        default:
                   2519:          assert (0 <= nonwrapper && nonwrapper <= 2);
                   2520:        }
                   2521:     }
                   2522:   return error_mark_node;
                   2523: }
                   2524: 
                   2525: /* Given an object OF, and a type conversion operator COMPONENT
                   2526:    build a call to the conversion operator, if a call is requested,
                   2527:    or return the address (as a pointer to member function) if one is not.
                   2528: 
                   2529:    OF can be a TYPE_DECL or any kind of datum that would normally
                   2530:    be passed to `build_component_ref'.  It may also be NULL_TREE,
                   2531:    in which case `current_class_type' and `current_class_decl'
                   2532:    provide default values.
                   2533: 
                   2534:    BASETYPE_PATH, if non-null, is the path of basetypes
                   2535:    to go through before we get the the instance of interest.
                   2536: 
                   2537:    PROTECT says whether we apply C++ scoping rules or not.  */
                   2538: tree
                   2539: build_component_type_expr (of, component, basetype_path, protect)
                   2540:      tree of, component, basetype_path;
                   2541:      int protect;
                   2542: {
                   2543:   tree cname = NULL_TREE;
                   2544:   tree tmp, last;
                   2545:   tree name;
                   2546:   int flags = protect ? LOOKUP_NORMAL : LOOKUP_COMPLAIN;
                   2547: 
                   2548:   assert (IS_AGGR_TYPE (TREE_TYPE (of)));
                   2549:   assert (TREE_CODE (component) == TYPE_EXPR);
                   2550: 
                   2551:   tmp = TREE_OPERAND (component, 0);
                   2552:   last = NULL_TREE;
                   2553: 
                   2554:   while (tmp)
                   2555:     {
                   2556:       switch (TREE_CODE (tmp))
                   2557:        {
                   2558:        case CALL_EXPR:
                   2559:          if (last)
                   2560:            TREE_OPERAND (last, 0) = TREE_OPERAND (tmp, 0);
                   2561:          else
                   2562:            TREE_OPERAND (component, 0) = TREE_OPERAND (tmp, 0);
                   2563:          if (TREE_OPERAND (tmp, 0)
                   2564:              && TREE_OPERAND (tmp, 0) != void_list_node)
                   2565:            {
                   2566:              error ("operator <typename> requires empty parameter list");
                   2567:              TREE_OPERAND (tmp, 0) = NULL_TREE;
                   2568:            }
                   2569:          last = groktypename (build_tree_list (TREE_TYPE (component),
                   2570:                                                TREE_OPERAND (component, 0)));
                   2571:          name = build_typename_overload (last);
                   2572:          TREE_TYPE (name) = last;
                   2573: 
                   2574:          if (of && TREE_CODE (of) != TYPE_DECL)
                   2575:            return build_method_call (of, name, NULL_TREE, NULL_TREE, flags);
                   2576:          else if (of)
                   2577:            {
                   2578:              tree this_this;
                   2579: 
                   2580:              if (current_class_decl == NULL_TREE)
                   2581:                {
                   2582:                  error ("object required for `operator <typename>' call");
                   2583:                  return error_mark_node;
                   2584:                }
                   2585: 
                   2586:              this_this = convert_pointer_to (TREE_TYPE (of), current_class_decl);
                   2587:              return build_method_call (this_this, name, NULL_TREE,
                   2588:                                        NULL_TREE, flags | LOOKUP_NONVIRTUAL);
                   2589:            }
                   2590:          else if (current_class_decl)
                   2591:            return build_method_call (tmp, name, NULL_TREE, NULL_TREE, flags);
                   2592: 
                   2593:          error ("object required for `operator <typename>' call");
                   2594:          return error_mark_node;
                   2595: 
                   2596:        case INDIRECT_REF:
                   2597:        case ADDR_EXPR:
                   2598:        case ARRAY_REF:
                   2599:          break;
                   2600: 
                   2601:        case SCOPE_REF:
                   2602:          assert (cname == 0);
                   2603:          cname = TREE_OPERAND (tmp, 0);
                   2604:          tmp = TREE_OPERAND (tmp, 1);
                   2605:          break;
                   2606: 
                   2607:        default:
                   2608:          abort ();
                   2609:        }
                   2610:       last = tmp;
                   2611:       tmp = TREE_OPERAND (tmp, 0);
                   2612:     }
                   2613: 
                   2614:   last = groktypename (build_tree_list (TREE_TYPE (component), TREE_OPERAND (component, 0)));
                   2615:   name = build_typename_overload (last);
                   2616:   TREE_TYPE (name) = last;
                   2617:   if (of && TREE_CODE (of) == TYPE_DECL)
                   2618:     {
                   2619:       if (cname == NULL_TREE)
                   2620:        {
                   2621:          cname = DECL_NAME (of);
                   2622:          of = NULL_TREE;
                   2623:        }
                   2624:       else assert (cname == DECL_NAME (of));
                   2625:     }
                   2626: 
                   2627:   if (of)
                   2628:     {
                   2629:       tree this_this;
                   2630: 
                   2631:       if (current_class_decl == NULL_TREE)
                   2632:        {
                   2633:          error ("object required for `operator <typename>' call");
                   2634:          return error_mark_node;
                   2635:        }
                   2636: 
                   2637:       this_this = convert_pointer_to (TREE_TYPE (of), current_class_decl);
                   2638:       return build_component_ref (this_this, name, 0, protect);
                   2639:     }
                   2640:   else if (cname)
                   2641:     return build_offset_ref (cname, name);
                   2642:   else if (current_class_name)
                   2643:     return build_offset_ref (current_class_name, name);
                   2644: 
                   2645:   error ("object required for `operator <typename>' member reference");
                   2646:   return error_mark_node;
                   2647: }

unix.superglobalmegacorp.com

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