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

1.1     ! root        1: /* Handle the hair of processing (but not expanding) inline functions.
        !             2:    Also manage function and 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 "class.h"
        !            33: #include "obstack.h"
        !            34: #include <ctype.h>
        !            35: #include "rtl.h"
        !            36: #include "expr.h"
        !            37: #include "output.h"
        !            38: #include "hard-reg-set.h"
        !            39: #include "flags.h"
        !            40: 
        !            41: /* TREE_LIST of the current inline functions that need to be
        !            42:    processed.  */
        !            43: struct pending_inline *pending_inlines;
        !            44: 
        !            45: #define obstack_chunk_alloc xmalloc
        !            46: #define obstack_chunk_free free
        !            47: 
        !            48: /* Obstack where we build text strings for overloading, etc.  */
        !            49: static struct obstack scratch_obstack;
        !            50: static char *scratch_firstobj;
        !            51: 
        !            52: # define OB_INIT() (scratch_firstobj ? (obstack_free (&scratch_obstack, scratch_firstobj), 0) : 0)
        !            53: # define OB_PUTC(C) (obstack_1grow (&scratch_obstack, (C)))
        !            54: # define OB_PUTC2(C1,C2)       \
        !            55:   (obstack_1grow (&scratch_obstack, (C1)), obstack_1grow (&scratch_obstack, (C2)))
        !            56: # define OB_PUTS(S) (obstack_grow (&scratch_obstack, (S), sizeof (S) - 1))
        !            57: # define OB_PUTID(ID)  \
        !            58:   (obstack_grow (&scratch_obstack, IDENTIFIER_POINTER (ID),    \
        !            59:                 IDENTIFIER_LENGTH (ID)))
        !            60: # define OB_PUTCP(S) (obstack_grow (&scratch_obstack, (S), strlen (S)))
        !            61: # define OB_FINISH() (obstack_1grow (&scratch_obstack, '\0'))
        !            62: 
        !            63: #ifdef NO_AUTO_OVERLOAD
        !            64: int is_overloaded ();
        !            65: #endif
        !            66: 
        !            67: void
        !            68: init_method ()
        !            69: {
        !            70:   gcc_obstack_init (&scratch_obstack);
        !            71:   scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0);
        !            72: }
        !            73: 
        !            74: /* This must be large enough to hold any printed integer or floating-point
        !            75:    value.  */
        !            76: static char digit_buffer[128];
        !            77: 
        !            78: /* Move inline function definitions out of structure so that they
        !            79:    can be processed normally.  CNAME is the name of the class
        !            80:    we are working from, METHOD_LIST is the list of method lists
        !            81:    of the structure.  We delete friend methods here, after
        !            82:    saving away their inline function definitions (if any).  */
        !            83: 
        !            84: void
        !            85: do_inline_function_hair (type, friend_list)
        !            86:      tree type, friend_list;
        !            87: {
        !            88:   tree method = TYPE_METHODS (type);
        !            89: 
        !            90:   if (method && TREE_CODE (method) == TREE_VEC)
        !            91:     {
        !            92:       if (TREE_VEC_ELT (method, 0))
        !            93:        method = TREE_VEC_ELT (method, 0);
        !            94:       else
        !            95:        method = TREE_VEC_ELT (method, 1);
        !            96:     }
        !            97: 
        !            98:   while (method)
        !            99:     {
        !           100:       /* Do inline member functions.  */
        !           101:       struct pending_inline *info = DECL_PENDING_INLINE_INFO (method);
        !           102:       if (info)
        !           103:        {
        !           104:          tree args;
        !           105: 
        !           106:          my_friendly_assert (info->fndecl == method, 238);
        !           107:          args = DECL_ARGUMENTS (method);
        !           108:          while (args)
        !           109:            {
        !           110:              DECL_CONTEXT (args) = method;
        !           111:              args = TREE_CHAIN (args);
        !           112:            }
        !           113: 
        !           114:          /* Allow this decl to be seen in global scope.  Don't do this for
        !           115:              local class methods, though.  */
        !           116:          if (! current_function_decl)
        !           117:            IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (method)) = method;
        !           118:        }
        !           119:       method = TREE_CHAIN (method);
        !           120:     }
        !           121:   while (friend_list)
        !           122:     {
        !           123:       tree fndecl = TREE_VALUE (friend_list);
        !           124:       struct pending_inline *info = DECL_PENDING_INLINE_INFO (fndecl);
        !           125:       if (info)
        !           126:        {
        !           127:          tree args;
        !           128: 
        !           129:          my_friendly_assert (info->fndecl == fndecl, 239);
        !           130:          args = DECL_ARGUMENTS (fndecl);
        !           131:          while (args)
        !           132:            {
        !           133:              DECL_CONTEXT (args) = fndecl;
        !           134:              args = TREE_CHAIN (args);
        !           135:            }
        !           136: 
        !           137:          /* Allow this decl to be seen in global scope */
        !           138:          if (! current_function_decl)
        !           139:            IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (fndecl)) = fndecl;
        !           140:        }
        !           141: 
        !           142:       friend_list = TREE_CHAIN (friend_list);
        !           143:     }
        !           144: }
        !           145: 
        !           146: /* Report an argument type mismatch between the best declared function
        !           147:    we could find and the current argument list that we have.  */
        !           148: void
        !           149: report_type_mismatch (cp, parmtypes, name_kind)
        !           150:      struct candidate *cp;
        !           151:      tree parmtypes;
        !           152:      char *name_kind;
        !           153: {
        !           154:   int i = cp->u.bad_arg;
        !           155:   tree ttf, tta;
        !           156:   char *tmp_firstobj;
        !           157: 
        !           158:   switch (i)
        !           159:     {
        !           160:     case -4:
        !           161:       my_friendly_assert (TREE_CODE (cp->function) == TEMPLATE_DECL, 240);
        !           162:       cp_error ("type unification failed for function template `%#D'",
        !           163:                cp->function);
        !           164:       return;
        !           165: 
        !           166:     case -3:
        !           167:       if (TYPE_READONLY (TREE_TYPE (TREE_VALUE (parmtypes))))
        !           168:        cp_error ("call to const %s `%#D' with non-const object", name_kind,
        !           169:                  cp->function);
        !           170:       else
        !           171:        cp_error ("call to non-const %s `%#D' with const object", name_kind,
        !           172:                  cp->function);
        !           173:       return;
        !           174:     case -2:
        !           175:       cp_error ("too few arguments for %s `%#D'", name_kind, cp->function);
        !           176:       return;
        !           177:     case -1:
        !           178:       cp_error ("too many arguments for %s `%#D'", name_kind, cp->function);
        !           179:       return;
        !           180:     case 0:
        !           181:       if (TREE_CODE (TREE_TYPE (cp->function)) == METHOD_TYPE)
        !           182:        {
        !           183:          /* Happens when we have an ambiguous base class.  */
        !           184:          my_friendly_assert (get_binfo (DECL_CLASS_CONTEXT (cp->function),
        !           185:                             TREE_TYPE (TREE_TYPE (TREE_VALUE (parmtypes))), 1) == error_mark_node,
        !           186:                              241);
        !           187:          return;
        !           188:        }
        !           189:     }
        !           190: 
        !           191:   ttf = TYPE_ARG_TYPES (TREE_TYPE (cp->function));
        !           192:   tta = parmtypes;
        !           193: 
        !           194:   while (i-- > 0)
        !           195:     {
        !           196:       ttf = TREE_CHAIN (ttf);
        !           197:       tta = TREE_CHAIN (tta);
        !           198:     }
        !           199: 
        !           200:   OB_INIT ();
        !           201:   OB_PUTS ("bad argument ");
        !           202:   sprintf (digit_buffer, "%d", cp->u.bad_arg
        !           203:           - (TREE_CODE (TREE_TYPE (cp->function)) == METHOD_TYPE)
        !           204:           + 1);
        !           205:   OB_PUTCP (digit_buffer);
        !           206: 
        !           207:   OB_PUTS (" for function `");
        !           208:   OB_PUTCP (decl_as_string (cp->function, 1));
        !           209:   OB_PUTS ("' (type was ");
        !           210: 
        !           211:   /* Reset `i' so that type printing routines do the right thing.  */
        !           212:   if (tta)
        !           213:     {
        !           214:       enum tree_code code = TREE_CODE (TREE_TYPE (TREE_VALUE (tta)));
        !           215:       if (code == ERROR_MARK)
        !           216:        OB_PUTS ("(failed type instantiation)");
        !           217:       else
        !           218:        {
        !           219:          i = (code == FUNCTION_TYPE || code == METHOD_TYPE);
        !           220:          OB_PUTCP (type_as_string (TREE_TYPE (TREE_VALUE (tta)), 1));
        !           221:        }
        !           222:     }
        !           223:   else OB_PUTS ("void");
        !           224:   OB_PUTC (')');
        !           225:   OB_FINISH ();
        !           226: 
        !           227:   tmp_firstobj = (char *)alloca (obstack_object_size (&scratch_obstack));
        !           228:   bcopy (obstack_base (&scratch_obstack), tmp_firstobj,
        !           229:         obstack_object_size (&scratch_obstack));
        !           230:   error (tmp_firstobj);
        !           231: }
        !           232: 
        !           233: /* Here is where overload code starts.  */
        !           234: 
        !           235: /* Array of types seen so far in top-level call to `build_overload_name'.
        !           236:    Allocated and deallocated by caller.  */
        !           237: static tree *typevec;
        !           238: 
        !           239: /* Number of types interned by `build_overload_name' so far.  */
        !           240: static int maxtype;
        !           241: 
        !           242: /* Number of occurrences of last type seen.  */
        !           243: static int nrepeats;
        !           244: 
        !           245: /* Nonzero if we should not try folding parameter types.  */
        !           246: static int nofold;
        !           247: 
        !           248: #define ALLOCATE_TYPEVEC(PARMTYPES) \
        !           249:   do { maxtype = 0, nrepeats = 0; \
        !           250:        typevec = (tree *)alloca (list_length (PARMTYPES) * sizeof (tree)); } while (0)
        !           251: 
        !           252: #define DEALLOCATE_TYPEVEC(PARMTYPES) \
        !           253:   do { tree t = (PARMTYPES); \
        !           254:        while (t) { TREE_USED (TREE_VALUE (t)) = 0; t = TREE_CHAIN (t); } \
        !           255:   } while (0)
        !           256: 
        !           257: /* Code to concatenate an asciified integer to a string.  */
        !           258: static
        !           259: #ifdef __GNUC__
        !           260: __inline
        !           261: #endif
        !           262: void
        !           263: icat (i)
        !           264:      int i;
        !           265: {
        !           266:   /* Handle this case first, to go really quickly.  For many common values,
        !           267:      the result of i/10 below is 1.  */
        !           268:   if (i == 1)
        !           269:     {
        !           270:       OB_PUTC ('1');
        !           271:       return;
        !           272:     }
        !           273: 
        !           274:   if (i < 0)
        !           275:     {
        !           276:       OB_PUTC ('m');
        !           277:       i = -i;
        !           278:     }
        !           279:   if (i < 10)
        !           280:     OB_PUTC ('0' + i);
        !           281:   else
        !           282:     {
        !           283:       icat (i / 10);
        !           284:       OB_PUTC ('0' + (i % 10));
        !           285:     }
        !           286: }
        !           287: 
        !           288: static
        !           289: #ifdef __GNUC__
        !           290: __inline
        !           291: #endif
        !           292: void
        !           293: flush_repeats (type)
        !           294:      tree type;
        !           295: {
        !           296:   int tindex = 0;
        !           297: 
        !           298:   while (typevec[tindex] != type)
        !           299:     tindex++;
        !           300: 
        !           301:   if (nrepeats > 1)
        !           302:     {
        !           303:       OB_PUTC ('N');
        !           304:       icat (nrepeats);
        !           305:       if (nrepeats > 9)
        !           306:        OB_PUTC ('_');
        !           307:     }
        !           308:   else
        !           309:     OB_PUTC ('T');
        !           310:   nrepeats = 0;
        !           311:   icat (tindex);
        !           312:   if (tindex > 9)
        !           313:     OB_PUTC ('_');
        !           314: }
        !           315: 
        !           316: static int numeric_outputed_need_bar;
        !           317: static void build_overload_identifier ();
        !           318: 
        !           319: static void
        !           320: build_overload_nested_name (context)
        !           321:      tree context;
        !           322: {
        !           323:   /* We use DECL_NAME here, because pushtag now sets the DECL_ASSEMBLER_NAME.  */
        !           324:   tree name = DECL_NAME (context);
        !           325:   if (DECL_CONTEXT (context))
        !           326:     {
        !           327:       context = DECL_CONTEXT (context);
        !           328:       if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')
        !           329:        context = TYPE_NAME (context);
        !           330:       build_overload_nested_name (context);
        !           331:     }
        !           332:   build_overload_identifier (name);
        !           333: }
        !           334: 
        !           335: static void
        !           336: build_overload_value (type, value)
        !           337:      tree type, value;
        !           338: {
        !           339:   while (TREE_CODE (value) == NON_LVALUE_EXPR
        !           340:         || TREE_CODE (value) == NOP_EXPR)
        !           341:     value = TREE_OPERAND (value, 0);
        !           342:   my_friendly_assert (TREE_CODE (type) == PARM_DECL, 242);
        !           343:   type = TREE_TYPE (type);
        !           344:   switch (TREE_CODE (type))
        !           345:     {
        !           346:     case INTEGER_TYPE:
        !           347:     case ENUMERAL_TYPE:
        !           348:       {
        !           349:        my_friendly_assert (TREE_CODE (value) == INTEGER_CST, 243);
        !           350:        if (TYPE_PRECISION (value) == 2 * HOST_BITS_PER_WIDE_INT)
        !           351:          {
        !           352:            if (tree_int_cst_lt (value, integer_zero_node))
        !           353:              {
        !           354:                OB_PUTC ('m');
        !           355:                value = build_int_2 (~ TREE_INT_CST_LOW (value),
        !           356:                                     - TREE_INT_CST_HIGH (value));
        !           357:              }
        !           358:            if (TREE_INT_CST_HIGH (value)
        !           359:                != (TREE_INT_CST_LOW (value) >> (HOST_BITS_PER_WIDE_INT - 1)))
        !           360:              {
        !           361:                /* need to print a DImode value in decimal */
        !           362:                sorry ("conversion of long long as PT parameter");
        !           363:              }
        !           364:            /* else fall through to print in smaller mode */
        !           365:          }
        !           366:        /* Wordsize or smaller */
        !           367:        icat (TREE_INT_CST_LOW (value));
        !           368:        return;
        !           369:       }
        !           370:     case BOOLEAN_TYPE:
        !           371:       {
        !           372:        icat (TREE_INT_CST_LOW (value));
        !           373:        return;
        !           374:       }
        !           375: #ifndef REAL_IS_NOT_DOUBLE
        !           376:     case REAL_TYPE:
        !           377:       {
        !           378:        REAL_VALUE_TYPE val;
        !           379:        char *bufp = digit_buffer;
        !           380:        extern char *index ();
        !           381: 
        !           382:        my_friendly_assert (TREE_CODE (value) == REAL_CST, 244);
        !           383:        val = TREE_REAL_CST (value);
        !           384:        if (val < 0)
        !           385:          {
        !           386:            val = -val;
        !           387:            *bufp++ = 'm';
        !           388:          }
        !           389:        sprintf (bufp, "%e", val);
        !           390:        bufp = (char *) index (bufp, 'e');
        !           391:        if (!bufp)
        !           392:          strcat (digit_buffer, "e0");
        !           393:        else
        !           394:          {
        !           395:            char *p;
        !           396:            bufp++;
        !           397:            if (*bufp == '-')
        !           398:              {
        !           399:                *bufp++ = 'm';
        !           400:              }
        !           401:            p = bufp;
        !           402:            if (*p == '+')
        !           403:              p++;
        !           404:            while (*p == '0')
        !           405:              p++;
        !           406:            if (*p == 0)
        !           407:              {
        !           408:                *bufp++ = '0';
        !           409:                *bufp = 0;
        !           410:              }
        !           411:            else if (p != bufp)
        !           412:              {
        !           413:                while (*p)
        !           414:                  *bufp++ = *p++;
        !           415:                *bufp = 0;
        !           416:              }
        !           417:          }
        !           418:        OB_PUTCP (digit_buffer);
        !           419:        return;
        !           420:       }
        !           421: #endif
        !           422:     case POINTER_TYPE:
        !           423:       value = TREE_OPERAND (value, 0);
        !           424:       if (TREE_CODE (value) == VAR_DECL)
        !           425:        {
        !           426:          my_friendly_assert (DECL_NAME (value) != 0, 245);
        !           427:          build_overload_identifier (DECL_NAME (value));
        !           428:          return;
        !           429:        }
        !           430:       else if (TREE_CODE (value) == FUNCTION_DECL)
        !           431:        {
        !           432:          my_friendly_assert (DECL_NAME (value) != 0, 246);
        !           433:          build_overload_identifier (DECL_NAME (value));
        !           434:          return;
        !           435:        }
        !           436:       else
        !           437:        my_friendly_abort (71);
        !           438:       break; /* not really needed */
        !           439: 
        !           440:     default:
        !           441:       sorry ("conversion of %s as template parameter",
        !           442:             tree_code_name [(int) TREE_CODE (type)]);
        !           443:       my_friendly_abort (72);
        !           444:     }
        !           445: }
        !           446: 
        !           447: static void
        !           448: build_overload_identifier (name)
        !           449:      tree name;
        !           450: {
        !           451:   if (IDENTIFIER_TEMPLATE (name))
        !           452:     {
        !           453:       tree template, parmlist, arglist, tname;
        !           454:       int i, nparms;
        !           455:       template = IDENTIFIER_TEMPLATE (name);
        !           456:       arglist = TREE_VALUE (template);
        !           457:       template = TREE_PURPOSE (template);
        !           458:       tname = DECL_NAME (template);
        !           459:       parmlist = DECL_ARGUMENTS (template);
        !           460:       nparms = TREE_VEC_LENGTH (parmlist);
        !           461:       OB_PUTC ('t');
        !           462:       icat (IDENTIFIER_LENGTH (tname));
        !           463:       OB_PUTID (tname);
        !           464:       icat (nparms);
        !           465:       for (i = 0; i < nparms; i++)
        !           466:        {
        !           467:          tree parm = TREE_VALUE (TREE_VEC_ELT (parmlist, i));
        !           468:          tree arg = TREE_VEC_ELT (arglist, i);
        !           469:          if (TREE_CODE (parm) == TYPE_DECL)
        !           470:            {
        !           471:              /* This parameter is a type.  */
        !           472:              OB_PUTC ('Z');
        !           473:              build_overload_name (arg, 0, 0);
        !           474:            }
        !           475:          else
        !           476:            {
        !           477:              /* It's a PARM_DECL.  */
        !           478:              build_overload_name (TREE_TYPE (parm), 0, 0);
        !           479:              build_overload_value (parm, arg);
        !           480:              numeric_outputed_need_bar = 1;
        !           481:            }
        !           482:        }
        !           483:     }
        !           484:   else
        !           485:     {
        !           486:       if (numeric_outputed_need_bar)
        !           487:        {
        !           488:          OB_PUTC ('_');
        !           489:          numeric_outputed_need_bar = 0;
        !           490:        }
        !           491:       icat (IDENTIFIER_LENGTH (name));
        !           492:       OB_PUTID (name);
        !           493:     }
        !           494: }
        !           495: 
        !           496: /* Given a list of parameters in PARMTYPES, create an unambiguous
        !           497:    overload string. Should distinguish any type that C (or C++) can
        !           498:    distinguish. I.e., pointers to functions are treated correctly.
        !           499: 
        !           500:    Caller must deal with whether a final `e' goes on the end or not.
        !           501: 
        !           502:    Any default conversions must take place before this function
        !           503:    is called.
        !           504: 
        !           505:    BEGIN and END control initialization and finalization of the
        !           506:    obstack where we build the string.  */
        !           507: 
        !           508: char *
        !           509: build_overload_name (parmtypes, begin, end)
        !           510:      tree parmtypes;
        !           511:      int begin, end;
        !           512: {
        !           513:   int just_one;
        !           514:   tree parmtype;
        !           515: 
        !           516:   if (begin) OB_INIT ();
        !           517:   numeric_outputed_need_bar = 0;
        !           518: 
        !           519:   if ((just_one = (TREE_CODE (parmtypes) != TREE_LIST)))
        !           520:     {
        !           521:       parmtype = parmtypes;
        !           522:       goto only_one;
        !           523:     }
        !           524: 
        !           525:   while (parmtypes)
        !           526:     {
        !           527:       parmtype = TREE_VALUE (parmtypes);
        !           528: 
        !           529:     only_one:
        !           530: 
        !           531:       if (! nofold)
        !           532:        {
        !           533:          if (! just_one)
        !           534:            /* Every argument gets counted.  */
        !           535:            typevec[maxtype++] = parmtype;
        !           536: 
        !           537:          if (TREE_USED (parmtype))
        !           538:            {
        !           539:              if (! just_one && parmtype == typevec[maxtype-2])
        !           540:                nrepeats++;
        !           541:              else
        !           542:                {
        !           543:                  if (nrepeats)
        !           544:                    flush_repeats (parmtype);
        !           545:                  if (! just_one && TREE_CHAIN (parmtypes)
        !           546:                      && parmtype == TREE_VALUE (TREE_CHAIN (parmtypes)))
        !           547:                    nrepeats++;
        !           548:                  else
        !           549:                    {
        !           550:                      int tindex = 0;
        !           551: 
        !           552:                      while (typevec[tindex] != parmtype)
        !           553:                        tindex++;
        !           554:                      OB_PUTC ('T');
        !           555:                      icat (tindex);
        !           556:                      if (tindex > 9)
        !           557:                        OB_PUTC ('_');
        !           558:                    }
        !           559:                }
        !           560:              goto next;
        !           561:            }
        !           562:          if (nrepeats)
        !           563:            flush_repeats (typevec[maxtype-2]);
        !           564:          if (! just_one
        !           565:              /* Only cache types which take more than one character.  */
        !           566:              && (parmtype != TYPE_MAIN_VARIANT (parmtype)
        !           567:                  || (TREE_CODE (parmtype) != INTEGER_TYPE
        !           568:                      && TREE_CODE (parmtype) != REAL_TYPE)))
        !           569:            TREE_USED (parmtype) = 1;
        !           570:        }
        !           571: 
        !           572:       if (TYPE_PTRMEMFUNC_P (parmtype))
        !           573:        parmtype = TYPE_PTRMEMFUNC_FN_TYPE (parmtype);
        !           574: 
        !           575:       if (TREE_READONLY (parmtype))
        !           576:        OB_PUTC ('C');
        !           577:       if (TREE_CODE (parmtype) == INTEGER_TYPE
        !           578:          && TYPE_MAIN_VARIANT (parmtype) == unsigned_type (TYPE_MAIN_VARIANT (parmtype)))
        !           579:        OB_PUTC ('U');
        !           580:       if (TYPE_VOLATILE (parmtype))
        !           581:        OB_PUTC ('V');
        !           582: 
        !           583:       switch (TREE_CODE (parmtype))
        !           584:        {
        !           585:        case OFFSET_TYPE:
        !           586:          OB_PUTC ('O');
        !           587:          build_overload_name (TYPE_OFFSET_BASETYPE (parmtype), 0, 0);
        !           588:          OB_PUTC ('_');
        !           589:          build_overload_name (TREE_TYPE (parmtype), 0, 0);
        !           590:          break;
        !           591: 
        !           592:        case REFERENCE_TYPE:
        !           593:          OB_PUTC ('R');
        !           594:          goto more;
        !           595: 
        !           596:        case ARRAY_TYPE:
        !           597: #if PARM_CAN_BE_ARRAY_TYPE
        !           598:          {
        !           599:            tree length;
        !           600: 
        !           601:            OB_PUTC ('A');
        !           602:            if (TYPE_DOMAIN (parmtype) == NULL_TREE)
        !           603:              error ("pointer or reference to array of unknown bound in parm type");
        !           604:            else
        !           605:              {
        !           606:                length = array_type_nelts (parmtype);
        !           607:                if (TREE_CODE (length) == INTEGER_CST)
        !           608:                  icat (TREE_INT_CST_LOW (length) + 1);
        !           609:              }
        !           610:            OB_PUTC ('_');
        !           611:            goto more;
        !           612:          }
        !           613: #else
        !           614:          OB_PUTC ('P');
        !           615:          goto more;
        !           616: #endif
        !           617: 
        !           618:        case POINTER_TYPE:
        !           619:          OB_PUTC ('P');
        !           620:        more:
        !           621:          build_overload_name (TREE_TYPE (parmtype), 0, 0);
        !           622:          break;
        !           623: 
        !           624:        case FUNCTION_TYPE:
        !           625:        case METHOD_TYPE:
        !           626:          {
        !           627:            tree firstarg = TYPE_ARG_TYPES (parmtype);
        !           628:            /* Otherwise have to implement reentrant typevecs,
        !           629:               unmark and remark types, etc.  */
        !           630:            int old_nofold = nofold;
        !           631:            nofold = 1;
        !           632: 
        !           633:            if (nrepeats)
        !           634:              flush_repeats (typevec[maxtype-1]);
        !           635: 
        !           636:            /* @@ It may be possible to pass a function type in
        !           637:               which is not preceded by a 'P'.  */
        !           638:            if (TREE_CODE (parmtype) == FUNCTION_TYPE)
        !           639:              {
        !           640:                OB_PUTC ('F');
        !           641:                if (firstarg == NULL_TREE)
        !           642:                  OB_PUTC ('e');
        !           643:                else if (firstarg == void_list_node)
        !           644:                  OB_PUTC ('v');
        !           645:                else
        !           646:                  build_overload_name (firstarg, 0, 0);
        !           647:              }
        !           648:            else
        !           649:              {
        !           650:                int constp = TYPE_READONLY (TREE_TYPE (TREE_VALUE (firstarg)));
        !           651:                int volatilep = TYPE_VOLATILE (TREE_TYPE (TREE_VALUE (firstarg)));
        !           652:                OB_PUTC ('M');
        !           653:                firstarg = TREE_CHAIN (firstarg);
        !           654: 
        !           655:                build_overload_name (TYPE_METHOD_BASETYPE (parmtype), 0, 0);
        !           656:                if (constp)
        !           657:                  OB_PUTC ('C');
        !           658:                if (volatilep)
        !           659:                  OB_PUTC ('V');
        !           660: 
        !           661:                /* For cfront 2.0 compatibility.  */
        !           662:                OB_PUTC ('F');
        !           663: 
        !           664:                if (firstarg == NULL_TREE)
        !           665:                  OB_PUTC ('e');
        !           666:                else if (firstarg == void_list_node)
        !           667:                  OB_PUTC ('v');
        !           668:                else
        !           669:                  build_overload_name (firstarg, 0, 0);
        !           670:              }
        !           671: 
        !           672:            /* Separate args from return type.  */
        !           673:            OB_PUTC ('_');
        !           674:            build_overload_name (TREE_TYPE (parmtype), 0, 0);
        !           675:            nofold = old_nofold;
        !           676:            break;
        !           677:          }
        !           678: 
        !           679:        case INTEGER_TYPE:
        !           680:          parmtype = TYPE_MAIN_VARIANT (parmtype);
        !           681:          if (parmtype == integer_type_node
        !           682:              || parmtype == unsigned_type_node)
        !           683:            OB_PUTC ('i');
        !           684:          else if (parmtype == long_integer_type_node
        !           685:                   || parmtype == long_unsigned_type_node)
        !           686:            OB_PUTC ('l');
        !           687:          else if (parmtype == short_integer_type_node
        !           688:                   || parmtype == short_unsigned_type_node)
        !           689:            OB_PUTC ('s');
        !           690:          else if (parmtype == signed_char_type_node)
        !           691:            {
        !           692:              OB_PUTC ('S');
        !           693:              OB_PUTC ('c');
        !           694:            }
        !           695:          else if (parmtype == char_type_node
        !           696:                   || parmtype == unsigned_char_type_node)
        !           697:            OB_PUTC ('c');
        !           698:          else if (parmtype == wchar_type_node)
        !           699:            OB_PUTC ('w');
        !           700:          else if (parmtype == long_long_integer_type_node
        !           701:              || parmtype == long_long_unsigned_type_node)
        !           702:            OB_PUTC ('x');
        !           703: #if 0
        !           704:          /* it would seem there is no way to enter these in source code,
        !           705:             yet.  (mrs) */
        !           706:          else if (parmtype == long_long_long_integer_type_node
        !           707:              || parmtype == long_long_long_unsigned_type_node)
        !           708:            OB_PUTC ('q');
        !           709: #endif
        !           710:          else
        !           711:            my_friendly_abort (73);
        !           712:          break;
        !           713: 
        !           714:        case BOOLEAN_TYPE:
        !           715:          OB_PUTC ('b');
        !           716:          break;
        !           717: 
        !           718:        case REAL_TYPE:
        !           719:          parmtype = TYPE_MAIN_VARIANT (parmtype);
        !           720:          if (parmtype == long_double_type_node)
        !           721:            OB_PUTC ('r');
        !           722:          else if (parmtype == double_type_node)
        !           723:            OB_PUTC ('d');
        !           724:          else if (parmtype == float_type_node)
        !           725:            OB_PUTC ('f');
        !           726:          else my_friendly_abort (74);
        !           727:          break;
        !           728: 
        !           729:        case VOID_TYPE:
        !           730:          if (! just_one)
        !           731:            {
        !           732: #if 0
        !           733:              extern tree void_list_node;
        !           734: 
        !           735:              /* See if anybody is wasting memory.  */
        !           736:              my_friendly_assert (parmtypes == void_list_node, 247);
        !           737: #endif
        !           738:              /* This is the end of a parameter list.  */
        !           739:              if (end) OB_FINISH ();
        !           740:              return (char *)obstack_base (&scratch_obstack);
        !           741:            }
        !           742:          OB_PUTC ('v');
        !           743:          break;
        !           744: 
        !           745:        case ERROR_MARK:        /* not right, but nothing is anyway */
        !           746:          break;
        !           747: 
        !           748:          /* have to do these */
        !           749:        case UNION_TYPE:
        !           750:        case RECORD_TYPE:
        !           751:          if (! just_one)
        !           752:            /* Make this type signature look incompatible
        !           753:               with AT&T.  */
        !           754:            OB_PUTC ('G');
        !           755:          goto common;
        !           756:        case ENUMERAL_TYPE:
        !           757:        common:
        !           758:          {
        !           759:            tree name = TYPE_NAME (parmtype);
        !           760:            int i = 1;
        !           761: 
        !           762:            if (TREE_CODE (name) == TYPE_DECL)
        !           763:              {
        !           764:                tree context = name;
        !           765:                while (DECL_CONTEXT (context))
        !           766:                  {
        !           767:                    i += 1;
        !           768:                    context = DECL_CONTEXT (context);
        !           769:                    if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')
        !           770:                      context = TYPE_NAME (context);
        !           771:                  }
        !           772:                name = DECL_NAME (name);
        !           773:              }
        !           774:            my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 248);
        !           775:            if (i > 1)
        !           776:              {
        !           777:                OB_PUTC ('Q');
        !           778:                if (i > 9)
        !           779:                  OB_PUTC ('_');
        !           780:                icat (i);
        !           781:                if (i > 9)
        !           782:                  OB_PUTC ('_');
        !           783:                 numeric_outputed_need_bar = 0;
        !           784:                build_overload_nested_name (TYPE_NAME (parmtype));
        !           785:              }
        !           786:            else
        !           787:              build_overload_identifier (name);
        !           788:            break;
        !           789:          }
        !           790: 
        !           791:        case UNKNOWN_TYPE:
        !           792:          /* This will take some work.  */
        !           793:          OB_PUTC ('?');
        !           794:          break;
        !           795: 
        !           796:        case TEMPLATE_TYPE_PARM:
        !           797:        case TEMPLATE_CONST_PARM:
        !           798:         case UNINSTANTIATED_P_TYPE:
        !           799:          /* We don't ever want this output, but it's inconvenient not to
        !           800:             be able to build the string.  This should cause assembler
        !           801:             errors we'll notice.  */
        !           802:          {
        !           803:            static int n;
        !           804:            sprintf (digit_buffer, " *%d", n++);
        !           805:            OB_PUTCP (digit_buffer);
        !           806:          }
        !           807:          break;
        !           808: 
        !           809:        default:
        !           810:          my_friendly_abort (75);
        !           811:        }
        !           812: 
        !           813:     next:
        !           814:       if (just_one) break;
        !           815:       parmtypes = TREE_CHAIN (parmtypes);
        !           816:     }
        !           817:   if (! just_one)
        !           818:     {
        !           819:       if (nrepeats)
        !           820:        flush_repeats (typevec[maxtype-1]);
        !           821: 
        !           822:       /* To get here, parms must end with `...'. */
        !           823:       OB_PUTC ('e');
        !           824:     }
        !           825: 
        !           826:   if (end) OB_FINISH ();
        !           827:   return (char *)obstack_base (&scratch_obstack);
        !           828: }
        !           829: 
        !           830: tree
        !           831: build_static_name (basetype, name)
        !           832:   tree basetype, name;
        !           833: {
        !           834:   char *basename  = build_overload_name (basetype, 1, 1);
        !           835:   char *buf = (char *) alloca (IDENTIFIER_LENGTH (name)
        !           836:                               + sizeof (STATIC_NAME_FORMAT)
        !           837:                               + strlen (basename));
        !           838:   sprintf (buf, STATIC_NAME_FORMAT, basename, IDENTIFIER_POINTER (name));
        !           839:   return get_identifier (buf);
        !           840: }  
        !           841: 
        !           842: /* Generate an identifier that encodes the (ANSI) exception TYPE. */
        !           843: 
        !           844: /* This should be part of `ansi_opname', or at least be defined by the std.  */
        !           845: #define EXCEPTION_NAME_PREFIX "__ex"
        !           846: #define EXCEPTION_NAME_LENGTH 4
        !           847: 
        !           848: tree
        !           849: cplus_exception_name (type)
        !           850:      tree type;
        !           851: {
        !           852:   OB_INIT ();
        !           853:   OB_PUTS (EXCEPTION_NAME_PREFIX);
        !           854:   return get_identifier (build_overload_name (type, 0, 1));
        !           855: }
        !           856: 
        !           857: /* Change the name of a function definition so that it may be
        !           858:    overloaded. NAME is the name of the function to overload,
        !           859:    PARMS is the parameter list (which determines what name the
        !           860:    final function obtains).
        !           861: 
        !           862:    FOR_METHOD is 1 if this overload is being performed
        !           863:    for a method, rather than a function type.  It is 2 if
        !           864:    this overload is being performed for a constructor.  */
        !           865: tree
        !           866: build_decl_overload (dname, parms, for_method)
        !           867:      tree dname;
        !           868:      tree parms;
        !           869:      int for_method;
        !           870: {
        !           871:   char *name = IDENTIFIER_POINTER (dname);
        !           872: 
        !           873:   /* member operators new and delete look like methods at this point.  */
        !           874:   if (! for_method && parms != NULL_TREE && TREE_CODE (parms) == TREE_LIST)
        !           875:     {
        !           876:       if (dname == ansi_opname[(int) DELETE_EXPR])
        !           877:        return get_identifier ("__builtin_delete");
        !           878:       else if (dname == ansi_opname[(int) VEC_DELETE_EXPR])
        !           879:        return get_identifier ("__builtin_vec_delete");
        !           880:       else if (TREE_CHAIN (parms) == void_list_node)
        !           881:        {
        !           882:          if (dname == ansi_opname[(int) NEW_EXPR])
        !           883:            return get_identifier ("__builtin_new");
        !           884:          else if (dname == ansi_opname[(int) VEC_NEW_EXPR])
        !           885:            return get_identifier ("__builtin_vec_new");
        !           886:        }
        !           887:     }
        !           888: 
        !           889:   OB_INIT ();
        !           890:   if (for_method != 2)
        !           891:     OB_PUTCP (name);
        !           892:   /* Otherwise, we can divine that this is a constructor,
        !           893:      and figure out its name without any extra encoding.  */
        !           894: 
        !           895:   OB_PUTC2 ('_', '_');
        !           896:   if (for_method)
        !           897:     {
        !           898: #if 0
        !           899:       /* We can get away without doing this.  */
        !           900:       OB_PUTC ('M');
        !           901: #endif
        !           902:       {
        !           903:        tree this_type = TREE_VALUE (parms);
        !           904: 
        !           905:        if (TREE_CODE (this_type) == RECORD_TYPE)  /* a signature pointer */
        !           906:          parms = temp_tree_cons (NULL_TREE, SIGNATURE_TYPE (this_type),
        !           907:                                  TREE_CHAIN (parms));
        !           908:        else
        !           909:          parms = temp_tree_cons (NULL_TREE, TREE_TYPE (this_type),
        !           910:                                  TREE_CHAIN (parms));
        !           911:       }
        !           912:     }
        !           913:   else
        !           914:     OB_PUTC ('F');
        !           915: 
        !           916:   if (parms == NULL_TREE)
        !           917:     OB_PUTC2 ('e', '\0');
        !           918:   else if (parms == void_list_node)
        !           919:     OB_PUTC2 ('v', '\0');
        !           920:   else
        !           921:     {
        !           922:       ALLOCATE_TYPEVEC (parms);
        !           923:       nofold = 0;
        !           924:       if (for_method)
        !           925:        {
        !           926:          build_overload_name (TREE_VALUE (parms), 0, 0);
        !           927: 
        !           928:          typevec[maxtype++] = TREE_VALUE (parms);
        !           929:          TREE_USED (TREE_VALUE (parms)) = 1;
        !           930: 
        !           931:          if (TREE_CHAIN (parms))
        !           932:            build_overload_name (TREE_CHAIN (parms), 0, 1);
        !           933:          else
        !           934:            OB_PUTC2 ('e', '\0');
        !           935:        }
        !           936:       else
        !           937:        build_overload_name (parms, 0, 1);
        !           938:       DEALLOCATE_TYPEVEC (parms);
        !           939:     }
        !           940:   {
        !           941:     tree n = get_identifier (obstack_base (&scratch_obstack));
        !           942:     if (IDENTIFIER_OPNAME_P (dname))
        !           943:       IDENTIFIER_OPNAME_P (n) = 1;
        !           944:     return n;
        !           945:   }
        !           946: }
        !           947: 
        !           948: /* Build an overload name for the type expression TYPE.  */
        !           949: tree
        !           950: build_typename_overload (type)
        !           951:      tree type;
        !           952: {
        !           953:   tree id;
        !           954: 
        !           955:   OB_INIT ();
        !           956:   OB_PUTID (ansi_opname[(int) TYPE_EXPR]);
        !           957:   nofold = 1;
        !           958:   build_overload_name (type, 0, 1);
        !           959:   id = get_identifier (obstack_base (&scratch_obstack));
        !           960:   IDENTIFIER_OPNAME_P (id) = 1;
        !           961: #if 0
        !           962:   IDENTIFIER_GLOBAL_VALUE (id) = TYPE_NAME (type);
        !           963: #endif
        !           964:   TREE_TYPE (id) = type;
        !           965:   return id;
        !           966: }
        !           967: 
        !           968: #ifndef NO_DOLLAR_IN_LABEL
        !           969: #define T_DESC_FORMAT "TD$"
        !           970: #define I_DESC_FORMAT "ID$"
        !           971: #define M_DESC_FORMAT "MD$"
        !           972: #else
        !           973: #if !defined(NO_DOT_IN_LABEL)
        !           974: #define T_DESC_FORMAT "TD."
        !           975: #define I_DESC_FORMAT "ID."
        !           976: #define M_DESC_FORMAT "MD."
        !           977: #else
        !           978: #define T_DESC_FORMAT "__t_desc_"
        !           979: #define I_DESC_FORMAT "__i_desc_"
        !           980: #define M_DESC_FORMAT "__m_desc_"
        !           981: #endif
        !           982: #endif
        !           983: 
        !           984: /* Build an overload name for the type expression TYPE.  */
        !           985: tree
        !           986: build_t_desc_overload (type)
        !           987:      tree type;
        !           988: {
        !           989:   OB_INIT ();
        !           990:   OB_PUTS (T_DESC_FORMAT);
        !           991:   nofold = 1;
        !           992: 
        !           993: #if 0
        !           994:   /* Use a different format if the type isn't defined yet.  */
        !           995:   if (TYPE_SIZE (type) == NULL_TREE)
        !           996:     {
        !           997:       char *p;
        !           998:       int changed;
        !           999: 
        !          1000:       for (p = tname; *p; p++)
        !          1001:        if (isupper (*p))
        !          1002:          {
        !          1003:            changed = 1;
        !          1004:            *p = tolower (*p);
        !          1005:          }
        !          1006:       /* If there's no change, we have an inappropriate T_DESC_FORMAT.  */
        !          1007:       my_friendly_assert (changed != 0, 249);
        !          1008:     }
        !          1009: #endif
        !          1010: 
        !          1011:   build_overload_name (type, 0, 1);
        !          1012:   return get_identifier (obstack_base (&scratch_obstack));
        !          1013: }
        !          1014: 
        !          1015: /* Top-level interface to explicit overload requests. Allow NAME
        !          1016:    to be overloaded. Error if NAME is already declared for the current
        !          1017:    scope. Warning if function is redundantly overloaded. */
        !          1018: 
        !          1019: void
        !          1020: declare_overloaded (name)
        !          1021:      tree name;
        !          1022: {
        !          1023: #ifdef NO_AUTO_OVERLOAD
        !          1024:   if (is_overloaded (name))
        !          1025:     warning ("function `%s' already declared overloaded",
        !          1026:             IDENTIFIER_POINTER (name));
        !          1027:   else if (IDENTIFIER_GLOBAL_VALUE (name))
        !          1028:     error ("overloading function `%s' that is already defined",
        !          1029:           IDENTIFIER_POINTER (name));
        !          1030:   else
        !          1031:     {
        !          1032:       TREE_OVERLOADED (name) = 1;
        !          1033:       IDENTIFIER_GLOBAL_VALUE (name) = build_tree_list (name, NULL_TREE);
        !          1034:       TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (name)) = unknown_type_node;
        !          1035:     }
        !          1036: #else
        !          1037:   if (current_lang_name == lang_name_cplusplus)
        !          1038:     {
        !          1039:       if (0)
        !          1040:        warning ("functions are implicitly overloaded in C++");
        !          1041:     }
        !          1042:   else if (current_lang_name == lang_name_c)
        !          1043:     error ("overloading function `%s' cannot be done in C language context");
        !          1044:   else
        !          1045:     my_friendly_abort (76);
        !          1046: #endif
        !          1047: }
        !          1048: 
        !          1049: #ifdef NO_AUTO_OVERLOAD
        !          1050: /* Check to see if NAME is overloaded. For first approximation,
        !          1051:    check to see if its TREE_OVERLOADED is set.  This is used on
        !          1052:    IDENTIFIER nodes.  */
        !          1053: int
        !          1054: is_overloaded (name)
        !          1055:      tree name;
        !          1056: {
        !          1057:   /* @@ */
        !          1058:   return (TREE_OVERLOADED (name)
        !          1059:          && (! IDENTIFIER_CLASS_VALUE (name) || current_class_type == 0)
        !          1060:          && ! IDENTIFIER_LOCAL_VALUE (name));
        !          1061: }
        !          1062: #endif
        !          1063: 
        !          1064: /* Given a tree_code CODE, and some arguments (at least one),
        !          1065:    attempt to use an overloaded operator on the arguments.
        !          1066: 
        !          1067:    For unary operators, only the first argument need be checked.
        !          1068:    For binary operators, both arguments may need to be checked.
        !          1069: 
        !          1070:    Member functions can convert class references to class pointers,
        !          1071:    for one-level deep indirection.  More than that is not supported.
        !          1072:    Operators [](), ()(), and ->() must be member functions.
        !          1073: 
        !          1074:    We call function call building calls with LOOKUP_COMPLAIN if they
        !          1075:    are our only hope.  This is true when we see a vanilla operator
        !          1076:    applied to something of aggregate type.  If this fails, we are free
        !          1077:    to return `error_mark_node', because we will have reported the
        !          1078:    error.
        !          1079: 
        !          1080:    Operators NEW and DELETE overload in funny ways: operator new takes
        !          1081:    a single `size' parameter, and operator delete takes a pointer to the
        !          1082:    storage being deleted.  When overloading these operators, success is
        !          1083:    assumed.  If there is a failure, report an error message and return
        !          1084:    `error_mark_node'.  */
        !          1085: 
        !          1086: /* NOSTRICT */
        !          1087: tree
        !          1088: build_opfncall (code, flags, xarg1, xarg2, arg3)
        !          1089:      enum tree_code code;
        !          1090:      int flags;
        !          1091:      tree xarg1, xarg2, arg3;
        !          1092: {
        !          1093:   tree rval = 0;
        !          1094:   tree arg1, arg2;
        !          1095:   tree type1, type2, fnname;
        !          1096:   tree fields1 = 0, parms = 0;
        !          1097:   tree global_fn;
        !          1098:   int try_second;
        !          1099:   int binary_is_unary;
        !          1100: 
        !          1101:   if (xarg1 == error_mark_node)
        !          1102:     return error_mark_node;
        !          1103: 
        !          1104:   if (code == COND_EXPR)
        !          1105:     {
        !          1106:       if (TREE_CODE (xarg2) == ERROR_MARK
        !          1107:          || TREE_CODE (arg3) == ERROR_MARK)
        !          1108:        return error_mark_node;
        !          1109:     }
        !          1110:   if (code == COMPONENT_REF)
        !          1111:     if (TREE_CODE (TREE_TYPE (xarg1)) == POINTER_TYPE)
        !          1112:       return rval;
        !          1113: 
        !          1114:   /* First, see if we can work with the first argument */
        !          1115:   type1 = TREE_TYPE (xarg1);
        !          1116: 
        !          1117:   /* Some tree codes have length > 1, but we really only want to
        !          1118:      overload them if their first argument has a user defined type.  */
        !          1119:   switch (code)
        !          1120:     {
        !          1121:     case PREINCREMENT_EXPR:
        !          1122:     case PREDECREMENT_EXPR:
        !          1123:     case POSTINCREMENT_EXPR:
        !          1124:     case POSTDECREMENT_EXPR:
        !          1125:     case COMPONENT_REF:
        !          1126:       binary_is_unary = 1;
        !          1127:       try_second = 0;
        !          1128:       break;
        !          1129: 
        !          1130:       /* ARRAY_REFs and CALL_EXPRs must overload successfully.
        !          1131:         If they do not, return error_mark_node instead of NULL_TREE.  */
        !          1132:     case ARRAY_REF:
        !          1133:       if (xarg2 == error_mark_node)
        !          1134:        return error_mark_node;
        !          1135:     case CALL_EXPR:
        !          1136:       rval = error_mark_node;
        !          1137:       binary_is_unary = 0;
        !          1138:       try_second = 0;
        !          1139:       break;
        !          1140: 
        !          1141:     case VEC_NEW_EXPR:
        !          1142:     case NEW_EXPR:
        !          1143:       {
        !          1144:        tree args = tree_cons (NULL_TREE, xarg2, arg3);
        !          1145:        fnname = ansi_opname[(int) code];
        !          1146:        if (flags & LOOKUP_GLOBAL)
        !          1147:          return build_overload_call (fnname, args, flags & LOOKUP_COMPLAIN,
        !          1148:                                      (struct candidate *)0);
        !          1149: 
        !          1150:        rval = build_method_call
        !          1151:          (build_indirect_ref (build1 (NOP_EXPR, xarg1, error_mark_node),
        !          1152:                               "new"),
        !          1153:           fnname, args, NULL_TREE, flags);
        !          1154:        if (rval == error_mark_node)
        !          1155:          /* User might declare fancy operator new, but invoke it
        !          1156:             like standard one.  */
        !          1157:          return rval;
        !          1158: 
        !          1159:        TREE_TYPE (rval) = xarg1;
        !          1160:        TREE_CALLS_NEW (rval) = 1;
        !          1161:        return rval;
        !          1162:       }
        !          1163:       break;
        !          1164: 
        !          1165:     case VEC_DELETE_EXPR:
        !          1166:     case DELETE_EXPR:
        !          1167:       {
        !          1168:        fnname = ansi_opname[(int) code];
        !          1169:        if (flags & LOOKUP_GLOBAL)
        !          1170:          return build_overload_call (fnname,
        !          1171:                                      build_tree_list (NULL_TREE, xarg1),
        !          1172:                                      flags & LOOKUP_COMPLAIN,
        !          1173:                                      (struct candidate *)0);
        !          1174: 
        !          1175:        rval = build_method_call
        !          1176:          (build_indirect_ref (build1 (NOP_EXPR, TREE_TYPE (xarg1),
        !          1177:                                       error_mark_node),
        !          1178:                               NULL_PTR),
        !          1179:           fnname, tree_cons (NULL_TREE, xarg1,
        !          1180:                               build_tree_list (NULL_TREE, xarg2)),
        !          1181:           NULL_TREE, flags);
        !          1182:        /* This happens when the user mis-declares `operator delete'.
        !          1183:           Should now be impossible.  */
        !          1184:        my_friendly_assert (rval != error_mark_node, 250);
        !          1185:        TREE_TYPE (rval) = void_type_node;
        !          1186:        return rval;
        !          1187:       }
        !          1188:       break;
        !          1189: 
        !          1190:     default:
        !          1191:       binary_is_unary = 0;
        !          1192:       try_second = tree_code_length [(int) code] == 2;
        !          1193:       if (try_second && xarg2 == error_mark_node)
        !          1194:        return error_mark_node;
        !          1195:       break;
        !          1196:     }
        !          1197: 
        !          1198:   if (try_second && xarg2 == error_mark_node)
        !          1199:     return error_mark_node;
        !          1200: 
        !          1201:   /* What ever it was, we do not know how to deal with it.  */
        !          1202:   if (type1 == NULL_TREE)
        !          1203:     return rval;
        !          1204: 
        !          1205:   if (TREE_CODE (type1) == OFFSET_TYPE)
        !          1206:     type1 = TREE_TYPE (type1);
        !          1207: 
        !          1208:   if (TREE_CODE (type1) == REFERENCE_TYPE)
        !          1209:     {
        !          1210:       arg1 = convert_from_reference (xarg1);
        !          1211:       type1 = TREE_TYPE (arg1);
        !          1212:     }
        !          1213:   else
        !          1214:     {
        !          1215:       arg1 = xarg1;
        !          1216:     }
        !          1217: 
        !          1218:   if (!IS_AGGR_TYPE (type1) || TYPE_PTRMEMFUNC_P (type1))
        !          1219:     {
        !          1220:       /* Try to fail. First, fail if unary */
        !          1221:       if (! try_second)
        !          1222:        return rval;
        !          1223:       /* Second, see if second argument is non-aggregate. */
        !          1224:       type2 = TREE_TYPE (xarg2);
        !          1225:       if (TREE_CODE (type2) == OFFSET_TYPE)
        !          1226:        type2 = TREE_TYPE (type2);
        !          1227:       if (TREE_CODE (type2) == REFERENCE_TYPE)
        !          1228:        {
        !          1229:          arg2 = convert_from_reference (xarg2);
        !          1230:          type2 = TREE_TYPE (arg2);
        !          1231:        }
        !          1232:       else
        !          1233:        {
        !          1234:          arg2 = xarg2;
        !          1235:        }
        !          1236: 
        !          1237:       if (!IS_AGGR_TYPE (type2))
        !          1238:        return rval;
        !          1239:       try_second = 0;
        !          1240:     }
        !          1241: 
        !          1242:   if (try_second)
        !          1243:     {
        !          1244:       /* First arg may succeed; see whether second should.  */
        !          1245:       type2 = TREE_TYPE (xarg2);
        !          1246:       if (TREE_CODE (type2) == OFFSET_TYPE)
        !          1247:        type2 = TREE_TYPE (type2);
        !          1248:       if (TREE_CODE (type2) == REFERENCE_TYPE)
        !          1249:        {
        !          1250:          arg2 = convert_from_reference (xarg2);
        !          1251:          type2 = TREE_TYPE (arg2);
        !          1252:        }
        !          1253:       else
        !          1254:        {
        !          1255:          arg2 = xarg2;
        !          1256:        }
        !          1257: 
        !          1258:       if (! IS_AGGR_TYPE (type2))
        !          1259:        try_second = 0;
        !          1260:     }
        !          1261: 
        !          1262:   if (type1 == unknown_type_node
        !          1263:       || (try_second && TREE_TYPE (xarg2) == unknown_type_node))
        !          1264:     {
        !          1265:       /* This will not be implemented in the foreseeable future.  */
        !          1266:       return rval;
        !          1267:     }
        !          1268: 
        !          1269:   if (code == MODIFY_EXPR)
        !          1270:     fnname = ansi_assopname[(int) TREE_CODE (arg3)];
        !          1271:   else
        !          1272:     fnname = ansi_opname[(int) code];
        !          1273: 
        !          1274:   global_fn = lookup_name_nonclass (fnname);
        !          1275: 
        !          1276:   /* This is the last point where we will accept failure.  This
        !          1277:      may be too eager if we wish an overloaded operator not to match,
        !          1278:      but would rather a normal operator be called on a type-converted
        !          1279:      argument.  */
        !          1280: 
        !          1281:   if (IS_AGGR_TYPE (type1))
        !          1282:     {
        !          1283:       fields1 = lookup_fnfields (TYPE_BINFO (type1), fnname, 0);
        !          1284:       /* ARM $13.4.7, prefix/postfix ++/--.  */
        !          1285:       if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
        !          1286:        {
        !          1287:          xarg2 = integer_zero_node;
        !          1288:          binary_is_unary = 0;
        !          1289: 
        !          1290:          if (fields1)
        !          1291:            {
        !          1292:              tree t, t2;
        !          1293:              int have_postfix = 0;
        !          1294: 
        !          1295:              /* Look for an `operator++ (int)'.  If they didn't have
        !          1296:                 one, then we fall back to the old way of doing things.  */
        !          1297:              for (t = TREE_VALUE (fields1); t ; t = TREE_CHAIN (t))
        !          1298:                {
        !          1299:                  t2 = TYPE_ARG_TYPES (TREE_TYPE (t));
        !          1300:                  if (TREE_CHAIN (t2) != NULL_TREE
        !          1301:                      && TREE_VALUE (TREE_CHAIN (t2)) == integer_type_node)
        !          1302:                    {
        !          1303:                      have_postfix = 1;
        !          1304:                      break;
        !          1305:                    }
        !          1306:                }
        !          1307: 
        !          1308:              if (! have_postfix)
        !          1309:                {
        !          1310:                  char *op = POSTINCREMENT_EXPR ? "++" : "--";
        !          1311: 
        !          1312:                  /* There's probably a LOT of code in the world that
        !          1313:                     relies upon this old behavior.  So we'll only give this
        !          1314:                     warning when we've been given -pedantic.  A few
        !          1315:                     releases after 2.4, we'll convert this to be a pedwarn
        !          1316:                     or something else more appropriate.  */
        !          1317:                  if (pedantic)
        !          1318:                    warning ("no `operator%s (int)' declared for postfix `%s'",
        !          1319:                             op, op);
        !          1320:                  xarg2 = NULL_TREE;
        !          1321:                  binary_is_unary = 1;
        !          1322:                }
        !          1323:            }
        !          1324:        }
        !          1325:     }
        !          1326: 
        !          1327:   if (fields1 == NULL_TREE && global_fn == NULL_TREE)
        !          1328:     return rval;
        !          1329: 
        !          1330:   /* If RVAL winds up being `error_mark_node', we will return
        !          1331:      that... There is no way that normal semantics of these
        !          1332:      operators will succeed.  */
        !          1333: 
        !          1334:   /* This argument may be an uncommitted OFFSET_REF.  This is
        !          1335:      the case for example when dealing with static class members
        !          1336:      which are referenced from their class name rather than
        !          1337:      from a class instance.  */
        !          1338:   if (TREE_CODE (xarg1) == OFFSET_REF
        !          1339:       && TREE_CODE (TREE_OPERAND (xarg1, 1)) == VAR_DECL)
        !          1340:     xarg1 = TREE_OPERAND (xarg1, 1);
        !          1341:   if (try_second && xarg2 && TREE_CODE (xarg2) == OFFSET_REF
        !          1342:       && TREE_CODE (TREE_OPERAND (xarg2, 1)) == VAR_DECL)
        !          1343:     xarg2 = TREE_OPERAND (xarg2, 1);
        !          1344: 
        !          1345:   if (global_fn)
        !          1346:     flags |= LOOKUP_GLOBAL;
        !          1347: 
        !          1348:   if (code == CALL_EXPR)
        !          1349:     {
        !          1350:       /* This can only be a member function.  */
        !          1351:       return build_method_call (xarg1, fnname, xarg2,
        !          1352:                                NULL_TREE, LOOKUP_NORMAL);
        !          1353:     }
        !          1354:   else if (tree_code_length[(int) code] == 1 || binary_is_unary)
        !          1355:     {
        !          1356:       parms = NULL_TREE;
        !          1357:       rval = build_method_call (xarg1, fnname, NULL_TREE, NULL_TREE, flags);
        !          1358:     }
        !          1359:   else if (code == COND_EXPR)
        !          1360:     {
        !          1361:       parms = tree_cons (0, xarg2, build_tree_list (NULL_TREE, arg3));
        !          1362:       rval = build_method_call (xarg1, fnname, parms, NULL_TREE, flags);
        !          1363:     }
        !          1364:   else if (code == METHOD_CALL_EXPR)
        !          1365:     {
        !          1366:       /* must be a member function.  */
        !          1367:       parms = tree_cons (NULL_TREE, xarg2, arg3);
        !          1368:       return build_method_call (xarg1, fnname, parms, NULL_TREE,
        !          1369:                                LOOKUP_NORMAL);
        !          1370:     }
        !          1371:   else if (fields1)
        !          1372:     {
        !          1373:       parms = build_tree_list (NULL_TREE, xarg2);
        !          1374:       rval = build_method_call (xarg1, fnname, parms, NULL_TREE, flags);
        !          1375:     }
        !          1376:   else
        !          1377:     {
        !          1378:       parms = tree_cons (NULL_TREE, xarg1,
        !          1379:                         build_tree_list (NULL_TREE, xarg2));
        !          1380:       rval = build_overload_call (fnname, parms, flags,
        !          1381:                                  (struct candidate *)0);
        !          1382:     }
        !          1383: 
        !          1384:   return rval;
        !          1385: }
        !          1386: 
        !          1387: /* This function takes an identifier, ID, and attempts to figure out what
        !          1388:    it means. There are a number of possible scenarios, presented in increasing
        !          1389:    order of hair:
        !          1390: 
        !          1391:    1) not in a class's scope
        !          1392:    2) in class's scope, member name of the class's method
        !          1393:    3) in class's scope, but not a member name of the class
        !          1394:    4) in class's scope, member name of a class's variable
        !          1395: 
        !          1396:    NAME is $1 from the bison rule. It is an IDENTIFIER_NODE.
        !          1397:    VALUE is $$ from the bison rule. It is the value returned by lookup_name ($1)
        !          1398:    yychar is the pending input character (suitably encoded :-).
        !          1399: 
        !          1400:    As a last ditch, try to look up the name as a label and return that
        !          1401:    address.
        !          1402: 
        !          1403:    Values which are declared as being of REFERENCE_TYPE are
        !          1404:    automatically dereferenced here (as a hack to make the
        !          1405:    compiler faster).  */
        !          1406: 
        !          1407: tree
        !          1408: hack_identifier (value, name, yychar)
        !          1409:      tree value, name;
        !          1410:      int yychar;
        !          1411: {
        !          1412:   tree type;
        !          1413: 
        !          1414:   if (TREE_CODE (value) == ERROR_MARK)
        !          1415:     {
        !          1416:       if (current_class_name)
        !          1417:        {
        !          1418:          tree fields = lookup_fnfields (TYPE_BINFO (current_class_type), name, 1);
        !          1419:          if (fields == error_mark_node)
        !          1420:            return error_mark_node;
        !          1421:          if (fields)
        !          1422:            {
        !          1423:              tree fndecl;
        !          1424: 
        !          1425:              fndecl = TREE_VALUE (fields);
        !          1426:              my_friendly_assert (TREE_CODE (fndecl) == FUNCTION_DECL, 251);
        !          1427:              if (DECL_CHAIN (fndecl) == NULL_TREE)
        !          1428:                {
        !          1429:                  warning ("methods cannot be converted to function pointers");
        !          1430:                  return fndecl;
        !          1431:                }
        !          1432:              else
        !          1433:                {
        !          1434:                  error ("ambiguous request for method pointer `%s'",
        !          1435:                         IDENTIFIER_POINTER (name));
        !          1436:                  return error_mark_node;
        !          1437:                }
        !          1438:            }
        !          1439:        }
        !          1440:       if (flag_labels_ok && IDENTIFIER_LABEL_VALUE (name))
        !          1441:        {
        !          1442:          return IDENTIFIER_LABEL_VALUE (name);
        !          1443:        }
        !          1444:       return error_mark_node;
        !          1445:     }
        !          1446: 
        !          1447:   type = TREE_TYPE (value);
        !          1448:   if (TREE_CODE (value) == FIELD_DECL)
        !          1449:     {
        !          1450:       if (current_class_decl == NULL_TREE)
        !          1451:        {
        !          1452:          error ("request for member `%s' in static member function",
        !          1453:                 IDENTIFIER_POINTER (DECL_NAME (value)));
        !          1454:          return error_mark_node;
        !          1455:        }
        !          1456:       TREE_USED (current_class_decl) = 1;
        !          1457:       if (yychar == '(')
        !          1458:        if (! ((TYPE_LANG_SPECIFIC (type)
        !          1459:                && TYPE_OVERLOADS_CALL_EXPR (type))
        !          1460:               || (TREE_CODE (type) == REFERENCE_TYPE
        !          1461:                   && TYPE_LANG_SPECIFIC (TREE_TYPE (type))
        !          1462:                   && TYPE_OVERLOADS_CALL_EXPR (TREE_TYPE (type))))
        !          1463:            && TREE_CODE (type) != FUNCTION_TYPE
        !          1464:            && TREE_CODE (type) != METHOD_TYPE
        !          1465:            && !TYPE_PTRMEMFUNC_P (type)
        !          1466:            && (TREE_CODE (type) != POINTER_TYPE
        !          1467:                || (TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE
        !          1468:                    && TREE_CODE (TREE_TYPE (type)) != METHOD_TYPE)))
        !          1469:          {
        !          1470:            error ("component `%s' is not a method",
        !          1471:                   IDENTIFIER_POINTER (name));
        !          1472:            return error_mark_node;
        !          1473:          }
        !          1474:       /* Mark so that if we are in a constructor, and then find that
        !          1475:         this field was initialized by a base initializer,
        !          1476:         we can emit an error message.  */
        !          1477:       TREE_USED (value) = 1;
        !          1478:       return build_component_ref (C_C_D, name, 0, 1);
        !          1479:     }
        !          1480: 
        !          1481:   if (really_overloaded_fn (value))
        !          1482:     {
        !          1483:       tree t = get_first_fn (value);
        !          1484:       for (; t; t = DECL_CHAIN (t))
        !          1485:        {
        !          1486:          if (TREE_CODE (t) == TEMPLATE_DECL)
        !          1487:            continue;
        !          1488: 
        !          1489:          assemble_external (t);
        !          1490:          TREE_USED (t) = 1;
        !          1491:        }
        !          1492:     }
        !          1493:   else if (TREE_CODE (value) == TREE_LIST)
        !          1494:     {
        !          1495:       tree t = value;
        !          1496:       while (t && TREE_CODE (t) == TREE_LIST)
        !          1497:        {
        !          1498:          assemble_external (TREE_VALUE (t));
        !          1499:          TREE_USED (t) = 1;
        !          1500:          t = TREE_CHAIN (t);
        !          1501:        }
        !          1502:     }
        !          1503:   else
        !          1504:     {
        !          1505:       assemble_external (value);
        !          1506:       TREE_USED (value) = 1;
        !          1507:     }
        !          1508: 
        !          1509:   if (TREE_CODE_CLASS (TREE_CODE (value)) == 'd' && DECL_NONLOCAL (value))
        !          1510:     {
        !          1511:       if (DECL_LANG_SPECIFIC (value)
        !          1512:          && DECL_CLASS_CONTEXT (value) != current_class_type)
        !          1513:        {
        !          1514:          tree path;
        !          1515:          enum access_type access;
        !          1516:          register tree context
        !          1517:            = (TREE_CODE (value) == FUNCTION_DECL && DECL_VIRTUAL_P (value))
        !          1518:              ? DECL_CLASS_CONTEXT (value)
        !          1519:              : DECL_CONTEXT (value);
        !          1520: 
        !          1521:          get_base_distance (context, current_class_type, 0, &path);
        !          1522:          if (path)
        !          1523:            {
        !          1524:              access = compute_access (path, value);
        !          1525:              if (access != access_public)
        !          1526:                {
        !          1527:                  if (TREE_CODE (value) == VAR_DECL)
        !          1528:                    error ("static member `%s' is %s",
        !          1529:                           IDENTIFIER_POINTER (name),
        !          1530:                           TREE_PRIVATE (value) ? "private" :
        !          1531:                           "from a private base class");
        !          1532:                  else
        !          1533:                    error ("enum `%s' is from private base class",
        !          1534:                           IDENTIFIER_POINTER (name));
        !          1535:                  return error_mark_node;
        !          1536:                }
        !          1537:            }
        !          1538:        }
        !          1539:       return value;
        !          1540:     }
        !          1541:   if (TREE_CODE (value) == TREE_LIST && TREE_NONLOCAL_FLAG (value))
        !          1542:     {
        !          1543:       if (type == 0)
        !          1544:        {
        !          1545:          error ("request for member `%s' is ambiguous in multiple inheritance lattice",
        !          1546:                 IDENTIFIER_POINTER (name));
        !          1547:          return error_mark_node;
        !          1548:        }
        !          1549: 
        !          1550:       return value;
        !          1551:     }
        !          1552: 
        !          1553:   if (TREE_CODE (type) == REFERENCE_TYPE)
        !          1554:     {
        !          1555:       my_friendly_assert (TREE_CODE (value) == VAR_DECL
        !          1556:                          || TREE_CODE (value) == PARM_DECL
        !          1557:                          || TREE_CODE (value) == RESULT_DECL, 252);
        !          1558:       if (DECL_REFERENCE_SLOT (value))
        !          1559:        return DECL_REFERENCE_SLOT (value);
        !          1560:     }
        !          1561:   return value;
        !          1562: }
        !          1563: 
        !          1564: 
        !          1565: #if 0
        !          1566: /* Given an object OF, and a type conversion operator COMPONENT
        !          1567:    build a call to the conversion operator, if a call is requested,
        !          1568:    or return the address (as a pointer to member function) if one is not.
        !          1569: 
        !          1570:    OF can be a TYPE_DECL or any kind of datum that would normally
        !          1571:    be passed to `build_component_ref'.  It may also be NULL_TREE,
        !          1572:    in which case `current_class_type' and `current_class_decl'
        !          1573:    provide default values.
        !          1574: 
        !          1575:    BASETYPE_PATH, if non-null, is the path of basetypes
        !          1576:    to go through before we get the the instance of interest.
        !          1577: 
        !          1578:    PROTECT says whether we apply C++ scoping rules or not.  */
        !          1579: tree
        !          1580: build_component_type_expr (of, component, basetype_path, protect)
        !          1581:      tree of, component, basetype_path;
        !          1582:      int protect;
        !          1583: {
        !          1584:   tree cname = NULL_TREE;
        !          1585:   tree tmp, last;
        !          1586:   tree name;
        !          1587:   int flags = protect ? LOOKUP_NORMAL : LOOKUP_COMPLAIN;
        !          1588: 
        !          1589:   if (of)
        !          1590:     my_friendly_assert (IS_AGGR_TYPE (TREE_TYPE (of)), 253);
        !          1591:   my_friendly_assert (TREE_CODE (component) == TYPE_EXPR, 254);
        !          1592: 
        !          1593:   tmp = TREE_OPERAND (component, 0);
        !          1594:   last = NULL_TREE;
        !          1595: 
        !          1596:   while (tmp)
        !          1597:     {
        !          1598:       switch (TREE_CODE (tmp))
        !          1599:        {
        !          1600:        case CALL_EXPR:
        !          1601:          if (last)
        !          1602:            TREE_OPERAND (last, 0) = TREE_OPERAND (tmp, 0);
        !          1603:          else
        !          1604:            TREE_OPERAND (component, 0) = TREE_OPERAND (tmp, 0);
        !          1605: 
        !          1606:          last = groktypename (build_tree_list (TREE_TYPE (component),
        !          1607:                                                TREE_OPERAND (component, 0)));
        !          1608:          name = build_typename_overload (last);
        !          1609:          TREE_TYPE (name) = last;
        !          1610: 
        !          1611:          if (TREE_OPERAND (tmp, 0)
        !          1612:              && TREE_OPERAND (tmp, 0) != void_list_node)
        !          1613:            {
        !          1614:              cp_error ("`operator %T' requires empty parameter list", last);
        !          1615:              TREE_OPERAND (tmp, 0) = NULL_TREE;
        !          1616:            }
        !          1617: 
        !          1618:          if (of && TREE_CODE (of) != TYPE_DECL)
        !          1619:            return build_method_call (of, name, NULL_TREE, NULL_TREE, flags);
        !          1620:          else if (of)
        !          1621:            {
        !          1622:              tree this_this;
        !          1623: 
        !          1624:              if (current_class_decl == NULL_TREE)
        !          1625:                {
        !          1626:                  cp_error ("object required for `operator %T' call",
        !          1627:                            TREE_TYPE (name));
        !          1628:                  return error_mark_node;
        !          1629:                }
        !          1630: 
        !          1631:              this_this = convert_pointer_to (TREE_TYPE (of),
        !          1632:                                              current_class_decl);
        !          1633:              this_this = build_indirect_ref (this_this, NULL_PTR);
        !          1634:              return build_method_call (this_this, name, NULL_TREE,
        !          1635:                                        NULL_TREE, flags | LOOKUP_NONVIRTUAL);
        !          1636:            }
        !          1637:          else if (current_class_decl)
        !          1638:            return build_method_call (tmp, name, NULL_TREE, NULL_TREE, flags);
        !          1639: 
        !          1640:          cp_error ("object required for `operator %T' call",
        !          1641:                    TREE_TYPE (name));
        !          1642:          return error_mark_node;
        !          1643: 
        !          1644:        case INDIRECT_REF:
        !          1645:        case ADDR_EXPR:
        !          1646:        case ARRAY_REF:
        !          1647:          break;
        !          1648: 
        !          1649:        case SCOPE_REF:
        !          1650:          my_friendly_assert (cname == 0, 255);
        !          1651:          cname = TREE_OPERAND (tmp, 0);
        !          1652:          tmp = TREE_OPERAND (tmp, 1);
        !          1653:          break;
        !          1654: 
        !          1655:        default:
        !          1656:          my_friendly_abort (77);
        !          1657:        }
        !          1658:       last = tmp;
        !          1659:       tmp = TREE_OPERAND (tmp, 0);
        !          1660:     }
        !          1661: 
        !          1662:   last = groktypename (build_tree_list (TREE_TYPE (component), TREE_OPERAND (component, 0)));
        !          1663:   name = build_typename_overload (last);
        !          1664:   TREE_TYPE (name) = last;
        !          1665:   if (of && TREE_CODE (of) == TYPE_DECL)
        !          1666:     {
        !          1667:       if (cname == NULL_TREE)
        !          1668:        {
        !          1669:          cname = DECL_NAME (of);
        !          1670:          of = NULL_TREE;
        !          1671:        }
        !          1672:       else my_friendly_assert (cname == DECL_NAME (of), 256);
        !          1673:     }
        !          1674: 
        !          1675:   if (of)
        !          1676:     {
        !          1677:       tree this_this;
        !          1678: 
        !          1679:       if (current_class_decl == NULL_TREE)
        !          1680:        {
        !          1681:          cp_error ("object required for `operator %T' call",
        !          1682:                    TREE_TYPE (name));
        !          1683:          return error_mark_node;
        !          1684:        }
        !          1685: 
        !          1686:       this_this = convert_pointer_to (TREE_TYPE (of), current_class_decl);
        !          1687:       return build_component_ref (this_this, name, 0, protect);
        !          1688:     }
        !          1689:   else if (cname)
        !          1690:     return build_offset_ref (cname, name);
        !          1691:   else if (current_class_name)
        !          1692:     return build_offset_ref (current_class_name, name);
        !          1693: 
        !          1694:   cp_error ("object required for `operator %T' member reference",
        !          1695:            TREE_TYPE (name));
        !          1696:   return error_mark_node;
        !          1697: }
        !          1698: #endif
        !          1699: 
        !          1700: static char *
        !          1701: thunk_printable_name (decl)
        !          1702:      tree decl;
        !          1703: {
        !          1704:   return "<thunk function>";
        !          1705: }
        !          1706: 
        !          1707: tree
        !          1708: make_thunk (function, delta)
        !          1709:      tree function;
        !          1710:      int delta;
        !          1711: {
        !          1712:   char buffer[250];
        !          1713:   tree thunk_fndecl, thunk_id;
        !          1714:   tree thunk;
        !          1715:   char *func_name;
        !          1716:   static int thunk_number = 0;
        !          1717:   tree func_decl;
        !          1718:   if (TREE_CODE (function) != ADDR_EXPR)
        !          1719:     abort ();
        !          1720:   func_decl = TREE_OPERAND (function, 0);
        !          1721:   if (TREE_CODE (func_decl) != FUNCTION_DECL)
        !          1722:     abort ();
        !          1723:   func_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (func_decl));
        !          1724:   sprintf (buffer, "__thunk_%d_%s", -delta, func_name);
        !          1725:   thunk_id = get_identifier (buffer);
        !          1726:   thunk = IDENTIFIER_GLOBAL_VALUE (thunk_id);
        !          1727:   if (thunk && TREE_CODE (thunk) != THUNK_DECL)
        !          1728:     {
        !          1729:       error_with_decl ("implementation-reserved name `%s' used");
        !          1730:       IDENTIFIER_GLOBAL_VALUE (thunk_id) = thunk = NULL_TREE;
        !          1731:     }
        !          1732:   if (thunk == NULL_TREE)
        !          1733:     {
        !          1734:       thunk = build_decl (THUNK_DECL, thunk_id, TREE_TYPE (func_decl));
        !          1735:       DECL_RESULT (thunk)
        !          1736:        = build_decl (RESULT_DECL, NULL_TREE, TREE_TYPE (vtable_entry_type));
        !          1737:       make_function_rtl (thunk);
        !          1738:       DECL_INITIAL (thunk) = function;
        !          1739:       THUNK_DELTA (thunk) = delta;
        !          1740:       /* So that finish_file can write out any thunks that need to be: */
        !          1741:       pushdecl_top_level (thunk);
        !          1742:     }
        !          1743:   return thunk;
        !          1744: }
        !          1745: 
        !          1746: void
        !          1747: emit_thunk (thunk_fndecl)
        !          1748:   tree thunk_fndecl;
        !          1749: {
        !          1750:   rtx insns;
        !          1751:   char *fnname;
        !          1752:   char buffer[250];
        !          1753:   tree argp;
        !          1754:   struct args_size stack_args_size;
        !          1755:   tree function = TREE_OPERAND (DECL_INITIAL (thunk_fndecl), 0);
        !          1756:   int delta = THUNK_DELTA (thunk_fndecl);
        !          1757:   int tem;
        !          1758:   int failure = 0;
        !          1759:   int current_call_is_indirect = 0;    /* needed for HPPA FUNCTION_ARG */
        !          1760: 
        !          1761:   /* Used to remember which regs we need to emit a USE rtx for. */
        !          1762:   rtx need_use[FIRST_PSEUDO_REGISTER];
        !          1763:   int need_use_count = 0;
        !          1764: 
        !          1765:   /* rtx for the 'this' parameter. */
        !          1766:   rtx this_rtx = 0, this_reg_rtx = 0, fixed_this_rtx;
        !          1767: 
        !          1768:   char *(*save_decl_printable_name) () = decl_printable_name;
        !          1769:   /* Data on reg parms scanned so far.  */
        !          1770:   CUMULATIVE_ARGS args_so_far;
        !          1771: 
        !          1772:   if (TREE_ASM_WRITTEN (thunk_fndecl))
        !          1773:     return;
        !          1774: 
        !          1775:   TREE_ASM_WRITTEN (thunk_fndecl) = 1;
        !          1776: 
        !          1777:   if (TREE_PUBLIC (function))
        !          1778:     {
        !          1779:       TREE_PUBLIC (thunk_fndecl) = 1;
        !          1780:       if (DECL_EXTERNAL (function))
        !          1781:        {
        !          1782:          DECL_EXTERNAL (thunk_fndecl) = 1;
        !          1783:          assemble_external (thunk_fndecl);
        !          1784:          return;
        !          1785:        }
        !          1786:     }
        !          1787: 
        !          1788:   decl_printable_name = thunk_printable_name;
        !          1789:   if (current_function_decl)
        !          1790:     abort ();
        !          1791:   current_function_decl = thunk_fndecl;
        !          1792:   init_function_start (thunk_fndecl, input_filename, lineno);
        !          1793:   pushlevel (0);
        !          1794:   expand_start_bindings (1);
        !          1795: 
        !          1796:   /* Start updating where the next arg would go.  */
        !          1797:   INIT_CUMULATIVE_ARGS (args_so_far, TREE_TYPE (function), NULL_RTX);
        !          1798:   stack_args_size.constant = 0;
        !          1799:   stack_args_size.var = 0;
        !          1800:   /* SETUP for possible structure return address FIXME */
        !          1801: 
        !          1802:   /* Now look through all the parameters, make sure that we
        !          1803:      don't clobber any registers used for parameters.
        !          1804:      Also, pick up an rtx for the first "this" parameter. */
        !          1805:   for (argp = TYPE_ARG_TYPES (TREE_TYPE (function));
        !          1806:        argp != NULL_TREE;
        !          1807:        argp = TREE_CHAIN (argp))
        !          1808: 
        !          1809:     {
        !          1810:       tree passed_type = TREE_VALUE (argp);
        !          1811:       register rtx entry_parm;
        !          1812:       int named = 1; /* FIXME */
        !          1813:       struct args_size stack_offset;
        !          1814:       struct args_size arg_size;
        !          1815: 
        !          1816:       if (passed_type == void_type_node)
        !          1817:        break;
        !          1818: 
        !          1819:       if ((TREE_CODE (TYPE_SIZE (passed_type)) != INTEGER_CST
        !          1820:           && contains_placeholder_p (TYPE_SIZE (passed_type)))
        !          1821: #ifdef FUNCTION_ARG_PASS_BY_REFERENCE
        !          1822:          || FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far,
        !          1823:                                             TYPE_MODE (passed_type),
        !          1824:                                             passed_type, named)
        !          1825: #endif
        !          1826:          )
        !          1827:        passed_type = build_pointer_type (passed_type);
        !          1828: 
        !          1829:       entry_parm = FUNCTION_ARG (args_so_far,
        !          1830:                                 TYPE_MODE (passed_type),
        !          1831:                                 passed_type,
        !          1832:                                 named);
        !          1833:       if (entry_parm != 0)
        !          1834:        need_use[need_use_count++] = entry_parm;
        !          1835: 
        !          1836:       locate_and_pad_parm (TYPE_MODE (passed_type), passed_type,
        !          1837: #ifdef STACK_PARMS_IN_REG_PARM_AREA
        !          1838:                           1,
        !          1839: #else
        !          1840:                           entry_parm != 0,
        !          1841: #endif
        !          1842:                           thunk_fndecl,
        !          1843:                           &stack_args_size, &stack_offset, &arg_size);
        !          1844: 
        !          1845: /*    REGNO (entry_parm);*/
        !          1846:       if (this_rtx == 0)
        !          1847:        {
        !          1848:          this_reg_rtx = entry_parm;
        !          1849:          if (!entry_parm)
        !          1850:            {
        !          1851:              rtx offset_rtx = ARGS_SIZE_RTX (stack_offset);
        !          1852: 
        !          1853:              rtx internal_arg_pointer, stack_parm;
        !          1854: 
        !          1855:              if ((ARG_POINTER_REGNUM == STACK_POINTER_REGNUM
        !          1856:                   || ! (fixed_regs[ARG_POINTER_REGNUM]
        !          1857:                         || ARG_POINTER_REGNUM == FRAME_POINTER_REGNUM)))
        !          1858:                internal_arg_pointer = copy_to_reg (virtual_incoming_args_rtx);
        !          1859:              else
        !          1860:                internal_arg_pointer = virtual_incoming_args_rtx;
        !          1861: 
        !          1862:              if (offset_rtx == const0_rtx)
        !          1863:                entry_parm = gen_rtx (MEM, TYPE_MODE (passed_type),
        !          1864:                                      internal_arg_pointer);
        !          1865:              else
        !          1866:                entry_parm = gen_rtx (MEM, TYPE_MODE (passed_type),
        !          1867:                                      gen_rtx (PLUS, Pmode,
        !          1868:                                               internal_arg_pointer, 
        !          1869:                                               offset_rtx));
        !          1870:            }
        !          1871:          
        !          1872:          this_rtx = entry_parm;
        !          1873:        }
        !          1874: 
        !          1875:       FUNCTION_ARG_ADVANCE (args_so_far,
        !          1876:                            TYPE_MODE (passed_type),
        !          1877:                            passed_type,
        !          1878:                            named);
        !          1879:     }
        !          1880: 
        !          1881:   fixed_this_rtx = plus_constant (this_rtx, delta);
        !          1882:   if (this_rtx != fixed_this_rtx)
        !          1883:     emit_move_insn (this_rtx, fixed_this_rtx);
        !          1884: 
        !          1885:   if (this_reg_rtx)
        !          1886:     emit_insn (gen_rtx (USE, VOIDmode, this_reg_rtx));
        !          1887: 
        !          1888:   emit_indirect_jump (XEXP (DECL_RTL (function), 0));
        !          1889: 
        !          1890:   while (need_use_count > 0)
        !          1891:     emit_insn (gen_rtx (USE, VOIDmode, need_use[--need_use_count]));
        !          1892: 
        !          1893:   expand_end_bindings (NULL, 1, 0);
        !          1894:   poplevel (0, 0, 0);
        !          1895: 
        !          1896:   /* From now on, allocate rtl in current_obstack, not in saveable_obstack.
        !          1897:      Note that that may have been done above, in save_for_inline_copying.
        !          1898:      The call to resume_temporary_allocation near the end of this function
        !          1899:      goes back to the usual state of affairs.  */
        !          1900: 
        !          1901:   rtl_in_current_obstack ();
        !          1902: 
        !          1903:   insns = get_insns ();
        !          1904: 
        !          1905:   /* Copy any shared structure that should not be shared.  */
        !          1906: 
        !          1907:   unshare_all_rtl (insns);
        !          1908: 
        !          1909:   /* We are no longer anticipating cse in this function, at least.  */
        !          1910: 
        !          1911:   cse_not_expected = 1;
        !          1912: 
        !          1913:   /* Now we choose between stupid (pcc-like) register allocation
        !          1914:      (if we got the -noreg switch and not -opt)
        !          1915:      and smart register allocation.  */
        !          1916: 
        !          1917:   if (optimize > 0)                    /* Stupid allocation probably won't work */
        !          1918:     obey_regdecls = 0;         /* if optimizations being done.  */
        !          1919: 
        !          1920:   regclass_init ();
        !          1921: 
        !          1922:   regclass (insns, max_reg_num ());
        !          1923:   if (obey_regdecls)
        !          1924:     {
        !          1925:       stupid_life_analysis (insns, max_reg_num (), NULL);
        !          1926:       failure = reload (insns, 0, NULL);
        !          1927:     }
        !          1928:   else
        !          1929:     {
        !          1930:       /* Do control and data flow analysis,
        !          1931:         and write some of the results to dump file.  */
        !          1932: 
        !          1933:       flow_analysis (insns, max_reg_num (), NULL);
        !          1934:       local_alloc ();
        !          1935:       failure = global_alloc (NULL);
        !          1936:     }
        !          1937: 
        !          1938:   reload_completed = 1;
        !          1939: 
        !          1940: #ifdef LEAF_REGISTERS
        !          1941:   leaf_function = 0;
        !          1942:   if (optimize > 0 && only_leaf_regs_used () && leaf_function_p ())
        !          1943:     leaf_function = 1;
        !          1944: #endif
        !          1945: 
        !          1946:   /* If a machine dependent reorganization is needed, call it.  */
        !          1947: #ifdef MACHINE_DEPENDENT_REORG
        !          1948:    MACHINE_DEPENDENT_REORG (insns);
        !          1949: #endif
        !          1950: 
        !          1951:   /* Now turn the rtl into assembler code.  */
        !          1952: 
        !          1953:     {
        !          1954:       char *fnname = XSTR (XEXP (DECL_RTL (thunk_fndecl), 0), 0);
        !          1955:       assemble_start_function (thunk_fndecl, fnname);
        !          1956:       final (insns, asm_out_file, optimize, 0);
        !          1957:       assemble_end_function (thunk_fndecl, fnname);
        !          1958:     };
        !          1959: 
        !          1960:  exit_rest_of_compilation:
        !          1961: 
        !          1962:   reload_completed = 0;
        !          1963: 
        !          1964:   /* Cancel the effect of rtl_in_current_obstack.  */
        !          1965: 
        !          1966:   resume_temporary_allocation ();
        !          1967: 
        !          1968:   decl_printable_name = save_decl_printable_name;
        !          1969:   current_function_decl = 0;
        !          1970: }
        !          1971: 
        !          1972: /* Code for synthesizing methods which have default semantics defined.  */
        !          1973: 
        !          1974: void
        !          1975: build_default_constructor (fndecl)
        !          1976:      tree fndecl;
        !          1977: {
        !          1978:   start_function (NULL_TREE, fndecl, NULL_TREE, 1);
        !          1979:   store_parm_decls ();
        !          1980:   setup_vtbl_ptr ();
        !          1981:   finish_function (lineno, 0);
        !          1982: }
        !          1983: 
        !          1984: /* For the anonymous union in TYPE, return the member that is at least as
        !          1985:    large as the rest of the members, so we can copy it.  */
        !          1986: static tree
        !          1987: largest_union_member (type)
        !          1988:      tree type;
        !          1989: {
        !          1990:   tree f, type_size = TYPE_SIZE (type);
        !          1991: 
        !          1992:   for (f = TYPE_FIELDS (type); f; f = TREE_CHAIN (f))
        !          1993:     if (simple_cst_equal (DECL_SIZE (f), type_size))
        !          1994:       return f;
        !          1995: 
        !          1996:   /* We should always find one.  */
        !          1997:   my_friendly_abort (323);
        !          1998:   return NULL_TREE;
        !          1999: }
        !          2000: 
        !          2001: /* Generate code for default X(X&) constructor.  */
        !          2002: void
        !          2003: build_copy_constructor (fndecl)
        !          2004:      tree fndecl;
        !          2005: {
        !          2006:   tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl));
        !          2007:   tree t;
        !          2008: 
        !          2009:   start_function (NULL_TREE, fndecl, NULL_TREE, 1);
        !          2010:   store_parm_decls ();
        !          2011:   clear_last_expr ();
        !          2012:   push_momentary ();
        !          2013: 
        !          2014:   if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type))
        !          2015:     parm = TREE_CHAIN (parm);
        !          2016:   parm = convert_from_reference (parm);
        !          2017: 
        !          2018:   if (! TYPE_HAS_COMPLEX_INIT_REF (current_class_type))
        !          2019:     {
        !          2020:       t = build (INIT_EXPR, void_type_node, C_C_D, parm);
        !          2021:       TREE_SIDE_EFFECTS (t) = 1;
        !          2022:       cplus_expand_expr_stmt (t);
        !          2023:     }
        !          2024:   else
        !          2025:     {
        !          2026:       tree fields = TYPE_FIELDS (current_class_type);
        !          2027:       int n_bases = CLASSTYPE_N_BASECLASSES (current_class_type);
        !          2028:       tree binfos = TYPE_BINFO_BASETYPES (current_class_type);
        !          2029:       int i;
        !          2030: 
        !          2031:       for (t = CLASSTYPE_VBASECLASSES (current_class_type); t;
        !          2032:           t = TREE_CHAIN (t))
        !          2033:        {
        !          2034:          tree basetype = BINFO_TYPE (t);
        !          2035:          tree p = convert (build_reference_type (basetype), parm);
        !          2036:          p = convert_from_reference (p);
        !          2037:          current_base_init_list = tree_cons (TYPE_NESTED_NAME (basetype),
        !          2038:                                              p, current_base_init_list);
        !          2039:        }
        !          2040:        
        !          2041:       for (i = 0; i < n_bases; ++i)
        !          2042:        {
        !          2043:          tree p, basetype = TREE_VEC_ELT (binfos, i);
        !          2044:          if (TREE_VIA_VIRTUAL (basetype))
        !          2045:            continue;     
        !          2046: 
        !          2047:          basetype = BINFO_TYPE (basetype);
        !          2048:          p = convert (build_reference_type (basetype), parm);
        !          2049:          p = convert_from_reference (p);
        !          2050:          current_base_init_list = tree_cons (TYPE_NESTED_NAME (basetype),
        !          2051:                                              p, current_base_init_list);
        !          2052:        }
        !          2053:       for (; fields; fields = TREE_CHAIN (fields))
        !          2054:        {
        !          2055:          tree name, init, t;
        !          2056:          if (TREE_CODE (fields) != FIELD_DECL)
        !          2057:            continue;
        !          2058:          if (DECL_NAME (fields))
        !          2059:            {
        !          2060:              if (VFIELD_NAME_P (DECL_NAME (fields)))
        !          2061:                continue;
        !          2062:              if (VBASE_NAME_P (DECL_NAME (fields)))
        !          2063:                continue;
        !          2064: 
        !          2065:              /* True for duplicate members.  */
        !          2066:              if (IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) != fields)
        !          2067:                continue;
        !          2068:            }
        !          2069:          else if ((t = TREE_TYPE (fields)) != NULL_TREE
        !          2070:                   && TREE_CODE (t) == UNION_TYPE
        !          2071:                   && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))
        !          2072:                   && TYPE_FIELDS (t) != NULL_TREE)
        !          2073:            fields = largest_union_member (t);
        !          2074:          else
        !          2075:            continue;
        !          2076: 
        !          2077:          init = build (COMPONENT_REF, TREE_TYPE (fields), parm, fields);
        !          2078:          init = build_tree_list (NULL_TREE, init);
        !          2079: 
        !          2080:          current_member_init_list
        !          2081:            = tree_cons (DECL_NAME (fields), init, current_member_init_list);
        !          2082:        }
        !          2083:       current_member_init_list = nreverse (current_member_init_list);
        !          2084:       setup_vtbl_ptr ();
        !          2085:     }
        !          2086: 
        !          2087:   pop_momentary ();
        !          2088:   finish_function (lineno, 0);
        !          2089: }
        !          2090: 
        !          2091: void
        !          2092: build_assign_ref (fndecl)
        !          2093:      tree fndecl;
        !          2094: {
        !          2095:   tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl));
        !          2096: 
        !          2097:   start_function (NULL_TREE, fndecl, NULL_TREE, 1);
        !          2098:   store_parm_decls ();
        !          2099:   push_momentary ();
        !          2100: 
        !          2101:   parm = convert_from_reference (parm);
        !          2102: 
        !          2103:   if (! TYPE_HAS_COMPLEX_ASSIGN_REF (current_class_type))
        !          2104:     {
        !          2105:       tree t = build (MODIFY_EXPR, void_type_node, C_C_D, parm);
        !          2106:       TREE_SIDE_EFFECTS (t) = 1;
        !          2107:       cplus_expand_expr_stmt (t);
        !          2108:     }
        !          2109:   else
        !          2110:     {
        !          2111:       tree fields = TYPE_FIELDS (current_class_type);
        !          2112:       int n_bases = CLASSTYPE_N_BASECLASSES (current_class_type);
        !          2113:       tree binfos = TYPE_BINFO_BASETYPES (current_class_type);
        !          2114:       int i;
        !          2115: 
        !          2116:       for (i = 0; i < n_bases; ++i)
        !          2117:        {
        !          2118:          tree basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, i));
        !          2119:          if (TYPE_HAS_ASSIGN_REF (basetype))
        !          2120:            {
        !          2121:              tree p = convert (build_reference_type (basetype), parm);
        !          2122:              p = convert_from_reference (p);
        !          2123:              p = build_member_call (TYPE_NESTED_NAME (basetype),
        !          2124:                                     ansi_opname [MODIFY_EXPR],
        !          2125:                                     build_tree_list (NULL_TREE, p));
        !          2126:              expand_expr_stmt (p);
        !          2127:            }
        !          2128:        }
        !          2129:       for (; fields; fields = TREE_CHAIN (fields))
        !          2130:        {
        !          2131:          tree comp, init, t;
        !          2132:          if (TREE_CODE (fields) != FIELD_DECL)
        !          2133:            continue;
        !          2134:          if (DECL_NAME (fields))
        !          2135:            {
        !          2136:              if (VFIELD_NAME_P (DECL_NAME (fields)))
        !          2137:                continue;
        !          2138:              if (VBASE_NAME_P (DECL_NAME (fields)))
        !          2139:                continue;
        !          2140: 
        !          2141:              /* True for duplicate members.  */
        !          2142:              if (IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) != fields)
        !          2143:                continue;
        !          2144:            }
        !          2145:          else if ((t = TREE_TYPE (fields)) != NULL_TREE
        !          2146:                   && TREE_CODE (t) == UNION_TYPE
        !          2147:                   && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))
        !          2148:                   && TYPE_FIELDS (t) != NULL_TREE)
        !          2149:            fields = largest_union_member (t);
        !          2150:          else
        !          2151:            continue;
        !          2152: 
        !          2153:          comp = build (COMPONENT_REF, TREE_TYPE (fields), C_C_D, fields);
        !          2154:          init = build (COMPONENT_REF, TREE_TYPE (fields), parm, fields);
        !          2155: 
        !          2156:          expand_expr_stmt (build_modify_expr (comp, NOP_EXPR, init));
        !          2157:        }
        !          2158:     }
        !          2159:   c_expand_return (C_C_D);
        !          2160:   pop_momentary ();
        !          2161:   finish_function (lineno, 0);
        !          2162: }
        !          2163: 
        !          2164: void
        !          2165: build_dtor (fndecl)
        !          2166:      tree fndecl;
        !          2167: {
        !          2168:   start_function (NULL_TREE, fndecl, NULL_TREE, 1);
        !          2169:   store_parm_decls ();
        !          2170:   finish_function (lineno, 0);
        !          2171: }

unix.superglobalmegacorp.com

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