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

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

unix.superglobalmegacorp.com

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