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

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

unix.superglobalmegacorp.com

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