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

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

unix.superglobalmegacorp.com

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