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

1.1       root        1: /* Handle the hair of processing (but not expanding) inline functions.
                      2:    Also manage function and variable name overloading.
                      3:    Copyright (C) 1987, 1989, 1992, 1993 Free Software Foundation, Inc.
                      4:    Contributed by Michael Tiemann ([email protected])
                      5: 
                      6:    This file is part of GNU CC.
                      7:    
                      8: GNU CC is free software; you can redistribute it and/or modify
                      9: it under the terms of the GNU General Public License as published by
                     10: the Free Software Foundation; either version 2, or (at your option)
                     11: any later version.
                     12: 
                     13: GNU CC is distributed in the hope that it will be useful,
                     14: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     15: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     16: GNU General Public License for more details.
                     17: 
                     18: You should have received a copy of the GNU General Public License
                     19: along with GNU CC; see the file COPYING.  If not, write to
                     20: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
                     21: 
                     22: 
                     23: #ifndef PARM_CAN_BE_ARRAY_TYPE
                     24: #define PARM_CAN_BE_ARRAY_TYPE 1
                     25: #endif
                     26: 
                     27: /* Handle method declarations.  */
                     28: #include <stdio.h>
                     29: #include "config.h"
                     30: #include "tree.h"
                     31: #include "cp-tree.h"
                     32: #include "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.