Annotation of GNUtools/cc/cp-method.c, revision 1.1.1.1

1.1       root        1: /* Handle the hair of processing (but not expanding) inline functions.
                      2:    Also manage function and variable name overloading.
                      3:    Copyright (C) 1987, 1989, 1992, 1993 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 "config.h"
                     30: #include "tree.h"
                     31: #include "cp-tree.h"
                     32: #include "cp-class.h"
                     33: #include "obstack.h"
                     34: #include <ctype.h>
                     35: 
                     36: /* TREE_LIST of the current inline functions that need to be
                     37:    processed.  */
                     38: struct pending_inline *pending_inlines;
                     39: 
                     40: #define obstack_chunk_alloc xmalloc
                     41: #define obstack_chunk_free free
                     42: 
                     43: /* Obstack where we build text strings for overloading, etc.  */
                     44: static struct obstack scratch_obstack;
                     45: static char *scratch_firstobj;
                     46: 
                     47: # define OB_INIT() (scratch_firstobj ? (obstack_free (&scratch_obstack, scratch_firstobj), 0) : 0)
                     48: # define OB_PUTC(C) (obstack_1grow (&scratch_obstack, (C)))
                     49: # define OB_PUTC2(C1,C2)       \
                     50:   (obstack_1grow (&scratch_obstack, (C1)), obstack_1grow (&scratch_obstack, (C2)))
                     51: # define OB_PUTS(S) (obstack_grow (&scratch_obstack, (S), sizeof (S) - 1))
                     52: # define OB_PUTID(ID)  \
                     53:   (obstack_grow (&scratch_obstack, IDENTIFIER_POINTER (ID),    \
                     54:                 IDENTIFIER_LENGTH (ID)))
                     55: # define OB_PUTCP(S) (obstack_grow (&scratch_obstack, (S), strlen (S)))
                     56: # define OB_FINISH() (obstack_1grow (&scratch_obstack, '\0'))
                     57: 
                     58: #ifdef NO_AUTO_OVERLOAD
                     59: int is_overloaded ();
                     60: #endif
                     61: 
                     62: void
                     63: init_method ()
                     64: {
                     65:   gcc_obstack_init (&scratch_obstack);
                     66:   scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0);
                     67: }
                     68: 
                     69: /* This must be large enough to hold any printed integer or floating-point
                     70:    value.  */
                     71: static char digit_buffer[128];
                     72: 
                     73: /* Move inline function definitions out of structure so that they
                     74:    can be processed normally.  CNAME is the name of the class
                     75:    we are working from, METHOD_LIST is the list of method lists
                     76:    of the structure.  We delete friend methods here, after
                     77:    saving away their inline function definitions (if any).  */
                     78: 
                     79: void
                     80: do_inline_function_hair (type, friend_list)
                     81:      tree type, friend_list;
                     82: {
                     83:   tree method = TYPE_METHODS (type);
                     84: 
                     85:   if (method && TREE_CODE (method) == TREE_VEC)
                     86:     {
                     87:       if (TREE_VEC_ELT (method, 0))
                     88:        method = TREE_VEC_ELT (method, 0);
                     89:       else
                     90:        method = TREE_VEC_ELT (method, 1);
                     91:     }
                     92: 
                     93:   while (method)
                     94:     {
                     95:       /* Do inline member functions.  */
                     96:       struct pending_inline *info = DECL_PENDING_INLINE_INFO (method);
                     97:       if (info)
                     98:        {
                     99:          tree args;
                    100: 
                    101:          my_friendly_assert (info->fndecl == method, 238);
                    102:          args = DECL_ARGUMENTS (method);
                    103:          while (args)
                    104:            {
                    105:              DECL_CONTEXT (args) = method;
                    106:              args = TREE_CHAIN (args);
                    107:            }
                    108: 
                    109:          /* Allow this decl to be seen in global scope */
                    110:          IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (method)) = method;
                    111:        }
                    112:       method = TREE_CHAIN (method);
                    113:     }
                    114:   while (friend_list)
                    115:     {
                    116:       tree fndecl = TREE_VALUE (friend_list);
                    117:       struct pending_inline *info = DECL_PENDING_INLINE_INFO (fndecl);
                    118:       if (info)
                    119:        {
                    120:          tree args;
                    121: 
                    122:          my_friendly_assert (info->fndecl == fndecl, 239);
                    123:          args = DECL_ARGUMENTS (fndecl);
                    124:          while (args)
                    125:            {
                    126:              DECL_CONTEXT (args) = fndecl;
                    127:              args = TREE_CHAIN (args);
                    128:            }
                    129: 
                    130:          /* Allow this decl to be seen in global scope */
                    131:          IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (fndecl)) = fndecl;
                    132:        }
                    133: 
                    134:       friend_list = TREE_CHAIN (friend_list);
                    135:     }
                    136: }
                    137: 
                    138: /* Report an argument type mismatch between the best declared function
                    139:    we could find and the current argument list that we have.  */
                    140: void
                    141: report_type_mismatch (cp, parmtypes, name_kind, err_name)
                    142:      struct candidate *cp;
                    143:      tree parmtypes;
                    144:      char *name_kind, *err_name;
                    145: {
                    146:   int i = cp->u.bad_arg;
                    147:   tree ttf, tta;
                    148:   char *tmp_firstobj;
                    149: 
                    150:   switch (i)
                    151:     {
                    152:     case -4:
                    153:       my_friendly_assert (TREE_CODE (cp->function) == TEMPLATE_DECL, 240);
                    154:       error ("type unification failed for function template `%s'", err_name);
                    155:       return;
                    156: 
                    157:     case -3:
                    158:       if (TYPE_READONLY (TREE_TYPE (TREE_VALUE (parmtypes))))
                    159:        error ("call to const %s `%s' with non-const object", name_kind, err_name);
                    160:       else
                    161:        error ("call to non-const %s `%s' with const object", name_kind, err_name);
                    162:       return;
                    163:     case -2:
                    164:       error ("too few arguments for %s `%s'", name_kind, err_name);
                    165:       return;
                    166:     case -1:
                    167:       error ("too many arguments for %s `%s'", name_kind, err_name);
                    168:       return;
                    169:     case 0:
                    170:       if (TREE_CODE (TREE_TYPE (cp->function)) == METHOD_TYPE)
                    171:        {
                    172:          /* Happens when we have an ambiguous base class.  */
                    173:          my_friendly_assert (get_binfo (DECL_CLASS_CONTEXT (cp->function),
                    174:                             TREE_TYPE (TREE_TYPE (TREE_VALUE (parmtypes))), 1) == error_mark_node,
                    175:                              241);
                    176:          return;
                    177:        }
                    178:     }
                    179: 
                    180:   ttf = TYPE_ARG_TYPES (TREE_TYPE (cp->function));
                    181:   tta = parmtypes;
                    182: 
                    183:   while (i-- > 0)
                    184:     {
                    185:       ttf = TREE_CHAIN (ttf);
                    186:       tta = TREE_CHAIN (tta);
                    187:     }
                    188: 
                    189:   OB_INIT ();
                    190:   OB_PUTS ("bad argument ");
                    191:   sprintf (digit_buffer, "%d", cp->u.bad_arg
                    192:           - (TREE_CODE (TREE_TYPE (cp->function)) == METHOD_TYPE)
                    193:           + 1);
                    194:   OB_PUTCP (digit_buffer);
                    195: 
                    196:   OB_PUTS (" for function `");
                    197:   OB_PUTCP (decl_as_string (cp->function, 1));
                    198:   OB_PUTS ("' (type was ");
                    199: 
                    200:   /* Reset `i' so that type printing routines do the right thing.  */
                    201:   if (tta)
                    202:     {
                    203:       enum tree_code code = TREE_CODE (TREE_TYPE (TREE_VALUE (tta)));
                    204:       if (code == ERROR_MARK)
                    205:        OB_PUTS ("(failed type instantiation)");
                    206:       else
                    207:        {
                    208:          i = (code == FUNCTION_TYPE || code == METHOD_TYPE);
                    209:          OB_PUTCP (type_as_string (TREE_TYPE (TREE_VALUE (tta)), 1));
                    210:        }
                    211:     }
                    212:   else OB_PUTS ("void");
                    213:   OB_PUTC (')');
                    214:   OB_FINISH ();
                    215: 
                    216:   tmp_firstobj = (char *)alloca (obstack_object_size (&scratch_obstack));
                    217:   bcopy (obstack_base (&scratch_obstack), tmp_firstobj,
                    218:         obstack_object_size (&scratch_obstack));
                    219:   error (tmp_firstobj);
                    220: }
                    221: 
                    222: /* Here is where overload code starts.  */
                    223: 
                    224: /* Array of types seen so far in top-level call to `build_overload_name'.
                    225:    Allocated and deallocated by caller.  */
                    226: static tree *typevec;
                    227: 
                    228: /* Number of types interned by `build_overload_name' so far.  */
                    229: static int maxtype;
                    230: 
                    231: /* Number of occurrences of last type seen.  */
                    232: static int nrepeats;
                    233: 
                    234: /* Nonzero if we should not try folding parameter types.  */
                    235: static int nofold;
                    236: 
                    237: #define ALLOCATE_TYPEVEC(PARMTYPES) \
                    238:   do { maxtype = 0, nrepeats = 0; \
                    239:        typevec = (tree *)alloca (list_length (PARMTYPES) * sizeof (tree)); } while (0)
                    240: 
                    241: #define DEALLOCATE_TYPEVEC(PARMTYPES) \
                    242:   do { tree t = (PARMTYPES); \
                    243:        while (t) { TREE_USED (TREE_VALUE (t)) = 0; t = TREE_CHAIN (t); } \
                    244:   } while (0)
                    245: 
                    246: /* Code to concatenate an asciified integer to a string.  */
                    247: static
                    248: #ifdef __GNUC__
                    249: __inline
                    250: #endif
                    251: void
                    252: icat (i)
                    253:      int i;
                    254: {
                    255:   /* Handle this case first, to go really quickly.  For many common values,
                    256:      the result of i/10 below is 1.  */
                    257:   if (i == 1)
                    258:     {
                    259:       OB_PUTC ('1');
                    260:       return;
                    261:     }
                    262: 
                    263:   if (i < 0)
                    264:     {
                    265:       OB_PUTC ('m');
                    266:       i = -i;
                    267:     }
                    268:   if (i < 10)
                    269:     OB_PUTC ('0' + i);
                    270:   else
                    271:     {
                    272:       icat (i / 10);
                    273:       OB_PUTC ('0' + (i % 10));
                    274:     }
                    275: }
                    276: 
                    277: static
                    278: #ifdef __GNUC__
                    279: __inline
                    280: #endif
                    281: void
                    282: flush_repeats (type)
                    283:      tree type;
                    284: {
                    285:   int tindex = 0;
                    286: 
                    287:   while (typevec[tindex] != type)
                    288:     tindex++;
                    289: 
                    290:   if (nrepeats > 1)
                    291:     {
                    292:       OB_PUTC ('N');
                    293:       icat (nrepeats);
                    294:       if (nrepeats > 9)
                    295:        OB_PUTC ('_');
                    296:     }
                    297:   else
                    298:     OB_PUTC ('T');
                    299:   nrepeats = 0;
                    300:   icat (tindex);
                    301:   if (tindex > 9)
                    302:     OB_PUTC ('_');
                    303: }
                    304: 
                    305: static void build_overload_identifier ();
                    306: 
                    307: static void
                    308: build_overload_nested_name (context)
                    309:      tree context;
                    310: {
                    311:   /* We use DECL_NAME here, because pushtag now sets the DECL_ASSEMBLER_NAME.  */
                    312:   tree name = DECL_NAME (context);
                    313:   if (DECL_CONTEXT (context))
                    314:     {
                    315:       context = DECL_CONTEXT (context);
                    316:       if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')
                    317:        context = TYPE_NAME (context);
                    318:       build_overload_nested_name (context);
                    319:     }
                    320:   build_overload_identifier (name);
                    321: }
                    322: 
                    323: static void
                    324: build_overload_value (type, value)
                    325:      tree type, value;
                    326: {
                    327:   while (TREE_CODE (value) == NON_LVALUE_EXPR
                    328:         || TREE_CODE (value) == NOP_EXPR)
                    329:     value = TREE_OPERAND (value, 0);
                    330:   my_friendly_assert (TREE_CODE (type) == PARM_DECL, 242);
                    331:   type = TREE_TYPE (type);
                    332:   switch (TREE_CODE (type))
                    333:     {
                    334:     case INTEGER_TYPE:
                    335:     case ENUMERAL_TYPE:
                    336:       {
                    337:        my_friendly_assert (TREE_CODE (value) == INTEGER_CST, 243);
                    338:        if (TYPE_PRECISION (value) == 2 * HOST_BITS_PER_WIDE_INT)
                    339:          {
                    340:            if (tree_int_cst_lt (value, integer_zero_node))
                    341:              {
                    342:                OB_PUTC ('m');
                    343:                value = build_int_2 (~ TREE_INT_CST_LOW (value),
                    344:                                     - TREE_INT_CST_HIGH (value));
                    345:              }
                    346:            if (TREE_INT_CST_HIGH (value)
                    347:                != (TREE_INT_CST_LOW (value) >> (HOST_BITS_PER_WIDE_INT - 1)))
                    348:              {
                    349:                /* need to print a DImode value in decimal */
                    350:                sorry ("conversion of long long as PT parameter");
                    351:              }
                    352:            /* else fall through to print in smaller mode */
                    353:          }
                    354:        /* Wordsize or smaller */
                    355:        icat (TREE_INT_CST_LOW (value));
                    356:        return;
                    357:       }
                    358: #ifndef REAL_IS_NOT_DOUBLE
                    359:     case REAL_TYPE:
                    360:       {
                    361:        REAL_VALUE_TYPE val;
                    362:        char *bufp = digit_buffer;
                    363:        extern char *index ();
                    364: 
                    365:        my_friendly_assert (TREE_CODE (value) == REAL_CST, 244);
                    366:        val = TREE_REAL_CST (value);
                    367:        if (val < 0)
                    368:          {
                    369:            val = -val;
                    370:            *bufp++ = 'm';
                    371:          }
                    372:        sprintf (bufp, "%e", val);
                    373:        bufp = (char *) index (bufp, 'e');
                    374:        if (!bufp)
                    375:          strcat (digit_buffer, "e0");
                    376:        else
                    377:          {
                    378:            char *p;
                    379:            bufp++;
                    380:            if (*bufp == '-')
                    381:              {
                    382:                *bufp++ = 'm';
                    383:              }
                    384:            p = bufp;
                    385:            if (*p == '+')
                    386:              p++;
                    387:            while (*p == '0')
                    388:              p++;
                    389:            if (*p == 0)
                    390:              {
                    391:                *bufp++ = '0';
                    392:                *bufp = 0;
                    393:              }
                    394:            else if (p != bufp)
                    395:              {
                    396:                while (*p)
                    397:                  *bufp++ = *p++;
                    398:                *bufp = 0;
                    399:              }
                    400:          }
                    401:        OB_PUTCP (digit_buffer);
                    402:        return;
                    403:       }
                    404: #endif
                    405:     case POINTER_TYPE:
                    406:       value = TREE_OPERAND (value, 0);
                    407:       if (TREE_CODE (value) == VAR_DECL)
                    408:        {
                    409:          my_friendly_assert (DECL_NAME (value) != 0, 245);
                    410:          build_overload_identifier (DECL_NAME (value));
                    411:          return;
                    412:        }
                    413:       else if (TREE_CODE (value) == FUNCTION_DECL)
                    414:        {
                    415:          my_friendly_assert (DECL_NAME (value) != 0, 246);
                    416:          build_overload_identifier (DECL_NAME (value));
                    417:          return;
                    418:        }
                    419:       else
                    420:        my_friendly_abort (71);
                    421:       break; /* not really needed */
                    422: 
                    423:     default:
                    424:       sorry ("conversion of %s as template parameter",
                    425:             tree_code_name [(int) TREE_CODE (type)]);
                    426:       my_friendly_abort (72);
                    427:     }
                    428: }
                    429: 
                    430: static void
                    431: build_overload_identifier (name)
                    432:      tree name;
                    433: {
                    434:   if (IDENTIFIER_TEMPLATE (name))
                    435:     {
                    436:       tree template, parmlist, arglist, tname;
                    437:       int i, nparms;
                    438:       template = IDENTIFIER_TEMPLATE (name);
                    439:       arglist = TREE_VALUE (template);
                    440:       template = TREE_PURPOSE (template);
                    441:       tname = DECL_NAME (template);
                    442:       parmlist = DECL_ARGUMENTS (template);
                    443:       nparms = TREE_VEC_LENGTH (parmlist);
                    444:       OB_PUTC ('t');
                    445:       icat (IDENTIFIER_LENGTH (tname));
                    446:       OB_PUTID (tname);
                    447:       icat (nparms);
                    448:       for (i = 0; i < nparms; i++)
                    449:        {
                    450:          tree parm = TREE_VEC_ELT (parmlist, i);
                    451:          tree arg = TREE_VEC_ELT (arglist, i);
                    452:          if (TREE_CODE (parm) == IDENTIFIER_NODE)
                    453:            {
                    454:              /* This parameter is a type.  */
                    455:              OB_PUTC ('Z');
                    456:              build_overload_name (arg, 0, 0);
                    457:            }
                    458:          else
                    459:            {
                    460:              /* It's a PARM_DECL.  */
                    461:              build_overload_name (TREE_TYPE (parm), 0, 0);
                    462:              build_overload_value (parm, arg);
                    463:            }
                    464:        }
                    465:     }
                    466:   else
                    467:     {
                    468:       icat (IDENTIFIER_LENGTH (name));
                    469:       OB_PUTID (name);
                    470:     }
                    471: }
                    472: 
                    473: /* Given a list of parameters in PARMTYPES, create an unambiguous
                    474:    overload string. Should distinguish any type that C (or C++) can
                    475:    distinguish. I.e., pointers to functions are treated correctly.
                    476: 
                    477:    Caller must deal with whether a final `e' goes on the end or not.
                    478: 
                    479:    Any default conversions must take place before this function
                    480:    is called.
                    481: 
                    482:    BEGIN and END control initialization and finalization of the
                    483:    obstack where we build the string.  */
                    484: 
                    485: char *
                    486: build_overload_name (parmtypes, begin, end)
                    487:      tree parmtypes;
                    488:      int begin, end;
                    489: {
                    490:   int just_one;
                    491:   tree parmtype;
                    492: 
                    493:   if (begin) OB_INIT ();
                    494: 
                    495:   if (just_one = (TREE_CODE (parmtypes) != TREE_LIST))
                    496:     {
                    497:       parmtype = parmtypes;
                    498:       goto only_one;
                    499:     }
                    500: 
                    501:   while (parmtypes)
                    502:     {
                    503:       parmtype = TREE_VALUE (parmtypes);
                    504: 
                    505:     only_one:
                    506: 
                    507:       if (! nofold)
                    508:        {
                    509:          if (! just_one)
                    510:            /* Every argument gets counted.  */
                    511:            typevec[maxtype++] = parmtype;
                    512: 
                    513:          if (TREE_USED (parmtype))
                    514:            {
                    515:              if (! just_one && parmtype == typevec[maxtype-2])
                    516:                nrepeats++;
                    517:              else
                    518:                {
                    519:                  if (nrepeats)
                    520:                    flush_repeats (parmtype);
                    521:                  if (! just_one && TREE_CHAIN (parmtypes)
                    522:                      && parmtype == TREE_VALUE (TREE_CHAIN (parmtypes)))
                    523:                    nrepeats++;
                    524:                  else
                    525:                    {
                    526:                      int tindex = 0;
                    527: 
                    528:                      while (typevec[tindex] != parmtype)
                    529:                        tindex++;
                    530:                      OB_PUTC ('T');
                    531:                      icat (tindex);
                    532:                      if (tindex > 9)
                    533:                        OB_PUTC ('_');
                    534:                    }
                    535:                }
                    536:              goto next;
                    537:            }
                    538:          if (nrepeats)
                    539:            flush_repeats (typevec[maxtype-2]);
                    540:          if (! just_one
                    541:              /* Only cache types which take more than one character.  */
                    542:              && (parmtype != TYPE_MAIN_VARIANT (parmtype)
                    543:                  || (TREE_CODE (parmtype) != INTEGER_TYPE
                    544:                      && TREE_CODE (parmtype) != REAL_TYPE)))
                    545:            TREE_USED (parmtype) = 1;
                    546:        }
                    547: 
                    548:       if (TYPE_PTRMEMFUNC_P (parmtype))
                    549:        parmtype = TYPE_PTRMEMFUNC_FN_TYPE (parmtype);
                    550: 
                    551:       if (TREE_READONLY (parmtype))
                    552:        OB_PUTC ('C');
                    553:       if (TREE_CODE (parmtype) == INTEGER_TYPE
                    554:          && TYPE_MAIN_VARIANT (parmtype) == unsigned_type (TYPE_MAIN_VARIANT (parmtype)))
                    555:        OB_PUTC ('U');
                    556:       if (TYPE_VOLATILE (parmtype))
                    557:        OB_PUTC ('V');
                    558: 
                    559:       switch (TREE_CODE (parmtype))
                    560:        {
                    561:        case OFFSET_TYPE:
                    562:          OB_PUTC ('O');
                    563:          build_overload_name (TYPE_OFFSET_BASETYPE (parmtype), 0, 0);
                    564:          OB_PUTC ('_');
                    565:          build_overload_name (TREE_TYPE (parmtype), 0, 0);
                    566:          break;
                    567: 
                    568:        case REFERENCE_TYPE:
                    569:          OB_PUTC ('R');
                    570:          goto more;
                    571: 
                    572:        case ARRAY_TYPE:
                    573: #if PARM_CAN_BE_ARRAY_TYPE
                    574:          {
                    575:            tree length;
                    576: 
                    577:            OB_PUTC ('A');
                    578:            if (TYPE_DOMAIN (parmtype) == NULL_TREE)
                    579:              {
                    580:                error ("parameter type with unspecified array bounds invalid");
                    581:                icat (1);
                    582:              }
                    583:            else
                    584:              {
                    585:                length = array_type_nelts (parmtype);
                    586:                if (TREE_CODE (length) == INTEGER_CST)
                    587:                  icat (TREE_INT_CST_LOW (length) + 1);
                    588:              }
                    589:            OB_PUTC ('_');
                    590:            goto more;
                    591:          }
                    592: #else
                    593:          OB_PUTC ('P');
                    594:          goto more;
                    595: #endif
                    596: 
                    597:        case POINTER_TYPE:
                    598:          OB_PUTC ('P');
                    599:        more:
                    600:          build_overload_name (TREE_TYPE (parmtype), 0, 0);
                    601:          break;
                    602: 
                    603:        case FUNCTION_TYPE:
                    604:        case METHOD_TYPE:
                    605:          {
                    606:            tree firstarg = TYPE_ARG_TYPES (parmtype);
                    607:            /* Otherwise have to implement reentrant typevecs,
                    608:               unmark and remark types, etc.  */
                    609:            int old_nofold = nofold;
                    610:            nofold = 1;
                    611: 
                    612:            if (nrepeats)
                    613:              flush_repeats (typevec[maxtype-1]);
                    614: 
                    615:            /* @@ It may be possible to pass a function type in
                    616:               which is not preceded by a 'P'.  */
                    617:            if (TREE_CODE (parmtype) == FUNCTION_TYPE)
                    618:              {
                    619:                OB_PUTC ('F');
                    620:                if (firstarg == NULL_TREE)
                    621:                  OB_PUTC ('e');
                    622:                else if (firstarg == void_list_node)
                    623:                  OB_PUTC ('v');
                    624:                else
                    625:                  build_overload_name (firstarg, 0, 0);
                    626:              }
                    627:            else
                    628:              {
                    629:                int constp = TYPE_READONLY (TREE_TYPE (TREE_VALUE (firstarg)));
                    630:                int volatilep = TYPE_VOLATILE (TREE_TYPE (TREE_VALUE (firstarg)));
                    631:                OB_PUTC ('M');
                    632:                firstarg = TREE_CHAIN (firstarg);
                    633: 
                    634:                build_overload_name (TYPE_METHOD_BASETYPE (parmtype), 0, 0);
                    635:                if (constp)
                    636:                  OB_PUTC ('C');
                    637:                if (volatilep)
                    638:                  OB_PUTC ('V');
                    639: 
                    640:                /* For cfront 2.0 compatibility.  */
                    641:                OB_PUTC ('F');
                    642: 
                    643:                if (firstarg == NULL_TREE)
                    644:                  OB_PUTC ('e');
                    645:                else if (firstarg == void_list_node)
                    646:                  OB_PUTC ('v');
                    647:                else
                    648:                  build_overload_name (firstarg, 0, 0);
                    649:              }
                    650: 
                    651:            /* Separate args from return type.  */
                    652:            OB_PUTC ('_');
                    653:            build_overload_name (TREE_TYPE (parmtype), 0, 0);
                    654:            nofold = old_nofold;
                    655:            break;
                    656:          }
                    657: 
                    658:        case INTEGER_TYPE:
                    659:          parmtype = TYPE_MAIN_VARIANT (parmtype);
                    660:          if (parmtype == integer_type_node
                    661:              || parmtype == unsigned_type_node)
                    662:            OB_PUTC ('i');
                    663:          else if (parmtype == long_integer_type_node
                    664:                   || parmtype == long_unsigned_type_node)
                    665:            OB_PUTC ('l');
                    666:          else if (parmtype == short_integer_type_node
                    667:                   || parmtype == short_unsigned_type_node)
                    668:            OB_PUTC ('s');
                    669:          else if (parmtype == signed_char_type_node)
                    670:            {
                    671:              OB_PUTC ('S');
                    672:              OB_PUTC ('c');
                    673:            }
                    674:          else if (parmtype == char_type_node
                    675:                   || parmtype == unsigned_char_type_node)
                    676:            OB_PUTC ('c');
                    677:          else if (parmtype == wchar_type_node)
                    678:            OB_PUTC ('w');
                    679:          else if (parmtype == long_long_integer_type_node
                    680:              || parmtype == long_long_unsigned_type_node)
                    681:            OB_PUTC ('x');
                    682: #if 0
                    683:          /* it would seem there is no way to enter these in source code,
                    684:             yet.  (mrs) */
                    685:          else if (parmtype == long_long_long_integer_type_node
                    686:              || parmtype == long_long_long_unsigned_type_node)
                    687:            OB_PUTC ('q');
                    688: #endif
                    689:          else
                    690:            my_friendly_abort (73);
                    691:          break;
                    692: 
                    693:        case REAL_TYPE:
                    694:          parmtype = TYPE_MAIN_VARIANT (parmtype);
                    695:          if (parmtype == long_double_type_node)
                    696:            OB_PUTC ('r');
                    697:          else if (parmtype == double_type_node)
                    698:            OB_PUTC ('d');
                    699:          else if (parmtype == float_type_node)
                    700:            OB_PUTC ('f');
                    701:          else my_friendly_abort (74);
                    702:          break;
                    703: 
                    704:        case VOID_TYPE:
                    705:          if (! just_one)
                    706:            {
                    707: #if 0
                    708:              extern tree void_list_node;
                    709: 
                    710:              /* See if anybody is wasting memory.  */
                    711:              my_friendly_assert (parmtypes == void_list_node, 247);
                    712: #endif
                    713:              /* This is the end of a parameter list.  */
                    714:              if (end) OB_FINISH ();
                    715:              return (char *)obstack_base (&scratch_obstack);
                    716:            }
                    717:          OB_PUTC ('v');
                    718:          break;
                    719: 
                    720:        case ERROR_MARK:        /* not right, but nothing is anyway */
                    721:          break;
                    722: 
                    723:          /* have to do these */
                    724:        case UNION_TYPE:
                    725:        case RECORD_TYPE:
                    726:          if (! just_one)
                    727:            /* Make this type signature look incompatible
                    728:               with AT&T.  */
                    729:            OB_PUTC ('G');
                    730:          goto common;
                    731:        case ENUMERAL_TYPE:
                    732:        common:
                    733:          {
                    734:            tree name = TYPE_NAME (parmtype);
                    735:            int i = 1;
                    736: 
                    737:            if (TREE_CODE (name) == TYPE_DECL)
                    738:              {
                    739:                tree context = name;
                    740:                while (DECL_CONTEXT (context))
                    741:                  {
                    742:                    i += 1;
                    743:                    context = DECL_CONTEXT (context);
                    744:                    if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')
                    745:                      context = TYPE_NAME (context);
                    746:                  }
                    747:                name = DECL_NAME (name);
                    748:              }
                    749:            my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 248);
                    750:            if (i > 1)
                    751:              {
                    752:                OB_PUTC ('Q');
                    753:                if (i > 9)
                    754:                  OB_PUTC ('_');
                    755:                icat (i);
                    756:                if (i > 9)
                    757:                  OB_PUTC ('_');
                    758:                build_overload_nested_name (TYPE_NAME (parmtype));
                    759:              }
                    760:            else
                    761:              build_overload_identifier (name);
                    762:            break;
                    763:          }
                    764: 
                    765:        case UNKNOWN_TYPE:
                    766:          /* This will take some work.  */
                    767:          OB_PUTC ('?');
                    768:          break;
                    769: 
                    770:        case TEMPLATE_TYPE_PARM:
                    771:        case TEMPLATE_CONST_PARM:
                    772:         case UNINSTANTIATED_P_TYPE:
                    773:          /* We don't ever want this output, but it's inconvenient not to
                    774:             be able to build the string.  This should cause assembler
                    775:             errors we'll notice.  */
                    776:          {
                    777:            static int n;
                    778:            sprintf (digit_buffer, " *%d", n++);
                    779:            OB_PUTCP (digit_buffer);
                    780:          }
                    781:          break;
                    782: 
                    783:        default:
                    784:          my_friendly_abort (75);
                    785:        }
                    786: 
                    787:     next:
                    788:       if (just_one) break;
                    789:       parmtypes = TREE_CHAIN (parmtypes);
                    790:     }
                    791:   if (! just_one)
                    792:     {
                    793:       if (nrepeats)
                    794:        flush_repeats (typevec[maxtype-1]);
                    795: 
                    796:       /* To get here, parms must end with `...'. */
                    797:       OB_PUTC ('e');
                    798:     }
                    799: 
                    800:   if (end) OB_FINISH ();
                    801:   return (char *)obstack_base (&scratch_obstack);
                    802: }
                    803: 
                    804: /* Generate an identifier that encodes the (ANSI) exception TYPE. */
                    805: 
                    806: /* This should be part of `ansi_opname', or at least be defined by the std.  */
                    807: #define EXCEPTION_NAME_PREFIX "__ex"
                    808: #define EXCEPTION_NAME_LENGTH 4
                    809: 
                    810: tree
                    811: cplus_exception_name (type)
                    812:      tree type;
                    813: {
                    814:   OB_INIT ();
                    815:   OB_PUTS (EXCEPTION_NAME_PREFIX);
                    816:   return get_identifier (build_overload_name (type, 0, 1));
                    817: }
                    818: 
                    819: /* Change the name of a function definition so that it may be
                    820:    overloaded. NAME is the name of the function to overload,
                    821:    PARMS is the parameter list (which determines what name the
                    822:    final function obtains).
                    823: 
                    824:    FOR_METHOD is 1 if this overload is being performed
                    825:    for a method, rather than a function type.  It is 2 if
                    826:    this overload is being performed for a constructor.  */
                    827: tree
                    828: build_decl_overload (dname, parms, for_method)
                    829:      tree dname;
                    830:      tree parms;
                    831:      int for_method;
                    832: {
                    833:   char *name = IDENTIFIER_POINTER (dname);
                    834: 
                    835:   if (dname == ansi_opname[(int) NEW_EXPR]
                    836:       && parms != NULL_TREE
                    837:       && TREE_CODE (parms) == TREE_LIST
                    838:       && TREE_VALUE (parms) == sizetype
                    839:       && TREE_CHAIN (parms) == void_list_node)
                    840:     return get_identifier ("__builtin_new");
                    841:   else if (dname == ansi_opname[(int) DELETE_EXPR]
                    842:           && parms != NULL_TREE
                    843:           && TREE_CODE (parms) == TREE_LIST
                    844:           && TREE_VALUE (parms) == ptr_type_node
                    845:           && TREE_CHAIN (parms) == void_list_node)
                    846:     return get_identifier ("__builtin_delete");
                    847:   else if (dname == ansi_opname[(int) DELETE_EXPR]
                    848:           && parms != NULL_TREE
                    849:           && TREE_CODE (parms) == TREE_LIST
                    850:           && TREE_VALUE (parms) == ptr_type_node
                    851:           && TREE_CHAIN (parms) != NULL_TREE
                    852:           && TREE_CODE (TREE_CHAIN (parms)) == TREE_LIST
                    853:           && TREE_VALUE (TREE_CHAIN (parms)) == sizetype
                    854:           && TREE_CHAIN (TREE_CHAIN (parms)) == void_list_node)
                    855:     return get_identifier ("__builtin_delete");
                    856: 
                    857:   OB_INIT ();
                    858:   if (for_method != 2)
                    859:     OB_PUTCP (name);
                    860:   /* Otherwise, we can divine that this is a constructor,
                    861:      and figure out its name without any extra encoding.  */
                    862: 
                    863:   OB_PUTC2 ('_', '_');
                    864:   if (for_method)
                    865:     {
                    866: #if 0
                    867:       /* We can get away without doing this.  */
                    868:       OB_PUTC ('M');
                    869: #endif
                    870:       parms = temp_tree_cons (NULL_TREE, TREE_TYPE (TREE_VALUE (parms)), TREE_CHAIN (parms));
                    871:     }
                    872:   else
                    873:     OB_PUTC ('F');
                    874: 
                    875:   if (parms == NULL_TREE)
                    876:     OB_PUTC2 ('e', '\0');
                    877:   else if (parms == void_list_node)
                    878:     OB_PUTC2 ('v', '\0');
                    879:   else
                    880:     {
                    881:       ALLOCATE_TYPEVEC (parms);
                    882:       nofold = 0;
                    883:       if (for_method)
                    884:        {
                    885:          build_overload_name (TREE_VALUE (parms), 0, 0);
                    886: 
                    887:          typevec[maxtype++] = TREE_VALUE (parms);
                    888:          TREE_USED (TREE_VALUE (parms)) = 1;
                    889: 
                    890:          if (TREE_CHAIN (parms))
                    891:            build_overload_name (TREE_CHAIN (parms), 0, 1);
                    892:          else
                    893:            OB_PUTC2 ('e', '\0');
                    894:        }
                    895:       else
                    896:        build_overload_name (parms, 0, 1);
                    897:       DEALLOCATE_TYPEVEC (parms);
                    898:     }
                    899:   {
                    900:     tree n = get_identifier (obstack_base (&scratch_obstack));
                    901:     if (IDENTIFIER_OPNAME_P (dname))
                    902:       IDENTIFIER_OPNAME_P (n) = 1;
                    903:     return n;
                    904:   }
                    905: }
                    906: 
                    907: /* Build an overload name for the type expression TYPE.  */
                    908: tree
                    909: build_typename_overload (type)
                    910:      tree type;
                    911: {
                    912:   tree id;
                    913: 
                    914:   OB_INIT ();
                    915:   OB_PUTID (ansi_opname[(int) TYPE_EXPR]);
                    916:   nofold = 1;
                    917:   build_overload_name (type, 0, 1);
                    918:   id = get_identifier (obstack_base (&scratch_obstack));
                    919:   IDENTIFIER_OPNAME_P (id) = 1;
                    920:   return id;
                    921: }
                    922: 
                    923: #ifndef NO_DOLLAR_IN_LABEL
                    924: #define T_DESC_FORMAT "TD$"
                    925: #define I_DESC_FORMAT "ID$"
                    926: #define M_DESC_FORMAT "MD$"
                    927: #else
                    928: #if !defined(NO_DOT_IN_LABEL)
                    929: #define T_DESC_FORMAT "TD."
                    930: #define I_DESC_FORMAT "ID."
                    931: #define M_DESC_FORMAT "MD."
                    932: #else
                    933: #define T_DESC_FORMAT "__t_desc_"
                    934: #define I_DESC_FORMAT "__i_desc_"
                    935: #define M_DESC_FORMAT "__m_desc_"
                    936: #endif
                    937: #endif
                    938: 
                    939: /* Build an overload name for the type expression TYPE.  */
                    940: tree
                    941: build_t_desc_overload (type)
                    942:      tree type;
                    943: {
                    944:   OB_INIT ();
                    945:   OB_PUTS (T_DESC_FORMAT);
                    946:   nofold = 1;
                    947: 
                    948: #if 0
                    949:   /* Use a different format if the type isn't defined yet.  */
                    950:   if (TYPE_SIZE (type) == NULL_TREE)
                    951:     {
                    952:       char *p;
                    953:       int changed;
                    954: 
                    955:       for (p = tname; *p; p++)
                    956:        if (isupper (*p))
                    957:          {
                    958:            changed = 1;
                    959:            *p = tolower (*p);
                    960:          }
                    961:       /* If there's no change, we have an inappropriate T_DESC_FORMAT.  */
                    962:       my_friendly_assert (changed != 0, 249);
                    963:     }
                    964: #endif
                    965: 
                    966:   build_overload_name (type, 0, 1);
                    967:   return get_identifier (obstack_base (&scratch_obstack));
                    968: }
                    969: 
                    970: /* Top-level interface to explicit overload requests. Allow NAME
                    971:    to be overloaded. Error if NAME is already declared for the current
                    972:    scope. Warning if function is redundantly overloaded. */
                    973: 
                    974: void
                    975: declare_overloaded (name)
                    976:      tree name;
                    977: {
                    978: #ifdef NO_AUTO_OVERLOAD
                    979:   if (is_overloaded (name))
                    980:     warning ("function `%s' already declared overloaded",
                    981:             IDENTIFIER_POINTER (name));
                    982:   else if (IDENTIFIER_GLOBAL_VALUE (name))
                    983:     error ("overloading function `%s' that is already defined",
                    984:           IDENTIFIER_POINTER (name));
                    985:   else
                    986:     {
                    987:       TREE_OVERLOADED (name) = 1;
                    988:       IDENTIFIER_GLOBAL_VALUE (name) = build_tree_list (name, NULL_TREE);
                    989:       TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (name)) = unknown_type_node;
                    990:     }
                    991: #else
                    992:   if (current_lang_name == lang_name_cplusplus)
                    993:     {
                    994:       if (0)
                    995:        warning ("functions are implicitly overloaded in C++");
                    996:     }
                    997:   else if (current_lang_name == lang_name_c)
                    998:     error ("overloading function `%s' cannot be done in C language context");
                    999:   else
                   1000:     my_friendly_abort (76);
                   1001: #endif
                   1002: }
                   1003: 
                   1004: #ifdef NO_AUTO_OVERLOAD
                   1005: /* Check to see if NAME is overloaded. For first approximation,
                   1006:    check to see if its TREE_OVERLOADED is set.  This is used on
                   1007:    IDENTIFIER nodes.  */
                   1008: int
                   1009: is_overloaded (name)
                   1010:      tree name;
                   1011: {
                   1012:   /* @@ */
                   1013:   return (TREE_OVERLOADED (name)
                   1014:          && (! IDENTIFIER_CLASS_VALUE (name) || current_class_type == 0)
                   1015:          && ! IDENTIFIER_LOCAL_VALUE (name));
                   1016: }
                   1017: #endif
                   1018: 
                   1019: /* Given a tree_code CODE, and some arguments (at least one),
                   1020:    attempt to use an overloaded operator on the arguments.
                   1021: 
                   1022:    For unary operators, only the first argument need be checked.
                   1023:    For binary operators, both arguments may need to be checked.
                   1024: 
                   1025:    Member functions can convert class references to class pointers,
                   1026:    for one-level deep indirection.  More than that is not supported.
                   1027:    Operators [](), ()(), and ->() must be member functions.
                   1028: 
                   1029:    We call function call building calls with nonzero complain if
                   1030:    they are our only hope.  This is true when we see a vanilla operator
                   1031:    applied to something of aggregate type.  If this fails, we are free to
                   1032:    return `error_mark_node', because we will have reported the error.
                   1033: 
                   1034:    Operators NEW and DELETE overload in funny ways: operator new takes
                   1035:    a single `size' parameter, and operator delete takes a pointer to the
                   1036:    storage being deleted.  When overloading these operators, success is
                   1037:    assumed.  If there is a failure, report an error message and return
                   1038:    `error_mark_node'.  */
                   1039: 
                   1040: /* NOSTRICT */
                   1041: tree
                   1042: build_opfncall (code, flags, xarg1, xarg2, arg3)
                   1043:      enum tree_code code;
                   1044:      int flags;
                   1045:      tree xarg1, xarg2, arg3;
                   1046: {
                   1047:   tree rval = 0;
                   1048:   tree arg1, arg2;
                   1049:   tree type1, type2, fnname;
                   1050:   tree fields1 = 0, parms = 0;
                   1051:   tree global_fn;
                   1052:   int try_second;
                   1053:   int binary_is_unary;
                   1054: 
                   1055:   if (xarg1 == error_mark_node)
                   1056:     return error_mark_node;
                   1057: 
                   1058:   if (code == COND_EXPR)
                   1059:     {
                   1060:       if (TREE_CODE (xarg2) == ERROR_MARK
                   1061:          || TREE_CODE (arg3) == ERROR_MARK)
                   1062:        return error_mark_node;
                   1063:     }
                   1064:   if (code == COMPONENT_REF)
                   1065:     if (TREE_CODE (TREE_TYPE (xarg1)) == POINTER_TYPE)
                   1066:       return rval;
                   1067: 
                   1068:   /* First, see if we can work with the first argument */
                   1069:   type1 = TREE_TYPE (xarg1);
                   1070: 
                   1071:   /* Some tree codes have length > 1, but we really only want to
                   1072:      overload them if their first argument has a user defined type.  */
                   1073:   switch (code)
                   1074:     {
                   1075:     case PREINCREMENT_EXPR:
                   1076:     case PREDECREMENT_EXPR:
                   1077:     case POSTINCREMENT_EXPR:
                   1078:     case POSTDECREMENT_EXPR:
                   1079:     case COMPONENT_REF:
                   1080:       binary_is_unary = 1;
                   1081:       try_second = 0;
                   1082:       break;
                   1083: 
                   1084:       /* ARRAY_REFs and CALL_EXPRs must overload successfully.
                   1085:         If they do not, return error_mark_node instead of NULL_TREE.  */
                   1086:     case ARRAY_REF:
                   1087:       if (xarg2 == error_mark_node)
                   1088:        return error_mark_node;
                   1089:     case CALL_EXPR:
                   1090:       rval = error_mark_node;
                   1091:       binary_is_unary = 0;
                   1092:       try_second = 0;
                   1093:       break;
                   1094: 
                   1095:     case NEW_EXPR:
                   1096:       {
                   1097:        /* For operators `new' (`delete'), only check visibility
                   1098:           if we are in a constructor (destructor), and we are
                   1099:           allocating for that constructor's (destructor's) type.  */
                   1100: 
                   1101:        fnname = ansi_opname[(int) NEW_EXPR];
                   1102:        if (flags & LOOKUP_GLOBAL)
                   1103:          return build_overload_call (fnname, tree_cons (NULL_TREE, xarg2, arg3),
                   1104:                                      flags & LOOKUP_COMPLAIN,
                   1105:                                      (struct candidate *)0);
                   1106: 
                   1107:        if (current_function_decl == NULL_TREE
                   1108:            || !DECL_CONSTRUCTOR_P (current_function_decl)
                   1109:            || current_class_type != TYPE_MAIN_VARIANT (type1))
                   1110:          flags = LOOKUP_COMPLAIN;
                   1111:        rval = build_method_call (build1 (NOP_EXPR, xarg1, error_mark_node),
                   1112:                                  fnname, tree_cons (NULL_TREE, xarg2, arg3),
                   1113:                                  NULL_TREE, flags);
                   1114:        if (rval == error_mark_node)
                   1115:          /* User might declare fancy operator new, but invoke it
                   1116:             like standard one.  */
                   1117:          return rval;
                   1118: 
                   1119:        TREE_TYPE (rval) = xarg1;
                   1120:        TREE_CALLS_NEW (rval) = 1;
                   1121:        return rval;
                   1122:       }
                   1123:       break;
                   1124: 
                   1125:     case DELETE_EXPR:
                   1126:       {
                   1127:        /* See comment above.  */
                   1128: 
                   1129:        fnname = ansi_opname[(int) DELETE_EXPR];
                   1130:        if (flags & LOOKUP_GLOBAL)
                   1131:          return build_overload_call (fnname,
                   1132:                                      tree_cons (NULL_TREE, xarg1,
                   1133:                                                 build_tree_list (NULL_TREE, xarg2)),
                   1134:                                      flags & LOOKUP_COMPLAIN,
                   1135:                                      (struct candidate *)0);
                   1136: 
                   1137:        if (current_function_decl == NULL_TREE
                   1138:            || !DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (current_function_decl))
                   1139:            || current_class_type != TYPE_MAIN_VARIANT (type1))
                   1140:          flags = LOOKUP_COMPLAIN;
                   1141:        rval = build_method_call (build1 (NOP_EXPR, TREE_TYPE (xarg1),
                   1142:                                          error_mark_node),
                   1143:                                  fnname, tree_cons (NULL_TREE, xarg1,
                   1144:                                                     build_tree_list (NULL_TREE, xarg2)),
                   1145:                                  NULL_TREE, flags);
                   1146:        /* This happens when the user mis-declares `operator delete'.
                   1147:           Should now be impossible.  */
                   1148:        my_friendly_assert (rval != error_mark_node, 250);
                   1149:        TREE_TYPE (rval) = void_type_node;
                   1150:        return rval;
                   1151:       }
                   1152:       break;
                   1153: 
                   1154:     default:
                   1155:       binary_is_unary = 0;
                   1156:       try_second = tree_code_length [(int) code] == 2;
                   1157:       if (try_second && xarg2 == error_mark_node)
                   1158:        return error_mark_node;
                   1159:       break;
                   1160:     }
                   1161: 
                   1162:   if (try_second && xarg2 == error_mark_node)
                   1163:     return error_mark_node;
                   1164: 
                   1165:   /* What ever it was, we do not know how to deal with it.  */
                   1166:   if (type1 == NULL_TREE)
                   1167:     return rval;
                   1168: 
                   1169:   if (TREE_CODE (type1) == OFFSET_TYPE)
                   1170:     type1 = TREE_TYPE (type1);
                   1171: 
                   1172:   if (TREE_CODE (type1) == REFERENCE_TYPE)
                   1173:     {
                   1174:       arg1 = convert_from_reference (xarg1);
                   1175:       type1 = TREE_TYPE (arg1);
                   1176:     }
                   1177:   else
                   1178:     {
                   1179:       arg1 = xarg1;
                   1180:     }
                   1181: 
                   1182:   if (!IS_AGGR_TYPE (type1))
                   1183:     {
                   1184:       /* Try to fail. First, fail if unary */
                   1185:       if (! try_second)
                   1186:        return rval;
                   1187:       /* Second, see if second argument is non-aggregate. */
                   1188:       type2 = TREE_TYPE (xarg2);
                   1189:       if (TREE_CODE (type2) == OFFSET_TYPE)
                   1190:        type2 = TREE_TYPE (type2);
                   1191:       if (TREE_CODE (type2) == REFERENCE_TYPE)
                   1192:        {
                   1193:          arg2 = convert_from_reference (xarg2);
                   1194:          type2 = TREE_TYPE (arg2);
                   1195:        }
                   1196:       else
                   1197:        {
                   1198:          arg2 = xarg2;
                   1199:        }
                   1200: 
                   1201:       if (!IS_AGGR_TYPE (type2))
                   1202:        return rval;
                   1203:       try_second = 0;
                   1204:     }
                   1205: 
                   1206:   if (try_second)
                   1207:     {
                   1208:       /* First arg may succeed; see whether second should.  */
                   1209:       type2 = TREE_TYPE (xarg2);
                   1210:       if (TREE_CODE (type2) == OFFSET_TYPE)
                   1211:        type2 = TREE_TYPE (type2);
                   1212:       if (TREE_CODE (type2) == REFERENCE_TYPE)
                   1213:        {
                   1214:          arg2 = convert_from_reference (xarg2);
                   1215:          type2 = TREE_TYPE (arg2);
                   1216:        }
                   1217:       else
                   1218:        {
                   1219:          arg2 = xarg2;
                   1220:        }
                   1221: 
                   1222:       if (! IS_AGGR_TYPE (type2))
                   1223:        try_second = 0;
                   1224:     }
                   1225: 
                   1226:   if (type1 == unknown_type_node
                   1227:       || (try_second && TREE_TYPE (xarg2) == unknown_type_node))
                   1228:     {
                   1229:       /* This will not be implemented in the foreseeable future.  */
                   1230:       return rval;
                   1231:     }
                   1232: 
                   1233:   if (code == MODIFY_EXPR)
                   1234:     fnname = ansi_assopname[(int) TREE_CODE (arg3)];
                   1235:   else
                   1236:     fnname = ansi_opname[(int) code];
                   1237: 
                   1238:   global_fn = IDENTIFIER_GLOBAL_VALUE (fnname);
                   1239: 
                   1240:   /* This is the last point where we will accept failure.  This
                   1241:      may be too eager if we wish an overloaded operator not to match,
                   1242:      but would rather a normal operator be called on a type-converted
                   1243:      argument.  */
                   1244: 
                   1245:   if (IS_AGGR_TYPE (type1))
                   1246:     {
                   1247:       fields1 = lookup_fnfields (TYPE_BINFO (type1), fnname, 0);
                   1248:       /* ARM $13.4.7, prefix/postfix ++/--.  */
                   1249:       if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
                   1250:        {
                   1251:          xarg2 = integer_zero_node;
                   1252:          binary_is_unary = 0;
                   1253: 
                   1254:          if (fields1)
                   1255:            {
                   1256:              tree t, t2;
                   1257:              int have_postfix = 0;
                   1258: 
                   1259:              /* Look for an `operator++ (int)'.  If they didn't have
                   1260:                 one, then we fall back to the old way of doing things.  */
                   1261:              for (t = TREE_VALUE (fields1); t ; t = TREE_CHAIN (t))
                   1262:                {
                   1263:                  t2 = TYPE_ARG_TYPES (TREE_TYPE (t));
                   1264:                  if (TREE_CHAIN (t2) != NULL_TREE
                   1265:                      && TREE_VALUE (TREE_CHAIN (t2)) == integer_type_node)
                   1266:                    {
                   1267:                      have_postfix = 1;
                   1268:                      break;
                   1269:                    }
                   1270:                }
                   1271: 
                   1272:              if (! have_postfix)
                   1273:                {
                   1274:                  char *op = POSTINCREMENT_EXPR ? "++" : "--";
                   1275: 
                   1276:                  /* There's probably a LOT of code in the world that
                   1277:                     relies upon this old behavior.  So we'll only give this
                   1278:                     warning when we've been given -pedantic.  A few
                   1279:                     releases after 2.4, we'll convert this to be a pedwarn
                   1280:                     or something else more appropriate.  */
                   1281:                  if (pedantic)
                   1282:                    warning ("no `operator%s (int)' declared for postfix `%s'",
                   1283:                             op, op);
                   1284:                  xarg2 = NULL_TREE;
                   1285:                  binary_is_unary = 1;
                   1286:                }
                   1287:            }
                   1288:        }
                   1289:     }
                   1290: 
                   1291:   if (fields1 == NULL_TREE && global_fn == NULL_TREE)
                   1292:     return rval;
                   1293: 
                   1294:   /* If RVAL winds up being `error_mark_node', we will return
                   1295:      that... There is no way that normal semantics of these
                   1296:      operators will succeed.  */
                   1297: 
                   1298:   /* This argument may be an uncommitted OFFSET_REF.  This is
                   1299:      the case for example when dealing with static class members
                   1300:      which are referenced from their class name rather than
                   1301:      from a class instance.  */
                   1302:   if (TREE_CODE (xarg1) == OFFSET_REF
                   1303:       && TREE_CODE (TREE_OPERAND (xarg1, 1)) == VAR_DECL)
                   1304:     xarg1 = TREE_OPERAND (xarg1, 1);
                   1305:   if (try_second && xarg2 && TREE_CODE (xarg2) == OFFSET_REF
                   1306:       && TREE_CODE (TREE_OPERAND (xarg2, 1)) == VAR_DECL)
                   1307:     xarg2 = TREE_OPERAND (xarg2, 1);
                   1308: 
                   1309:   if (global_fn)
                   1310:     flags |= LOOKUP_GLOBAL;
                   1311: 
                   1312:   if (code == CALL_EXPR)
                   1313:     {
                   1314:       /* This can only be a member function.  */
                   1315:       return build_method_call (xarg1, fnname, xarg2,
                   1316:                                NULL_TREE, LOOKUP_NORMAL);
                   1317:     }
                   1318:   else if (tree_code_length[(int) code] == 1 || binary_is_unary)
                   1319:     {
                   1320:       parms = NULL_TREE;
                   1321:       rval = build_method_call (xarg1, fnname, NULL_TREE, NULL_TREE, flags);
                   1322:     }
                   1323:   else if (code == COND_EXPR)
                   1324:     {
                   1325:       parms = tree_cons (0, xarg2, build_tree_list (NULL_TREE, arg3));
                   1326:       rval = build_method_call (xarg1, fnname, parms, NULL_TREE, flags);
                   1327:     }
                   1328:   else if (code == METHOD_CALL_EXPR)
                   1329:     {
                   1330:       /* must be a member function.  */
                   1331:       parms = tree_cons (NULL_TREE, xarg2, arg3);
                   1332:       return build_method_call (xarg1, fnname, parms, NULL_TREE, LOOKUP_NORMAL);
                   1333:     }
                   1334:   else if (fields1)
                   1335:     {
                   1336:       parms = build_tree_list (NULL_TREE, xarg2);
                   1337:       rval = build_method_call (xarg1, fnname, parms, NULL_TREE, flags);
                   1338:     }
                   1339:   else
                   1340:     {
                   1341:       parms = tree_cons (NULL_TREE, xarg1,
                   1342:                         build_tree_list (NULL_TREE, xarg2));
                   1343:       rval = build_overload_call (fnname, parms, flags & LOOKUP_COMPLAIN,
                   1344:                                  (struct candidate *)0);
                   1345:     }
                   1346: 
                   1347:   /* If we did not win, do not lose yet, since type conversion may work.  */
                   1348:   if (TREE_CODE (rval) == ERROR_MARK)
                   1349:     {
                   1350:       if (flags & LOOKUP_COMPLAIN)
                   1351:        return rval;
                   1352:       return 0;
                   1353:     }
                   1354: 
                   1355:   return rval;
                   1356: }
                   1357: 
                   1358: /* This function takes an identifier, ID, and attempts to figure out what
                   1359:    it means. There are a number of possible scenarios, presented in increasing
                   1360:    order of hair:
                   1361: 
                   1362:    1) not in a class's scope
                   1363:    2) in class's scope, member name of the class's method
                   1364:    3) in class's scope, but not a member name of the class
                   1365:    4) in class's scope, member name of a class's variable
                   1366: 
                   1367:    NAME is $1 from the bison rule. It is an IDENTIFIER_NODE.
                   1368:    VALUE is $$ from the bison rule. It is the value returned by lookup_name ($1)
                   1369:    yychar is the pending input character (suitably encoded :-).
                   1370: 
                   1371:    As a last ditch, try to look up the name as a label and return that
                   1372:    address.
                   1373: 
                   1374:    Values which are declared as being of REFERENCE_TYPE are
                   1375:    automatically dereferenced here (as a hack to make the
                   1376:    compiler faster).  */
                   1377: 
                   1378: tree
                   1379: hack_identifier (value, name, yychar)
                   1380:      tree value, name;
                   1381:      int yychar;
                   1382: {
                   1383:   tree type;
                   1384: 
                   1385:   if (TREE_CODE (value) == ERROR_MARK)
                   1386:     {
                   1387:       if (current_class_name)
                   1388:        {
                   1389:          tree fields = lookup_fnfields (TYPE_BINFO (current_class_type), name, 1);
                   1390:          if (fields == error_mark_node)
                   1391:            return error_mark_node;
                   1392:          if (fields)
                   1393:            {
                   1394:              tree fndecl;
                   1395: 
                   1396:              fndecl = TREE_VALUE (fields);
                   1397:              my_friendly_assert (TREE_CODE (fndecl) == FUNCTION_DECL, 251);
                   1398:              if (DECL_CHAIN (fndecl) == NULL_TREE)
                   1399:                {
                   1400:                  warning ("methods cannot be converted to function pointers");
                   1401:                  return fndecl;
                   1402:                }
                   1403:              else
                   1404:                {
                   1405:                  error ("ambiguous request for method pointer `%s'",
                   1406:                         IDENTIFIER_POINTER (name));
                   1407:                  return error_mark_node;
                   1408:                }
                   1409:            }
                   1410:        }
                   1411:       if (flag_labels_ok && IDENTIFIER_LABEL_VALUE (name))
                   1412:        {
                   1413:          return IDENTIFIER_LABEL_VALUE (name);
                   1414:        }
                   1415:       return error_mark_node;
                   1416:     }
                   1417: 
                   1418:   type = TREE_TYPE (value);
                   1419:   if (TREE_CODE (value) == FIELD_DECL)
                   1420:     {
                   1421:       if (current_class_decl == NULL_TREE)
                   1422:        {
                   1423:          error ("request for member `%s' in static member function",
                   1424:                 IDENTIFIER_POINTER (DECL_NAME (value)));
                   1425:          return error_mark_node;
                   1426:        }
                   1427:       TREE_USED (current_class_decl) = 1;
                   1428:       if (yychar == '(')
                   1429:        if (! ((TYPE_LANG_SPECIFIC (type)
                   1430:                && TYPE_OVERLOADS_CALL_EXPR (type))
                   1431:               || (TREE_CODE (type) == REFERENCE_TYPE
                   1432:                   && TYPE_LANG_SPECIFIC (TREE_TYPE (type))
                   1433:                   && TYPE_OVERLOADS_CALL_EXPR (TREE_TYPE (type))))
                   1434:            && TREE_CODE (type) != FUNCTION_TYPE
                   1435:            && TREE_CODE (type) != METHOD_TYPE
                   1436:            && (TREE_CODE (type) != POINTER_TYPE
                   1437:                || (TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE
                   1438:                    && TREE_CODE (TREE_TYPE (type)) != METHOD_TYPE)))
                   1439:          {
                   1440:            error ("component `%s' is not a method",
                   1441:                   IDENTIFIER_POINTER (name));
                   1442:            return error_mark_node;
                   1443:          }
                   1444:       /* Mark so that if we are in a constructor, and then find that
                   1445:         this field was initialized by a base initializer,
                   1446:         we can emit an error message.  */
                   1447:       TREE_USED (value) = 1;
                   1448:       return build_component_ref (C_C_D, name, 0, 1);
                   1449:     }
                   1450: 
                   1451:   if (TREE_CODE (value) == TREE_LIST)
                   1452:     {
                   1453:       tree t = value;
                   1454:       while (t && TREE_CODE (t) == TREE_LIST)
                   1455:        {
                   1456:          assemble_external (TREE_VALUE (t));
                   1457:          TREE_USED (t) = 1;
                   1458:          t = TREE_CHAIN (t);
                   1459:        }
                   1460:     }
                   1461:   else
                   1462:     {
                   1463:       assemble_external (value);
                   1464:       TREE_USED (value) = 1;
                   1465:     }
                   1466: 
                   1467:   if (TREE_CODE_CLASS (TREE_CODE (value)) == 'd' && DECL_NONLOCAL (value))
                   1468:     {
                   1469:       if (DECL_LANG_SPECIFIC (value)
                   1470:          && DECL_CLASS_CONTEXT (value) != current_class_type)
                   1471:        {
                   1472:          tree path;
                   1473:          enum visibility_type visibility;
                   1474:          register tree context
                   1475:            = (TREE_CODE (value) == FUNCTION_DECL && DECL_VIRTUAL_P (value))
                   1476:              ? DECL_CLASS_CONTEXT (value)
                   1477:              : DECL_CONTEXT (value);
                   1478: 
                   1479:          get_base_distance (context, current_class_type, 0, &path);
                   1480:          if (path)
                   1481:            {
                   1482:              visibility = compute_visibility (path, value);
                   1483:              if (visibility != visibility_public)
                   1484:                {
                   1485:                  if (TREE_CODE (value) == VAR_DECL)
                   1486:                    error ("static member `%s' is from private base class",
                   1487:                           IDENTIFIER_POINTER (name));
                   1488:                  else
                   1489:                    error ("enum `%s' is from private base class",
                   1490:                           IDENTIFIER_POINTER (name));
                   1491:                  return error_mark_node;
                   1492:                }
                   1493:            }
                   1494:        }
                   1495:       return value;
                   1496:     }
                   1497:   if (TREE_CODE (value) == TREE_LIST && TREE_NONLOCAL_FLAG (value))
                   1498:     {
                   1499:       if (type == 0)
                   1500:        {
                   1501:          error ("request for member `%s' is ambiguous in multiple inheritance lattice",
                   1502:                 IDENTIFIER_POINTER (name));
                   1503:          return error_mark_node;
                   1504:        }
                   1505: 
                   1506:       return value;
                   1507:     }
                   1508: 
                   1509:   if (TREE_CODE (type) == REFERENCE_TYPE)
                   1510:     {
                   1511:       my_friendly_assert (TREE_CODE (value) == VAR_DECL
                   1512:                          || TREE_CODE (value) == PARM_DECL
                   1513:                          || TREE_CODE (value) == RESULT_DECL, 252);
                   1514:       if (DECL_REFERENCE_SLOT (value))
                   1515:        return DECL_REFERENCE_SLOT (value);
                   1516:     }
                   1517:   return value;
                   1518: }
                   1519: 
                   1520: 
                   1521: /* Given an object OF, and a type conversion operator COMPONENT
                   1522:    build a call to the conversion operator, if a call is requested,
                   1523:    or return the address (as a pointer to member function) if one is not.
                   1524: 
                   1525:    OF can be a TYPE_DECL or any kind of datum that would normally
                   1526:    be passed to `build_component_ref'.  It may also be NULL_TREE,
                   1527:    in which case `current_class_type' and `current_class_decl'
                   1528:    provide default values.
                   1529: 
                   1530:    BASETYPE_PATH, if non-null, is the path of basetypes
                   1531:    to go through before we get the the instance of interest.
                   1532: 
                   1533:    PROTECT says whether we apply C++ scoping rules or not.  */
                   1534: tree
                   1535: build_component_type_expr (of, component, basetype_path, protect)
                   1536:      tree of, component, basetype_path;
                   1537:      int protect;
                   1538: {
                   1539:   tree cname = NULL_TREE;
                   1540:   tree tmp, last;
                   1541:   tree name;
                   1542:   int flags = protect ? LOOKUP_NORMAL : LOOKUP_COMPLAIN;
                   1543: 
                   1544:   if (of)
                   1545:     my_friendly_assert (IS_AGGR_TYPE (TREE_TYPE (of)), 253);
                   1546:   my_friendly_assert (TREE_CODE (component) == TYPE_EXPR, 254);
                   1547: 
                   1548:   tmp = TREE_OPERAND (component, 0);
                   1549:   last = NULL_TREE;
                   1550: 
                   1551:   while (tmp)
                   1552:     {
                   1553:       switch (TREE_CODE (tmp))
                   1554:        {
                   1555:        case CALL_EXPR:
                   1556:          if (last)
                   1557:            TREE_OPERAND (last, 0) = TREE_OPERAND (tmp, 0);
                   1558:          else
                   1559:            TREE_OPERAND (component, 0) = TREE_OPERAND (tmp, 0);
                   1560: 
                   1561:          last = groktypename (build_tree_list (TREE_TYPE (component),
                   1562:                                                TREE_OPERAND (component, 0)));
                   1563:          name = build_typename_overload (last);
                   1564:          TREE_TYPE (name) = last;
                   1565: 
                   1566:          if (TREE_OPERAND (tmp, 0)
                   1567:              && TREE_OPERAND (tmp, 0) != void_list_node)
                   1568:            {
                   1569:              cp_error ("`operator %T' requires empty parameter list", last);
                   1570:              TREE_OPERAND (tmp, 0) = NULL_TREE;
                   1571:            }
                   1572: 
                   1573:          if (of && TREE_CODE (of) != TYPE_DECL)
                   1574:            return build_method_call (of, name, NULL_TREE, NULL_TREE, flags);
                   1575:          else if (of)
                   1576:            {
                   1577:              tree this_this;
                   1578: 
                   1579:              if (current_class_decl == NULL_TREE)
                   1580:                {
                   1581:                  cp_error ("object required for `operator %T' call",
                   1582:                            TREE_TYPE (name));
                   1583:                  return error_mark_node;
                   1584:                }
                   1585: 
                   1586:              this_this = convert_pointer_to (TREE_TYPE (of), current_class_decl);
                   1587:              return build_method_call (this_this, name, NULL_TREE,
                   1588:                                        NULL_TREE, flags | LOOKUP_NONVIRTUAL);
                   1589:            }
                   1590:          else if (current_class_decl)
                   1591:            return build_method_call (tmp, name, NULL_TREE, NULL_TREE, flags);
                   1592: 
                   1593:          cp_error ("object required for `operator %T' call",
                   1594:                    TREE_TYPE (name));
                   1595:          return error_mark_node;
                   1596: 
                   1597:        case INDIRECT_REF:
                   1598:        case ADDR_EXPR:
                   1599:        case ARRAY_REF:
                   1600:          break;
                   1601: 
                   1602:        case SCOPE_REF:
                   1603:          my_friendly_assert (cname == 0, 255);
                   1604:          cname = TREE_OPERAND (tmp, 0);
                   1605:          tmp = TREE_OPERAND (tmp, 1);
                   1606:          break;
                   1607: 
                   1608:        default:
                   1609:          my_friendly_abort (77);
                   1610:        }
                   1611:       last = tmp;
                   1612:       tmp = TREE_OPERAND (tmp, 0);
                   1613:     }
                   1614: 
                   1615:   last = groktypename (build_tree_list (TREE_TYPE (component), TREE_OPERAND (component, 0)));
                   1616:   name = build_typename_overload (last);
                   1617:   TREE_TYPE (name) = last;
                   1618:   if (of && TREE_CODE (of) == TYPE_DECL)
                   1619:     {
                   1620:       if (cname == NULL_TREE)
                   1621:        {
                   1622:          cname = DECL_NAME (of);
                   1623:          of = NULL_TREE;
                   1624:        }
                   1625:       else my_friendly_assert (cname == DECL_NAME (of), 256);
                   1626:     }
                   1627: 
                   1628:   if (of)
                   1629:     {
                   1630:       tree this_this;
                   1631: 
                   1632:       if (current_class_decl == NULL_TREE)
                   1633:        {
                   1634:          cp_error ("object required for `operator %T' call",
                   1635:                    TREE_TYPE (name));
                   1636:          return error_mark_node;
                   1637:        }
                   1638: 
                   1639:       this_this = convert_pointer_to (TREE_TYPE (of), current_class_decl);
                   1640:       return build_component_ref (this_this, name, 0, protect);
                   1641:     }
                   1642:   else if (cname)
                   1643:     return build_offset_ref (cname, name);
                   1644:   else if (current_class_name)
                   1645:     return build_offset_ref (current_class_name, name);
                   1646: 
                   1647:   cp_error ("object required for `operator %T' member reference",
                   1648:            TREE_TYPE (name));
                   1649:   return error_mark_node;
                   1650: }

unix.superglobalmegacorp.com

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