Annotation of GNUtools/cc/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 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.