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

1.1     ! root        1: /* Separate lexical analyzer for GNU C++.
        !             2:    Copyright (C) 1987, 1989, 1992, 1993, 1994 Free Software Foundation, Inc.
        !             3:    Hacked by Michael Tiemann ([email protected])
        !             4: 
        !             5: This file is part of GNU CC.
        !             6: 
        !             7: GNU CC is free software; you can redistribute it and/or modify
        !             8: it under the terms of the GNU General Public License as published by
        !             9: the Free Software Foundation; either version 2, or (at your option)
        !            10: any later version.
        !            11: 
        !            12: GNU CC is distributed in the hope that it will be useful,
        !            13: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            15: GNU General Public License for more details.
        !            16: 
        !            17: You should have received a copy of the GNU General Public License
        !            18: along with GNU CC; see the file COPYING.  If not, write to
        !            19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
        !            20: 
        !            21: 
        !            22: /* This file is the lexical analyzer for GNU C++.  */
        !            23: 
        !            24: /* Cause the `yydebug' variable to be defined.  */
        !            25: #define YYDEBUG 1
        !            26: 
        !            27: #include <sys/types.h>
        !            28: #include <stdio.h>
        !            29: #include <errno.h>
        !            30: #include <setjmp.h>
        !            31: #include "config.h"
        !            32: #include "input.h"
        !            33: #include "tree.h"
        !            34: #include "lex.h"
        !            35: #include "parse.h"
        !            36: #include "cp-tree.h"
        !            37: #include "flags.h"
        !            38: #include "obstack.h"
        !            39: 
        !            40: #ifdef MULTIBYTE_CHARS
        !            41: #include <stdlib.h>
        !            42: #include <locale.h>
        !            43: #endif
        !            44: 
        !            45: #ifndef errno
        !            46: extern int errno;              /* needed for VAX.  */
        !            47: #endif
        !            48: extern jmp_buf toplevel;
        !            49: 
        !            50: #define obstack_chunk_alloc xmalloc
        !            51: #define obstack_chunk_free free
        !            52: 
        !            53: extern struct obstack *expression_obstack, permanent_obstack;
        !            54: extern struct obstack *current_obstack, *saveable_obstack;
        !            55: 
        !            56: extern double atof ();
        !            57: 
        !            58: extern char *get_directive_line ();    /* In c-common.c */
        !            59: 
        !            60: /* Given a file name X, return the nondirectory portion.
        !            61:    Keep in mind that X can be computed more than once.  */
        !            62: #ifndef FILE_NAME_NONDIRECTORY
        !            63: #define FILE_NAME_NONDIRECTORY(X)              \
        !            64:  (rindex (X, '/') != 0 ? rindex (X, '/') + 1 : X)
        !            65: #endif
        !            66: 
        !            67: extern char *index ();
        !            68: extern char *rindex ();
        !            69: 
        !            70: void extract_interface_info ();
        !            71: void yyerror ();
        !            72: 
        !            73: /* This obstack is needed to hold text.  It is not safe to use
        !            74:    TOKEN_BUFFER because `check_newline' calls `yylex'.  */
        !            75: struct obstack inline_text_obstack;
        !            76: static char *inline_text_firstobj;
        !            77: 
        !            78: /* This obstack is used to hold information about methods to be
        !            79:    synthesized.  It should go away when synthesized methods are handled
        !            80:    properly (i.e. only when needed).  */
        !            81: struct obstack synth_obstack;
        !            82: static char *synth_firstobj;
        !            83: 
        !            84: int end_of_file;
        !            85: 
        !            86: /* Pending language change.
        !            87:    Positive is push count, negative is pop count.  */
        !            88: int pending_lang_change = 0;
        !            89: 
        !            90: /* Wrap the current header file in extern "C".  */
        !            91: static int c_header_level = 0;
        !            92: 
        !            93: extern int first_token;
        !            94: extern struct obstack token_obstack;
        !            95: 
        !            96: /* ??? Don't really know where this goes yet.  */
        !            97: #if 1
        !            98: #include "input.c"
        !            99: #else
        !           100: extern void put_back (/* int */);
        !           101: extern int input_redirected ();
        !           102: extern void feed_input (/* char *, int, struct obstack * */);
        !           103: #endif
        !           104: 
        !           105: /* Holds translations from TREE_CODEs to operator name strings,
        !           106:    i.e., opname_tab[PLUS_EXPR] == "+".  */
        !           107: char **opname_tab;
        !           108: char **assignop_tab;
        !           109: 
        !           110: extern int yychar;             /*  the lookahead symbol                */
        !           111: extern YYSTYPE yylval;         /*  the semantic value of the           */
        !           112:                                /*  lookahead symbol                    */
        !           113: 
        !           114: #if 0
        !           115: YYLTYPE yylloc;                        /*  location data for the lookahead     */
        !           116:                                /*  symbol                              */
        !           117: #endif
        !           118: 
        !           119: 
        !           120: /* the declaration found for the last IDENTIFIER token read in.
        !           121:    yylex must look this up to detect typedefs, which get token type TYPENAME,
        !           122:    so it is left around in case the identifier is not a typedef but is
        !           123:    used in a context which makes it a reference to a variable.  */
        !           124: tree lastiddecl;
        !           125: 
        !           126: /* The elements of `ridpointers' are identifier nodes
        !           127:    for the reserved type names and storage classes.
        !           128:    It is indexed by a RID_... value.  */
        !           129: tree ridpointers[(int) RID_MAX];
        !           130: 
        !           131: /* We may keep statistics about how long which files took to compile.  */
        !           132: static int header_time, body_time;
        !           133: static tree get_time_identifier ();
        !           134: static tree filename_times;
        !           135: static tree this_filename_time;
        !           136: 
        !           137: /* For implementing #pragma unit.  */
        !           138: tree current_unit_name;
        !           139: tree current_unit_language;
        !           140: 
        !           141: /* Array for holding counts of the numbers of tokens seen.  */
        !           142: extern int *token_count;
        !           143: 
        !           144: /* Textual definition used for default functions.  */
        !           145: static void default_copy_constructor_body ();
        !           146: static void default_assign_ref_body ();
        !           147: 
        !           148: /* Return something to represent absolute declarators containing a *.
        !           149:    TARGET is the absolute declarator that the * contains.
        !           150:    TYPE_QUALS is a list of modifiers such as const or volatile
        !           151:    to apply to the pointer type, represented as identifiers.
        !           152: 
        !           153:    We return an INDIRECT_REF whose "contents" are TARGET
        !           154:    and whose type is the modifier list.  */
        !           155: 
        !           156: tree
        !           157: make_pointer_declarator (type_quals, target)
        !           158:      tree type_quals, target;
        !           159: {
        !           160:   if (target && TREE_CODE (target) == IDENTIFIER_NODE
        !           161:       && ANON_AGGRNAME_P (target))
        !           162:     error ("type name expected before `*'");
        !           163:   target = build_parse_node (INDIRECT_REF, target);
        !           164:   TREE_TYPE (target) = type_quals;
        !           165:   return target;
        !           166: }
        !           167: 
        !           168: /* Return something to represent absolute declarators containing a &.
        !           169:    TARGET is the absolute declarator that the & contains.
        !           170:    TYPE_QUALS is a list of modifiers such as const or volatile
        !           171:    to apply to the reference type, represented as identifiers.
        !           172: 
        !           173:    We return an ADDR_EXPR whose "contents" are TARGET
        !           174:    and whose type is the modifier list.  */
        !           175:    
        !           176: tree
        !           177: make_reference_declarator (type_quals, target)
        !           178:      tree type_quals, target;
        !           179: {
        !           180:   if (target)
        !           181:     {
        !           182:       if (TREE_CODE (target) == ADDR_EXPR)
        !           183:        {
        !           184:          error ("cannot declare references to references");
        !           185:          return target;
        !           186:        }
        !           187:       if (TREE_CODE (target) == INDIRECT_REF)
        !           188:        {
        !           189:          error ("cannot declare pointers to references");
        !           190:          return target;
        !           191:        }
        !           192:       if (TREE_CODE (target) == IDENTIFIER_NODE && ANON_AGGRNAME_P (target))
        !           193:          error ("type name expected before `&'");
        !           194:     }
        !           195:   target = build_parse_node (ADDR_EXPR, target);
        !           196:   TREE_TYPE (target) = type_quals;
        !           197:   return target;
        !           198: }
        !           199: 
        !           200: /* Build names and nodes for overloaded operators.  */
        !           201: 
        !           202: tree ansi_opname[LAST_CPLUS_TREE_CODE];
        !           203: tree ansi_assopname[LAST_CPLUS_TREE_CODE];
        !           204: 
        !           205: char *
        !           206: operator_name_string (name)
        !           207:      tree name;
        !           208: {
        !           209:   char *opname = IDENTIFIER_POINTER (name) + 2;
        !           210:   tree *opname_table;
        !           211:   int i, assign;
        !           212: 
        !           213:   /* Works for builtin and user defined types.  */
        !           214:   if (IDENTIFIER_GLOBAL_VALUE (name)
        !           215:       && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (name)) == TYPE_DECL)
        !           216:     return IDENTIFIER_POINTER (name);
        !           217: 
        !           218:   if (opname[0] == 'a' && opname[2] != '\0' && opname[2] != '_')
        !           219:     {
        !           220:       opname += 1;
        !           221:       assign = 1;
        !           222:       opname_table = ansi_assopname;
        !           223:     }
        !           224:   else
        !           225:     {
        !           226:       assign = 0;
        !           227:       opname_table = ansi_opname;
        !           228:     }
        !           229: 
        !           230:   for (i = 0; i < (int) LAST_CPLUS_TREE_CODE; i++)
        !           231:     {
        !           232:       if (opname[0] == IDENTIFIER_POINTER (opname_table[i])[2+assign]
        !           233:          && opname[1] == IDENTIFIER_POINTER (opname_table[i])[3+assign])
        !           234:        break;
        !           235:     }
        !           236: 
        !           237:   if (i == LAST_CPLUS_TREE_CODE)
        !           238:     return "<invalid operator>";
        !           239: 
        !           240:   if (assign)
        !           241:     return assignop_tab[i];
        !           242:   else
        !           243:     return opname_tab[i];
        !           244: }
        !           245: 
        !           246: int interface_only;            /* whether or not current file is only for
        !           247:                                   interface definitions.  */
        !           248: int interface_unknown;         /* whether or not we know this class
        !           249:                                   to behave according to #pragma interface.  */
        !           250: 
        !           251: /* lexical analyzer */
        !           252: 
        !           253: /* File used for outputting assembler code.  */
        !           254: extern FILE *asm_out_file;
        !           255: 
        !           256: #ifndef WCHAR_TYPE_SIZE
        !           257: #ifdef INT_TYPE_SIZE
        !           258: #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
        !           259: #else
        !           260: #define WCHAR_TYPE_SIZE        BITS_PER_WORD
        !           261: #endif
        !           262: #endif
        !           263: 
        !           264: /* Number of bytes in a wide character.  */
        !           265: #define WCHAR_BYTES (WCHAR_TYPE_SIZE / BITS_PER_UNIT)
        !           266: 
        !           267: static int maxtoken;           /* Current nominal length of token buffer.  */
        !           268: char *token_buffer;            /* Pointer to token buffer.
        !           269:                                   Actual allocated length is maxtoken + 2.  */
        !           270: 
        !           271: #include "hash.h"
        !           272: 
        !           273: int check_newline ();
        !           274: 
        !           275: /* Nonzero tells yylex to ignore \ in string constants.  */
        !           276: static int ignore_escape_flag = 0;
        !           277: 
        !           278: static int skip_white_space ();
        !           279: 
        !           280: static tree
        !           281: get_time_identifier (name)
        !           282:      char *name;
        !           283: {
        !           284:   tree time_identifier;
        !           285:   int len = strlen (name);
        !           286:   char *buf = (char *) alloca (len + 6);
        !           287:   strcpy (buf, "file ");
        !           288:   bcopy (name, buf+5, len);
        !           289:   buf[len+5] = '\0';
        !           290:   time_identifier = get_identifier (buf);
        !           291:   if (IDENTIFIER_LOCAL_VALUE (time_identifier) == NULL_TREE)
        !           292:     {
        !           293:       push_obstacks_nochange ();
        !           294:       end_temporary_allocation ();
        !           295:       IDENTIFIER_LOCAL_VALUE (time_identifier) = build_int_2 (0, 0);
        !           296:       IDENTIFIER_CLASS_VALUE (time_identifier) = build_int_2 (0, 1);
        !           297:       IDENTIFIER_GLOBAL_VALUE (time_identifier) = filename_times;
        !           298:       filename_times = time_identifier;
        !           299:       pop_obstacks ();
        !           300:     }
        !           301:   return time_identifier;
        !           302: }
        !           303: 
        !           304: #ifdef __GNUC__
        !           305: __inline
        !           306: #endif
        !           307: static int
        !           308: my_get_run_time ()
        !           309: {
        !           310:   int old_quiet_flag = quiet_flag;
        !           311:   int this_time;
        !           312:   quiet_flag = 0;
        !           313:   this_time = get_run_time ();
        !           314:   quiet_flag = old_quiet_flag;
        !           315:   return this_time;
        !           316: }
        !           317: 
        !           318: /* Table indexed by tree code giving a string containing a character
        !           319:    classifying the tree code.  Possibilities are
        !           320:    t, d, s, c, r, <, 1 and 2.  See cp/tree.def for details.  */
        !           321: 
        !           322: #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
        !           323: 
        !           324: char *cplus_tree_code_type[] = {
        !           325:   "x",
        !           326: #include "tree.def"
        !           327: };
        !           328: #undef DEFTREECODE
        !           329: 
        !           330: /* Table indexed by tree code giving number of expression
        !           331:    operands beyond the fixed part of the node structure.
        !           332:    Not used for types or decls.  */
        !           333: 
        !           334: #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
        !           335: 
        !           336: int cplus_tree_code_length[] = {
        !           337:   0,
        !           338: #include "tree.def"
        !           339: };
        !           340: #undef DEFTREECODE
        !           341: 
        !           342: /* Names of tree components.
        !           343:    Used for printing out the tree and error messages.  */
        !           344: #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
        !           345: 
        !           346: char *cplus_tree_code_name[] = {
        !           347:   "@@dummy",
        !           348: #include "tree.def"
        !           349: };
        !           350: #undef DEFTREECODE
        !           351: 
        !           352: /* toplev.c needs to call these.  */
        !           353: 
        !           354: void
        !           355: lang_init ()
        !           356: {
        !           357:   /* the beginning of the file is a new line; check for # */
        !           358:   /* With luck, we discover the real source file's name from that
        !           359:      and put it in input_filename.  */
        !           360:   put_back (check_newline ());
        !           361: 
        !           362:   if (flag_cadillac)
        !           363:     cadillac_start ();
        !           364:   if (flag_gnu_xref) GNU_xref_begin (input_filename);
        !           365: }
        !           366: 
        !           367: void
        !           368: lang_finish ()
        !           369: {
        !           370:   extern int errorcount, sorrycount;
        !           371:   if (flag_gnu_xref) GNU_xref_end (errorcount+sorrycount);
        !           372: }
        !           373: 
        !           374: char *
        !           375: lang_identify ()
        !           376: {
        !           377:   return "cplusplus";
        !           378: }
        !           379: 
        !           380: void
        !           381: init_filename_times ()
        !           382: {
        !           383:   this_filename_time = get_time_identifier ("<top level>");
        !           384:   if (flag_detailed_statistics)
        !           385:     {
        !           386:       header_time = 0;
        !           387:       body_time = my_get_run_time ();
        !           388:       TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time)) = body_time;
        !           389:     }
        !           390: }
        !           391: 
        !           392: /* Change by Bryan Boreham, Kewill, Thu Jul 27 09:46:05 1989.
        !           393:    Stuck this hack in to get the files open correctly; this is called
        !           394:    in place of init_lex if we are an unexec'd binary.    */
        !           395: void
        !           396: reinit_lang_specific ()
        !           397: {
        !           398:   init_filename_times ();
        !           399:   reinit_search_statistics ();
        !           400: }
        !           401: 
        !           402: void
        !           403: init_lex ()
        !           404: {
        !           405:   extern char *(*decl_printable_name) ();
        !           406: 
        !           407:   int i;
        !           408: 
        !           409:   /* Initialize the lookahead machinery.  */
        !           410:   init_spew ();
        !           411: 
        !           412:   /* Make identifier nodes long enough for the language-specific slots.  */
        !           413:   set_identifier_size (sizeof (struct lang_identifier));
        !           414:   decl_printable_name = lang_printable_name;
        !           415: 
        !           416:   init_cplus_expand ();
        !           417: 
        !           418:   tree_code_type
        !           419:     = (char **) realloc (tree_code_type,
        !           420:                         sizeof (char *) * LAST_CPLUS_TREE_CODE);
        !           421:   tree_code_length
        !           422:     = (int *) realloc (tree_code_length,
        !           423:                       sizeof (int) * LAST_CPLUS_TREE_CODE);
        !           424:   tree_code_name
        !           425:     = (char **) realloc (tree_code_name,
        !           426:                         sizeof (char *) * LAST_CPLUS_TREE_CODE);
        !           427:   bcopy ((char *)cplus_tree_code_type,
        !           428:         (char *)(tree_code_type + (int) LAST_AND_UNUSED_TREE_CODE),
        !           429:         (LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (char *));
        !           430:   bcopy ((char *)cplus_tree_code_length,
        !           431:         (char *)(tree_code_length + (int) LAST_AND_UNUSED_TREE_CODE),
        !           432:         (LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (int));
        !           433:   bcopy ((char *)cplus_tree_code_name,
        !           434:         (char *)(tree_code_name + (int) LAST_AND_UNUSED_TREE_CODE),
        !           435:         (LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (char *));
        !           436: 
        !           437:   opname_tab = (char **)oballoc ((int)LAST_CPLUS_TREE_CODE * sizeof (char *));
        !           438:   bzero ((char *)opname_tab, (int)LAST_CPLUS_TREE_CODE * sizeof (char *));
        !           439:   assignop_tab = (char **)oballoc ((int)LAST_CPLUS_TREE_CODE * sizeof (char *));
        !           440:   bzero ((char *)assignop_tab, (int)LAST_CPLUS_TREE_CODE * sizeof (char *));
        !           441: 
        !           442:   ansi_opname[0] = get_identifier ("<invalid operator>");
        !           443:   for (i = 0; i < (int) LAST_CPLUS_TREE_CODE; i++)
        !           444:     {
        !           445:       ansi_opname[i] = ansi_opname[0];
        !           446:       ansi_assopname[i] = ansi_opname[0];
        !           447:     }
        !           448: 
        !           449:   ansi_opname[(int) MULT_EXPR] = get_identifier ("__ml");
        !           450:   IDENTIFIER_OPNAME_P (ansi_opname[(int) MULT_EXPR]) = 1;
        !           451:   ansi_opname[(int) INDIRECT_REF] = ansi_opname[(int) MULT_EXPR];
        !           452:   ansi_assopname[(int) MULT_EXPR] = get_identifier ("__aml");
        !           453:   IDENTIFIER_OPNAME_P (ansi_assopname[(int) MULT_EXPR]) = 1;
        !           454:   ansi_assopname[(int) INDIRECT_REF] = ansi_assopname[(int) MULT_EXPR];
        !           455:   ansi_opname[(int) TRUNC_MOD_EXPR] = get_identifier ("__md");
        !           456:   IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUNC_MOD_EXPR]) = 1;
        !           457:   ansi_assopname[(int) TRUNC_MOD_EXPR] = get_identifier ("__amd");
        !           458:   IDENTIFIER_OPNAME_P (ansi_assopname[(int) TRUNC_MOD_EXPR]) = 1;
        !           459:   ansi_opname[(int) CEIL_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR];
        !           460:   ansi_opname[(int) FLOOR_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR];
        !           461:   ansi_opname[(int) ROUND_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR];
        !           462:   ansi_opname[(int) MINUS_EXPR] = get_identifier ("__mi");
        !           463:   IDENTIFIER_OPNAME_P (ansi_opname[(int) MINUS_EXPR]) = 1;
        !           464:   ansi_opname[(int) NEGATE_EXPR] = ansi_opname[(int) MINUS_EXPR];
        !           465:   ansi_assopname[(int) MINUS_EXPR] = get_identifier ("__ami");
        !           466:   IDENTIFIER_OPNAME_P (ansi_assopname[(int) MINUS_EXPR]) = 1;
        !           467:   ansi_assopname[(int) NEGATE_EXPR] = ansi_assopname[(int) MINUS_EXPR];
        !           468:   ansi_opname[(int) RSHIFT_EXPR] = get_identifier ("__rs");
        !           469:   IDENTIFIER_OPNAME_P (ansi_opname[(int) RSHIFT_EXPR]) = 1;
        !           470:   ansi_assopname[(int) RSHIFT_EXPR] = get_identifier ("__ars");
        !           471:   IDENTIFIER_OPNAME_P (ansi_assopname[(int) RSHIFT_EXPR]) = 1;
        !           472:   ansi_opname[(int) NE_EXPR] = get_identifier ("__ne");
        !           473:   IDENTIFIER_OPNAME_P (ansi_opname[(int) NE_EXPR]) = 1;
        !           474:   ansi_opname[(int) GT_EXPR] = get_identifier ("__gt");
        !           475:   IDENTIFIER_OPNAME_P (ansi_opname[(int) GT_EXPR]) = 1;
        !           476:   ansi_opname[(int) GE_EXPR] = get_identifier ("__ge");
        !           477:   IDENTIFIER_OPNAME_P (ansi_opname[(int) GE_EXPR]) = 1;
        !           478:   ansi_opname[(int) BIT_IOR_EXPR] = get_identifier ("__or");
        !           479:   IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_IOR_EXPR]) = 1;
        !           480:   ansi_assopname[(int) BIT_IOR_EXPR] = get_identifier ("__aor");
        !           481:   IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_IOR_EXPR]) = 1;
        !           482:   ansi_opname[(int) TRUTH_ANDIF_EXPR] = get_identifier ("__aa");
        !           483:   IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_ANDIF_EXPR]) = 1;
        !           484:   ansi_opname[(int) TRUTH_NOT_EXPR] = get_identifier ("__nt");
        !           485:   IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_NOT_EXPR]) = 1;
        !           486:   ansi_opname[(int) PREINCREMENT_EXPR] = get_identifier ("__pp");
        !           487:   IDENTIFIER_OPNAME_P (ansi_opname[(int) PREINCREMENT_EXPR]) = 1;
        !           488:   ansi_opname[(int) POSTINCREMENT_EXPR] = ansi_opname[(int) PREINCREMENT_EXPR];
        !           489:   ansi_opname[(int) MODIFY_EXPR] = get_identifier ("__as");
        !           490:   IDENTIFIER_OPNAME_P (ansi_opname[(int) MODIFY_EXPR]) = 1;
        !           491:   ansi_assopname[(int) NOP_EXPR] = ansi_opname[(int) MODIFY_EXPR];
        !           492:   ansi_opname[(int) COMPOUND_EXPR] = get_identifier ("__cm");
        !           493:   IDENTIFIER_OPNAME_P (ansi_opname[(int) COMPOUND_EXPR]) = 1;
        !           494:   ansi_opname[(int) EXACT_DIV_EXPR] = get_identifier ("__dv");
        !           495:   IDENTIFIER_OPNAME_P (ansi_opname[(int) EXACT_DIV_EXPR]) = 1;
        !           496:   ansi_assopname[(int) EXACT_DIV_EXPR] = get_identifier ("__adv");
        !           497:   IDENTIFIER_OPNAME_P (ansi_assopname[(int) EXACT_DIV_EXPR]) = 1;
        !           498:   ansi_opname[(int) TRUNC_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR];
        !           499:   ansi_opname[(int) CEIL_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR];
        !           500:   ansi_opname[(int) FLOOR_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR];
        !           501:   ansi_opname[(int) ROUND_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR];
        !           502:   ansi_opname[(int) PLUS_EXPR] = get_identifier ("__pl");
        !           503:   ansi_assopname[(int) TRUNC_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
        !           504:   ansi_assopname[(int) CEIL_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
        !           505:   ansi_assopname[(int) FLOOR_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
        !           506:   ansi_assopname[(int) ROUND_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
        !           507:   IDENTIFIER_OPNAME_P (ansi_opname[(int) PLUS_EXPR]) = 1;
        !           508:   ansi_assopname[(int) PLUS_EXPR] = get_identifier ("__apl");
        !           509:   IDENTIFIER_OPNAME_P (ansi_assopname[(int) PLUS_EXPR]) = 1;
        !           510:   ansi_opname[(int) CONVERT_EXPR] = ansi_opname[(int) PLUS_EXPR];
        !           511:   ansi_assopname[(int) CONVERT_EXPR] = ansi_assopname[(int) PLUS_EXPR];
        !           512:   ansi_opname[(int) LSHIFT_EXPR] = get_identifier ("__ls");
        !           513:   IDENTIFIER_OPNAME_P (ansi_opname[(int) LSHIFT_EXPR]) = 1;
        !           514:   ansi_assopname[(int) LSHIFT_EXPR] = get_identifier ("__als");
        !           515:   IDENTIFIER_OPNAME_P (ansi_assopname[(int) LSHIFT_EXPR]) = 1;
        !           516:   ansi_opname[(int) EQ_EXPR] = get_identifier ("__eq");
        !           517:   IDENTIFIER_OPNAME_P (ansi_opname[(int) EQ_EXPR]) = 1;
        !           518:   ansi_opname[(int) LT_EXPR] = get_identifier ("__lt");
        !           519:   IDENTIFIER_OPNAME_P (ansi_opname[(int) LT_EXPR]) = 1;
        !           520:   ansi_opname[(int) LE_EXPR] = get_identifier ("__le");
        !           521:   IDENTIFIER_OPNAME_P (ansi_opname[(int) LE_EXPR]) = 1;
        !           522:   ansi_opname[(int) BIT_AND_EXPR] = get_identifier ("__ad");
        !           523:   IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_AND_EXPR]) = 1;
        !           524:   ansi_assopname[(int) BIT_AND_EXPR] = get_identifier ("__aad");
        !           525:   IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_AND_EXPR]) = 1;
        !           526:   ansi_opname[(int) ADDR_EXPR] = ansi_opname[(int) BIT_AND_EXPR];
        !           527:   ansi_assopname[(int) ADDR_EXPR] = ansi_assopname[(int) BIT_AND_EXPR];
        !           528:   ansi_opname[(int) BIT_XOR_EXPR] = get_identifier ("__er");
        !           529:   IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_XOR_EXPR]) = 1;
        !           530:   ansi_assopname[(int) BIT_XOR_EXPR] = get_identifier ("__aer");
        !           531:   IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_XOR_EXPR]) = 1;
        !           532:   ansi_opname[(int) TRUTH_ORIF_EXPR] = get_identifier ("__oo");
        !           533:   IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_ORIF_EXPR]) = 1;
        !           534:   ansi_opname[(int) BIT_NOT_EXPR] = get_identifier ("__co");
        !           535:   IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_NOT_EXPR]) = 1;
        !           536:   ansi_opname[(int) PREDECREMENT_EXPR] = get_identifier ("__mm");
        !           537:   IDENTIFIER_OPNAME_P (ansi_opname[(int) PREDECREMENT_EXPR]) = 1;
        !           538:   ansi_opname[(int) POSTDECREMENT_EXPR] = ansi_opname[(int) PREDECREMENT_EXPR];
        !           539:   ansi_opname[(int) COMPONENT_REF] = get_identifier ("__rf");
        !           540:   IDENTIFIER_OPNAME_P (ansi_opname[(int) COMPONENT_REF]) = 1;
        !           541:   ansi_opname[(int) MEMBER_REF] = get_identifier ("__rm");
        !           542:   IDENTIFIER_OPNAME_P (ansi_opname[(int) MEMBER_REF]) = 1;
        !           543:   ansi_opname[(int) CALL_EXPR] = get_identifier ("__cl");
        !           544:   IDENTIFIER_OPNAME_P (ansi_opname[(int) CALL_EXPR]) = 1;
        !           545:   ansi_opname[(int) ARRAY_REF] = get_identifier ("__vc");
        !           546:   IDENTIFIER_OPNAME_P (ansi_opname[(int) ARRAY_REF]) = 1;
        !           547:   ansi_opname[(int) NEW_EXPR] = get_identifier ("__nw");
        !           548:   IDENTIFIER_OPNAME_P (ansi_opname[(int) NEW_EXPR]) = 1;
        !           549:   ansi_opname[(int) DELETE_EXPR] = get_identifier ("__dl");
        !           550:   IDENTIFIER_OPNAME_P (ansi_opname[(int) DELETE_EXPR]) = 1;
        !           551:   ansi_opname[(int) VEC_NEW_EXPR] = get_identifier ("__vn");
        !           552:   IDENTIFIER_OPNAME_P (ansi_opname[(int) VEC_NEW_EXPR]) = 1;
        !           553:   ansi_opname[(int) VEC_DELETE_EXPR] = get_identifier ("__vd");
        !           554:   IDENTIFIER_OPNAME_P (ansi_opname[(int) VEC_DELETE_EXPR]) = 1;
        !           555:   ansi_opname[(int) TYPE_EXPR] = get_identifier ("__op");
        !           556:   IDENTIFIER_OPNAME_P (ansi_opname[(int) TYPE_EXPR]) = 1;
        !           557: 
        !           558:   /* This is not true: these operators are not defined in ANSI,
        !           559:      but we need them anyway.  */
        !           560:   ansi_opname[(int) MIN_EXPR] = get_identifier ("__mn");
        !           561:   IDENTIFIER_OPNAME_P (ansi_opname[(int) MIN_EXPR]) = 1;
        !           562:   ansi_opname[(int) MAX_EXPR] = get_identifier ("__mx");
        !           563:   IDENTIFIER_OPNAME_P (ansi_opname[(int) MAX_EXPR]) = 1;
        !           564:   ansi_opname[(int) COND_EXPR] = get_identifier ("__cn");
        !           565:   IDENTIFIER_OPNAME_P (ansi_opname[(int) COND_EXPR]) = 1;
        !           566:   ansi_opname[(int) METHOD_CALL_EXPR] = get_identifier ("__wr");
        !           567:   IDENTIFIER_OPNAME_P (ansi_opname[(int) METHOD_CALL_EXPR]) = 1;
        !           568: 
        !           569:   init_method ();
        !           570:   init_error ();
        !           571:   gcc_obstack_init (&inline_text_obstack);
        !           572:   inline_text_firstobj = (char *) obstack_alloc (&inline_text_obstack, 0);
        !           573:   gcc_obstack_init (&synth_obstack);
        !           574:   synth_firstobj = (char *) obstack_alloc (&synth_obstack, 0);
        !           575: 
        !           576:   /* Start it at 0, because check_newline is called at the very beginning
        !           577:      and will increment it to 1.  */
        !           578:   lineno = 0;
        !           579:   input_filename = "<internal>";
        !           580:   current_function_decl = NULL;
        !           581: 
        !           582:   maxtoken = 40;
        !           583:   token_buffer = (char *) xmalloc (maxtoken + 2);
        !           584: 
        !           585:   ridpointers[(int) RID_INT] = get_identifier ("int");
        !           586:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_INT],
        !           587:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]));
        !           588:   ridpointers[(int) RID_BOOL] = get_identifier ("bool");
        !           589:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_BOOL],
        !           590:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_BOOL]));
        !           591:   ridpointers[(int) RID_CHAR] = get_identifier ("char");
        !           592:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_CHAR],
        !           593:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]));
        !           594:   ridpointers[(int) RID_VOID] = get_identifier ("void");
        !           595:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VOID],
        !           596:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]));
        !           597:   ridpointers[(int) RID_FLOAT] = get_identifier ("float");
        !           598:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_FLOAT],
        !           599:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_FLOAT]));
        !           600:   ridpointers[(int) RID_DOUBLE] = get_identifier ("double");
        !           601:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_DOUBLE],
        !           602:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_DOUBLE]));
        !           603:   ridpointers[(int) RID_SHORT] = get_identifier ("short");
        !           604:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_SHORT],
        !           605:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_SHORT]));
        !           606:   ridpointers[(int) RID_LONG] = get_identifier ("long");
        !           607:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_LONG],
        !           608:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]));
        !           609:   ridpointers[(int) RID_UNSIGNED] = get_identifier ("unsigned");
        !           610:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_UNSIGNED],
        !           611:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_UNSIGNED]));
        !           612:   ridpointers[(int) RID_SIGNED] = get_identifier ("signed");
        !           613:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_SIGNED],
        !           614:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_SIGNED]));
        !           615:   ridpointers[(int) RID_INLINE] = get_identifier ("inline");
        !           616:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_INLINE],
        !           617:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_INLINE]));
        !           618:   ridpointers[(int) RID_CONST] = get_identifier ("const");
        !           619:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_CONST],
        !           620:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_CONST]));
        !           621:   ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile");
        !           622:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VOLATILE],
        !           623:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_VOLATILE]));
        !           624:   ridpointers[(int) RID_AUTO] = get_identifier ("auto");
        !           625:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_AUTO],
        !           626:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_AUTO]));
        !           627:   ridpointers[(int) RID_STATIC] = get_identifier ("static");
        !           628:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_STATIC],
        !           629:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]));
        !           630:   ridpointers[(int) RID_EXTERN] = get_identifier ("extern");
        !           631:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_EXTERN],
        !           632:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]));
        !           633:   ridpointers[(int) RID_TYPEDEF] = get_identifier ("typedef");
        !           634:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_TYPEDEF],
        !           635:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_TYPEDEF]));
        !           636:   ridpointers[(int) RID_REGISTER] = get_identifier ("register");
        !           637:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_REGISTER],
        !           638:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_REGISTER]));
        !           639: 
        !           640:   /* C++ extensions. These are probably not correctly named. */
        !           641:   ridpointers[(int) RID_WCHAR] = get_identifier ("__wchar_t");
        !           642:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_WCHAR],
        !           643:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_WCHAR]));
        !           644:   class_type_node = build_int_2 (class_type, 0);
        !           645:   TREE_TYPE (class_type_node) = class_type_node;
        !           646:   ridpointers[(int) RID_CLASS] = class_type_node;
        !           647: 
        !           648:   record_type_node = build_int_2 (record_type, 0);
        !           649:   TREE_TYPE (record_type_node) = record_type_node;
        !           650:   ridpointers[(int) RID_RECORD] = record_type_node;
        !           651: 
        !           652:   union_type_node = build_int_2 (union_type, 0);
        !           653:   TREE_TYPE (union_type_node) = union_type_node;
        !           654:   ridpointers[(int) RID_UNION] = union_type_node;
        !           655: 
        !           656:   enum_type_node = build_int_2 (enum_type, 0);
        !           657:   TREE_TYPE (enum_type_node) = enum_type_node;
        !           658:   ridpointers[(int) RID_ENUM] = enum_type_node;
        !           659: 
        !           660:   ridpointers[(int) RID_VIRTUAL] = get_identifier ("virtual");
        !           661:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VIRTUAL],
        !           662:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_VIRTUAL]));
        !           663:   ridpointers[(int) RID_FRIEND] = get_identifier ("friend");
        !           664:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_FRIEND],
        !           665:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_FRIEND]));
        !           666: 
        !           667:   ridpointers[(int) RID_PUBLIC] = get_identifier ("public");
        !           668:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PUBLIC],
        !           669:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_PUBLIC]));
        !           670:   ridpointers[(int) RID_PRIVATE] = get_identifier ("private");
        !           671:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PRIVATE],
        !           672:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_PRIVATE]));
        !           673:   ridpointers[(int) RID_PROTECTED] = get_identifier ("protected");
        !           674:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PROTECTED],
        !           675:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_PROTECTED]));
        !           676:   ridpointers[(int) RID_TEMPLATE] = get_identifier ("template");
        !           677:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_TEMPLATE],
        !           678:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_TEMPLATE]));
        !           679:   /* This is for ANSI C++. */
        !           680:   ridpointers[(int) RID_MUTABLE] = get_identifier ("mutable");
        !           681:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_MUTABLE],
        !           682:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_MUTABLE]));
        !           683: 
        !           684:   /* Exception handling extensions.  */
        !           685:   exception_type_node = build_int_2 (exception_type, 0);
        !           686:   TREE_TYPE (exception_type_node) = exception_type_node;
        !           687:   ridpointers[(int) RID_EXCEPTION] = exception_type_node;
        !           688: 
        !           689:   /* Signature handling extensions.  */
        !           690:   signature_type_node = build_int_2 (signature_type, 0);
        !           691:   TREE_TYPE (signature_type_node) = signature_type_node;
        !           692:   ridpointers[(int) RID_SIGNATURE] = signature_type_node;
        !           693: 
        !           694:   opname_tab[(int) COMPONENT_REF] = "->";
        !           695:   opname_tab[(int) MEMBER_REF] = "->*";
        !           696:   opname_tab[(int) METHOD_CALL_EXPR] = "->()";
        !           697:   opname_tab[(int) INDIRECT_REF] = "(unary *)";
        !           698:   opname_tab[(int) ARRAY_REF] = "[]";
        !           699:   opname_tab[(int) MODIFY_EXPR] = "=";
        !           700:   opname_tab[(int) NEW_EXPR] = "new";
        !           701:   opname_tab[(int) DELETE_EXPR] = "delete";
        !           702:   opname_tab[(int) VEC_NEW_EXPR] = "new []";
        !           703:   opname_tab[(int) VEC_DELETE_EXPR] = "delete []";
        !           704:   opname_tab[(int) COND_EXPR] = "... ? ... : ...";
        !           705:   opname_tab[(int) CALL_EXPR] = "()";
        !           706:   opname_tab[(int) PLUS_EXPR] = "+";
        !           707:   opname_tab[(int) MINUS_EXPR] = "-";
        !           708:   opname_tab[(int) MULT_EXPR] = "*";
        !           709:   opname_tab[(int) TRUNC_DIV_EXPR] = "/";
        !           710:   opname_tab[(int) CEIL_DIV_EXPR] = "(ceiling /)";
        !           711:   opname_tab[(int) FLOOR_DIV_EXPR] = "(floor /)";
        !           712:   opname_tab[(int) ROUND_DIV_EXPR] = "(round /)";
        !           713:   opname_tab[(int) TRUNC_MOD_EXPR] = "%";
        !           714:   opname_tab[(int) CEIL_MOD_EXPR] = "(ceiling %)";
        !           715:   opname_tab[(int) FLOOR_MOD_EXPR] = "(floor %)";
        !           716:   opname_tab[(int) ROUND_MOD_EXPR] = "(round %)";
        !           717:   opname_tab[(int) NEGATE_EXPR] = "-";
        !           718:   opname_tab[(int) MIN_EXPR] = "<?";
        !           719:   opname_tab[(int) MAX_EXPR] = ">?";
        !           720:   opname_tab[(int) ABS_EXPR] = "abs";
        !           721:   opname_tab[(int) FFS_EXPR] = "ffs";
        !           722:   opname_tab[(int) LSHIFT_EXPR] = "<<";
        !           723:   opname_tab[(int) RSHIFT_EXPR] = ">>";
        !           724:   opname_tab[(int) BIT_IOR_EXPR] = "|";
        !           725:   opname_tab[(int) BIT_XOR_EXPR] = "^";
        !           726:   opname_tab[(int) BIT_AND_EXPR] = "&";
        !           727:   opname_tab[(int) BIT_ANDTC_EXPR] = "&~";
        !           728:   opname_tab[(int) BIT_NOT_EXPR] = "~";
        !           729:   opname_tab[(int) TRUTH_ANDIF_EXPR] = "&&";
        !           730:   opname_tab[(int) TRUTH_ORIF_EXPR] = "||";
        !           731:   opname_tab[(int) TRUTH_AND_EXPR] = "strict &&";
        !           732:   opname_tab[(int) TRUTH_OR_EXPR] = "strict ||";
        !           733:   opname_tab[(int) TRUTH_NOT_EXPR] = "!";
        !           734:   opname_tab[(int) LT_EXPR] = "<";
        !           735:   opname_tab[(int) LE_EXPR] = "<=";
        !           736:   opname_tab[(int) GT_EXPR] = ">";
        !           737:   opname_tab[(int) GE_EXPR] = ">=";
        !           738:   opname_tab[(int) EQ_EXPR] = "==";
        !           739:   opname_tab[(int) NE_EXPR] = "!=";
        !           740:   opname_tab[(int) IN_EXPR] = "in";
        !           741:   opname_tab[(int) RANGE_EXPR] = "..";
        !           742:   opname_tab[(int) CONVERT_EXPR] = "(unary +)";
        !           743:   opname_tab[(int) ADDR_EXPR] = "(unary &)";
        !           744:   opname_tab[(int) PREDECREMENT_EXPR] = "--";
        !           745:   opname_tab[(int) PREINCREMENT_EXPR] = "++";
        !           746:   opname_tab[(int) POSTDECREMENT_EXPR] = "--";
        !           747:   opname_tab[(int) POSTINCREMENT_EXPR] = "++";
        !           748:   opname_tab[(int) COMPOUND_EXPR] = ",";
        !           749: 
        !           750:   assignop_tab[(int) NOP_EXPR] = "=";
        !           751:   assignop_tab[(int) PLUS_EXPR] =  "+=";
        !           752:   assignop_tab[(int) CONVERT_EXPR] =  "+=";
        !           753:   assignop_tab[(int) MINUS_EXPR] = "-=";
        !           754:   assignop_tab[(int) NEGATE_EXPR] = "-=";
        !           755:   assignop_tab[(int) MULT_EXPR] = "*=";
        !           756:   assignop_tab[(int) INDIRECT_REF] = "*=";
        !           757:   assignop_tab[(int) TRUNC_DIV_EXPR] = "/=";
        !           758:   assignop_tab[(int) EXACT_DIV_EXPR] = "(exact /=)";
        !           759:   assignop_tab[(int) CEIL_DIV_EXPR] = "(ceiling /=)";
        !           760:   assignop_tab[(int) FLOOR_DIV_EXPR] = "(floor /=)";
        !           761:   assignop_tab[(int) ROUND_DIV_EXPR] = "(round /=)";
        !           762:   assignop_tab[(int) TRUNC_MOD_EXPR] = "%=";
        !           763:   assignop_tab[(int) CEIL_MOD_EXPR] = "(ceiling %=)";
        !           764:   assignop_tab[(int) FLOOR_MOD_EXPR] = "(floor %=)";
        !           765:   assignop_tab[(int) ROUND_MOD_EXPR] = "(round %=)";
        !           766:   assignop_tab[(int) MIN_EXPR] = "<?=";
        !           767:   assignop_tab[(int) MAX_EXPR] = ">?=";
        !           768:   assignop_tab[(int) LSHIFT_EXPR] = "<<=";
        !           769:   assignop_tab[(int) RSHIFT_EXPR] = ">>=";
        !           770:   assignop_tab[(int) BIT_IOR_EXPR] = "|=";
        !           771:   assignop_tab[(int) BIT_XOR_EXPR] = "^=";
        !           772:   assignop_tab[(int) BIT_AND_EXPR] = "&=";
        !           773:   assignop_tab[(int) ADDR_EXPR] = "&=";
        !           774: 
        !           775:   init_filename_times ();
        !           776: 
        !           777:   /* Some options inhibit certain reserved words.
        !           778:      Clear those words out of the hash table so they won't be recognized.  */
        !           779: #define UNSET_RESERVED_WORD(STRING) \
        !           780:   do { struct resword *s = is_reserved_word (STRING, sizeof (STRING) - 1); \
        !           781:        if (s) s->name = ""; } while (0)
        !           782: 
        !           783: #if 0
        !           784:   /* let's parse things, and if they use it, then give them an error.  */
        !           785:   if (!flag_handle_exceptions)
        !           786:     {
        !           787:       UNSET_RESERVED_WORD ("throw");
        !           788:       UNSET_RESERVED_WORD ("try");
        !           789:       UNSET_RESERVED_WORD ("catch");
        !           790:     }
        !           791: #endif
        !           792: 
        !           793:   if (! (flag_gc || flag_dossier))
        !           794:     {
        !           795:       UNSET_RESERVED_WORD ("classof");
        !           796:       UNSET_RESERVED_WORD ("headof");
        !           797:     }
        !           798:   if (! flag_handle_signatures)
        !           799:     {
        !           800:       /* Easiest way to not recognize signature
        !           801:         handling extensions...  */
        !           802:       UNSET_RESERVED_WORD ("signature");
        !           803:       UNSET_RESERVED_WORD ("sigof");
        !           804:     }
        !           805:   if (flag_no_asm)
        !           806:     UNSET_RESERVED_WORD ("asm");
        !           807:   if (flag_no_asm || flag_traditional)
        !           808:     UNSET_RESERVED_WORD ("typeof");
        !           809: 
        !           810:   token_count = init_parse ();
        !           811:   interface_unknown = 1;
        !           812: }
        !           813: 
        !           814: void
        !           815: reinit_parse_for_function ()
        !           816: {
        !           817:   current_base_init_list = NULL_TREE;
        !           818:   current_member_init_list = NULL_TREE;
        !           819: }
        !           820: 
        !           821: #ifdef __GNUC__
        !           822: __inline
        !           823: #endif
        !           824: void
        !           825: yyprint (file, yychar, yylval)
        !           826:      FILE *file;
        !           827:      int yychar;
        !           828:      YYSTYPE yylval;
        !           829: {
        !           830:   tree t;
        !           831:   switch (yychar)
        !           832:     {
        !           833:     case IDENTIFIER:
        !           834:     case TYPENAME:
        !           835:     case TYPESPEC:
        !           836:     case PTYPENAME:
        !           837:     case IDENTIFIER_DEFN:
        !           838:     case TYPENAME_DEFN:
        !           839:     case PTYPENAME_DEFN:
        !           840:     case TYPENAME_ELLIPSIS:
        !           841:     case SCSPEC:
        !           842:     case PRE_PARSED_CLASS_DECL:
        !           843:       t = yylval.ttype;
        !           844:       my_friendly_assert (TREE_CODE (t) == IDENTIFIER_NODE, 224);
        !           845:       if (IDENTIFIER_POINTER (t))
        !           846:          fprintf (file, " `%s'", IDENTIFIER_POINTER (t));
        !           847:       break;
        !           848:     case AGGR:
        !           849:       if (yylval.ttype == class_type_node)
        !           850:        fprintf (file, " `class'");
        !           851:       else if (yylval.ttype == record_type_node)
        !           852:        fprintf (file, " `struct'");
        !           853:       else if (yylval.ttype == union_type_node)
        !           854:        fprintf (file, " `union'");
        !           855:       else if (yylval.ttype == enum_type_node)
        !           856:        fprintf (file, " `enum'");
        !           857:       else if (yylval.ttype == signature_type_node)
        !           858:        fprintf (file, " `signature'");
        !           859:       else
        !           860:        my_friendly_abort (80);
        !           861:       break;
        !           862:     }
        !           863: }
        !           864: 
        !           865: static int *reduce_count;
        !           866: int *token_count;
        !           867: 
        !           868: #define REDUCE_LENGTH (sizeof (yyr2) / sizeof (yyr2[0]))
        !           869: #define TOKEN_LENGTH (256 + sizeof (yytname) / sizeof (yytname[0]))
        !           870: 
        !           871: int *
        !           872: init_parse ()
        !           873: {
        !           874: #ifdef GATHER_STATISTICS
        !           875:   reduce_count = (int *)malloc (sizeof (int) * (REDUCE_LENGTH + 1));
        !           876:   bzero (reduce_count, sizeof (int) * (REDUCE_LENGTH + 1));
        !           877:   reduce_count += 1;
        !           878:   token_count = (int *)malloc (sizeof (int) * (TOKEN_LENGTH + 1));
        !           879:   bzero (token_count, sizeof (int) * (TOKEN_LENGTH + 1));
        !           880:   token_count += 1;
        !           881: #endif
        !           882:   return token_count;
        !           883: }
        !           884: 
        !           885: #ifdef GATHER_STATISTICS
        !           886: void
        !           887: yyhook (yyn)
        !           888:      int yyn;
        !           889: {
        !           890:   reduce_count[yyn] += 1;
        !           891: }
        !           892: 
        !           893: static int
        !           894: reduce_cmp (p, q)
        !           895:      int *p, *q;
        !           896: {
        !           897:   return reduce_count[*q] - reduce_count[*p];
        !           898: }
        !           899: 
        !           900: static int
        !           901: token_cmp (p, q)
        !           902:      int *p, *q;
        !           903: {
        !           904:   return token_count[*q] - token_count[*p];
        !           905: }
        !           906: #endif
        !           907: 
        !           908: void
        !           909: print_parse_statistics ()
        !           910: {
        !           911: #ifdef GATHER_STATISTICS
        !           912: #if YYDEBUG != 0
        !           913:   int i;
        !           914:   int maxlen = REDUCE_LENGTH;
        !           915:   unsigned *sorted;
        !           916:   
        !           917:   if (reduce_count[-1] == 0)
        !           918:     return;
        !           919: 
        !           920:   if (TOKEN_LENGTH > REDUCE_LENGTH)
        !           921:     maxlen = TOKEN_LENGTH;
        !           922:   sorted = (unsigned *) alloca (sizeof (int) * maxlen);
        !           923: 
        !           924:   for (i = 0; i < TOKEN_LENGTH; i++)
        !           925:     sorted[i] = i;
        !           926:   qsort (sorted, TOKEN_LENGTH, sizeof (int), token_cmp);
        !           927:   for (i = 0; i < TOKEN_LENGTH; i++)
        !           928:     {
        !           929:       int index = sorted[i];
        !           930:       if (token_count[index] == 0)
        !           931:        break;
        !           932:       if (token_count[index] < token_count[-1])
        !           933:        break;
        !           934:       fprintf (stderr, "token %d, `%s', count = %d\n",
        !           935:               index, yytname[YYTRANSLATE (index)], token_count[index]);
        !           936:     }
        !           937:   fprintf (stderr, "\n");
        !           938:   for (i = 0; i < REDUCE_LENGTH; i++)
        !           939:     sorted[i] = i;
        !           940:   qsort (sorted, REDUCE_LENGTH, sizeof (int), reduce_cmp);
        !           941:   for (i = 0; i < REDUCE_LENGTH; i++)
        !           942:     {
        !           943:       int index = sorted[i];
        !           944:       if (reduce_count[index] == 0)
        !           945:        break;
        !           946:       if (reduce_count[index] < reduce_count[-1])
        !           947:        break;
        !           948:       fprintf (stderr, "rule %d, line %d, count = %d\n",
        !           949:               index, yyrline[index], reduce_count[index]);
        !           950:     }
        !           951:   fprintf (stderr, "\n");
        !           952: #endif
        !           953: #endif
        !           954: }
        !           955: 
        !           956: /* Sets the value of the 'yydebug' variable to VALUE.
        !           957:    This is a function so we don't have to have YYDEBUG defined
        !           958:    in order to build the compiler.  */
        !           959: void
        !           960: set_yydebug (value)
        !           961:      int value;
        !           962: {
        !           963: #if YYDEBUG != 0
        !           964:   extern int yydebug;
        !           965:   yydebug = value;
        !           966: #else
        !           967:   warning ("YYDEBUG not defined.");
        !           968: #endif
        !           969: }
        !           970: 
        !           971: 
        !           972: /* Functions and data structures for #pragma interface.
        !           973: 
        !           974:    `#pragma implementation' means that the main file being compiled
        !           975:    is considered to implement (provide) the classes that appear in
        !           976:    its main body.  I.e., if this is file "foo.cc", and class `bar'
        !           977:    is defined in "foo.cc", then we say that "foo.cc implements bar".
        !           978: 
        !           979:    All main input files "implement" themselves automagically.
        !           980: 
        !           981:    `#pragma interface' means that unless this file (of the form "foo.h"
        !           982:    is not presently being included by file "foo.cc", the
        !           983:    CLASSTYPE_INTERFACE_ONLY bit gets set.  The effect is that none
        !           984:    of the vtables nor any of the inline functions defined in foo.h
        !           985:    will ever be output.
        !           986: 
        !           987:    There are cases when we want to link files such as "defs.h" and
        !           988:    "main.cc".  In this case, we give "defs.h" a `#pragma interface',
        !           989:    and "main.cc" has `#pragma implementation "defs.h"'.  */
        !           990: 
        !           991: struct impl_files
        !           992: {
        !           993:   char *filename;
        !           994:   struct impl_files *next;
        !           995: };
        !           996: 
        !           997: static struct impl_files *impl_file_chain;
        !           998: 
        !           999: /* Helper function to load global variables with interface
        !          1000:    information.  */
        !          1001: void
        !          1002: extract_interface_info ()
        !          1003: {
        !          1004:   tree fileinfo = 0;
        !          1005: 
        !          1006:   if (flag_alt_external_templates)
        !          1007:     {
        !          1008:       struct tinst_level *til = tinst_for_decl ();
        !          1009:   
        !          1010:       if (til)
        !          1011:        fileinfo = get_time_identifier (til->file);
        !          1012:     }
        !          1013:   if (!fileinfo)
        !          1014:     fileinfo = get_time_identifier (input_filename);
        !          1015:   fileinfo = IDENTIFIER_CLASS_VALUE (fileinfo);
        !          1016:   interface_only = TREE_INT_CST_LOW (fileinfo);
        !          1017:   if (!processing_template_defn || flag_external_templates)
        !          1018:     interface_unknown = TREE_INT_CST_HIGH (fileinfo);
        !          1019: }
        !          1020: 
        !          1021: /* Return nonzero if S is not considered part of an
        !          1022:    INTERFACE/IMPLEMENTATION pair.  Otherwise, return 0.  */
        !          1023: static int
        !          1024: interface_strcmp (s)
        !          1025:      char *s;
        !          1026: {
        !          1027:   /* Set the interface/implementation bits for this scope.  */
        !          1028:   struct impl_files *ifiles;
        !          1029:   char *s1;
        !          1030: 
        !          1031:   for (ifiles = impl_file_chain; ifiles; ifiles = ifiles->next)
        !          1032:     {
        !          1033:       char *t1 = ifiles->filename;
        !          1034:       s1 = s;
        !          1035: 
        !          1036:       if (*s1 != *t1 || *s1 == 0)
        !          1037:        continue;
        !          1038: 
        !          1039:       while (*s1 == *t1 && *s1 != 0)
        !          1040:        s1++, t1++;
        !          1041: 
        !          1042:       /* A match.  */
        !          1043:       if (*s1 == *t1)
        !          1044:        return 0;
        !          1045: 
        !          1046:       /* Don't get faked out by xxx.yyy.cc vs xxx.zzz.cc.  */
        !          1047:       if (index (s1, '.') || index (t1, '.'))
        !          1048:        continue;
        !          1049: 
        !          1050:       if (*s1 == '\0' || s1[-1] != '.' || t1[-1] != '.')
        !          1051:        continue;
        !          1052: 
        !          1053:       /* A match.  */
        !          1054:       return 0;
        !          1055:     }
        !          1056: 
        !          1057:   /* No matches.  */
        !          1058:   return 1;
        !          1059: }
        !          1060: 
        !          1061: void
        !          1062: set_typedecl_interface_info (prev, vars)
        !          1063:      tree prev, vars;
        !          1064: {
        !          1065:   tree id = get_time_identifier (DECL_SOURCE_FILE (vars));
        !          1066:   tree fileinfo = IDENTIFIER_CLASS_VALUE (id);
        !          1067:   tree type = TREE_TYPE (vars);
        !          1068: 
        !          1069:   CLASSTYPE_INTERFACE_ONLY (type) = TREE_INT_CST_LOW (fileinfo)
        !          1070:     = interface_strcmp (FILE_NAME_NONDIRECTORY (DECL_SOURCE_FILE (vars)));
        !          1071: }
        !          1072: 
        !          1073: void
        !          1074: set_vardecl_interface_info (prev, vars)
        !          1075:      tree prev, vars;
        !          1076: {
        !          1077:   tree type = DECL_CONTEXT (vars);
        !          1078: 
        !          1079:   if (CLASSTYPE_INTERFACE_KNOWN (type))
        !          1080:     {
        !          1081:       if (CLASSTYPE_INTERFACE_ONLY (type))
        !          1082:        set_typedecl_interface_info (prev, TYPE_NAME (type));
        !          1083:       else
        !          1084:        CLASSTYPE_VTABLE_NEEDS_WRITING (type) = 1;
        !          1085:       DECL_EXTERNAL (vars) = CLASSTYPE_INTERFACE_ONLY (type);
        !          1086:       TREE_PUBLIC (vars) = 1;
        !          1087:     }
        !          1088: }
        !          1089: 
        !          1090: /* Called from the top level: if there are any pending inlines to
        !          1091:    do, set up to process them now.  This function sets up the first function
        !          1092:    to be parsed; after it has been, the rule for fndef in parse.y will
        !          1093:    call process_next_inline to start working on the next one.  */
        !          1094: void
        !          1095: do_pending_inlines ()
        !          1096: {
        !          1097:   struct pending_inline *t;
        !          1098: 
        !          1099:   /* Oops, we're still dealing with the last batch.  */
        !          1100:   if (yychar == PRE_PARSED_FUNCTION_DECL)
        !          1101:     return;
        !          1102: 
        !          1103:   /* Reverse the pending inline functions, since
        !          1104:      they were cons'd instead of appended.  */
        !          1105:   {
        !          1106:     struct pending_inline *prev = 0, *tail, *bottom = 0;
        !          1107:     t = pending_inlines;
        !          1108:     pending_inlines = 0;
        !          1109: 
        !          1110:     for (; t; t = tail)
        !          1111:       {
        !          1112:        tail = t->next;
        !          1113:        t->next = prev;
        !          1114:        t->deja_vu = 1;
        !          1115:        prev = t;
        !          1116:       }
        !          1117: 
        !          1118:     /* This kludge should go away when synthesized methods are handled
        !          1119:        properly, i.e. only when needed.  */
        !          1120:     for (t = prev; t; t = t->next)
        !          1121:       {
        !          1122:        if (t->lineno <= 0)
        !          1123:          {
        !          1124:            tree f = t->fndecl;
        !          1125:            DECL_PENDING_INLINE_INFO (f) = 0;
        !          1126:            interface_unknown = t->interface == 1;
        !          1127:            interface_only = t->interface == 0;
        !          1128:            switch (- t->lineno)
        !          1129:              {
        !          1130:              case 0: case 1:
        !          1131:                build_dtor (f); break;
        !          1132:              case 2:
        !          1133:                build_default_constructor (f); break;
        !          1134:              case 3: case 4:
        !          1135:                build_copy_constructor (f); break;
        !          1136:              case 5: case 6:
        !          1137:                build_assign_ref (f); break;
        !          1138:              default:
        !          1139:                ;
        !          1140:              }
        !          1141:            if (tail)
        !          1142:              tail->next = t->next;
        !          1143:            else
        !          1144:              prev = t->next;
        !          1145:            if (! bottom)
        !          1146:              bottom = t;
        !          1147:          }
        !          1148:        else
        !          1149:          tail = t;
        !          1150:       }
        !          1151:     if (bottom)
        !          1152:       {
        !          1153:        obstack_free (&synth_obstack, bottom);
        !          1154:        extract_interface_info ();
        !          1155:       }
        !          1156:     t = prev;
        !          1157:   }
        !          1158: 
        !          1159:   if (t == 0)
        !          1160:     return;
        !          1161:            
        !          1162:   /* Now start processing the first inline function.  */
        !          1163:   my_friendly_assert ((t->parm_vec == NULL_TREE) == (t->bindings == NULL_TREE),
        !          1164:                      226);
        !          1165:   if (t->parm_vec)
        !          1166:     push_template_decls (t->parm_vec, t->bindings, 0);
        !          1167:   if (t->len > 0)
        !          1168:     {
        !          1169:       feed_input (t->buf, t->len, t->can_free ? &inline_text_obstack : 0);
        !          1170:       lineno = t->lineno;
        !          1171: #if 0
        !          1172:       if (input_filename != t->filename)
        !          1173:        {
        !          1174:          input_filename = t->filename;
        !          1175:          /* Get interface/implementation back in sync.  */
        !          1176:          extract_interface_info ();
        !          1177:        }
        !          1178: #else
        !          1179:       input_filename = t->filename;
        !          1180:       interface_unknown = t->interface == 1;
        !          1181:       interface_only = t->interface == 0;
        !          1182: #endif
        !          1183:       yychar = PRE_PARSED_FUNCTION_DECL;
        !          1184:     }
        !          1185:   /* Pass back a handle on the rest of the inline functions, so that they
        !          1186:      can be processed later.  */
        !          1187:   yylval.ttype = build_tree_list ((tree) t, t->fndecl);
        !          1188: #if 0
        !          1189:   if (flag_default_inline && t->fndecl
        !          1190:       /* If we're working from a template, don't change
        !          1191:         the `inline' state.  */
        !          1192:       && t->parm_vec == NULL_TREE)
        !          1193:     DECL_INLINE (t->fndecl) = 1;
        !          1194: #endif
        !          1195:   DECL_PENDING_INLINE_INFO (t->fndecl) = 0;
        !          1196: }
        !          1197: 
        !          1198: extern struct pending_input *to_be_restored;
        !          1199: static int nextchar = -1;
        !          1200: 
        !          1201: /* Called from the fndecl rule in the parser when the function just parsed
        !          1202:    was declared using a PRE_PARSED_FUNCTION_DECL (i.e. came from
        !          1203:    do_pending_inlines).  */
        !          1204: void
        !          1205: process_next_inline (t)
        !          1206:      tree t;
        !          1207: {
        !          1208:   struct pending_inline *i = (struct pending_inline *) TREE_PURPOSE (t);
        !          1209:   my_friendly_assert ((i->parm_vec == NULL_TREE) == (i->bindings == NULL_TREE),
        !          1210:                      227);
        !          1211:   if (i->parm_vec)
        !          1212:     pop_template_decls (i->parm_vec, i->bindings, 0);
        !          1213:   i = i->next;
        !          1214:   if (yychar == YYEMPTY)
        !          1215:     yychar = yylex ();
        !          1216:   if (yychar != END_OF_SAVED_INPUT)
        !          1217:     {
        !          1218:       error ("parse error at end of saved function text");
        !          1219:       /* restore_pending_input will abort unless yychar is either
        !          1220:        * END_OF_SAVED_INPUT or YYEMPTY; since we already know we're
        !          1221:        * hosed, feed back YYEMPTY.
        !          1222:        *  We also need to discard nextchar, since that may have gotten
        !          1223:        * set as well.
        !          1224:        */
        !          1225:       nextchar = -1;
        !          1226:     }
        !          1227:   yychar = YYEMPTY;
        !          1228:   if (to_be_restored == 0)
        !          1229:     my_friendly_abort (123);
        !          1230:   restore_pending_input (to_be_restored);
        !          1231:   to_be_restored = 0;
        !          1232:   if (i && i->fndecl != NULL_TREE)
        !          1233:     {
        !          1234:       my_friendly_assert ((i->parm_vec == NULL_TREE) == (i->bindings == NULL_TREE),
        !          1235:                          228);
        !          1236:       if (i->parm_vec)
        !          1237:        push_template_decls (i->parm_vec, i->bindings, 0);
        !          1238:       feed_input (i->buf, i->len, i->can_free ? &inline_text_obstack : 0);
        !          1239:       lineno = i->lineno;
        !          1240:       input_filename = i->filename;
        !          1241:       yychar = PRE_PARSED_FUNCTION_DECL;
        !          1242:       yylval.ttype = build_tree_list ((tree) i, i->fndecl);
        !          1243: #if 0
        !          1244:       if (flag_default_inline
        !          1245:          /* If we're working from a template, don't change
        !          1246:             the `inline' state.  */
        !          1247:          && i->parm_vec == NULL_TREE)
        !          1248:        DECL_INLINE (i->fndecl) = 1;
        !          1249: #endif
        !          1250:       DECL_PENDING_INLINE_INFO (i->fndecl) = 0;
        !          1251:     }
        !          1252:   if (i)
        !          1253:     {
        !          1254:       interface_unknown = i->interface == 1;
        !          1255:       interface_only = i->interface == 0;
        !          1256:     }
        !          1257:   else
        !          1258:     extract_interface_info ();
        !          1259: }
        !          1260: 
        !          1261: /* Since inline methods can refer to text which has not yet been seen,
        !          1262:    we store the text of the method in a structure which is placed in the
        !          1263:    DECL_PENDING_INLINE_INFO field of the FUNCTION_DECL.
        !          1264:    After parsing the body of the class definition, the FUNCTION_DECL's are
        !          1265:    scanned to see which ones have this field set.  Those are then digested
        !          1266:    one at a time.
        !          1267: 
        !          1268:    This function's FUNCTION_DECL will have a bit set in its common so
        !          1269:    that we know to watch out for it.  */
        !          1270: 
        !          1271: static void
        !          1272: consume_string (this_obstack, matching_char)
        !          1273:      register struct obstack *this_obstack;
        !          1274:      int matching_char;
        !          1275: {
        !          1276:   register int c;
        !          1277:   int starting_lineno = lineno;
        !          1278:   do
        !          1279:     {
        !          1280:       c = getch ();
        !          1281:       if (c == EOF)
        !          1282:        {
        !          1283:          int save_lineno = lineno;
        !          1284:          lineno = starting_lineno;
        !          1285:          if (matching_char == '"')
        !          1286:            error ("end of file encountered inside string constant");
        !          1287:          else
        !          1288:            error ("end of file encountered inside character constant");
        !          1289:          lineno = save_lineno;
        !          1290:          return;
        !          1291:        }
        !          1292:       if (c == '\\')
        !          1293:        {
        !          1294:          obstack_1grow (this_obstack, c);
        !          1295:          c = getch ();
        !          1296:          obstack_1grow (this_obstack, c);
        !          1297: 
        !          1298:          /* Make sure we continue the loop */
        !          1299:          c = 0;
        !          1300:          continue;
        !          1301:        }
        !          1302:       if (c == '\n')
        !          1303:        {
        !          1304:          if (pedantic)
        !          1305:            pedwarn ("ANSI C++ forbids newline in string constant");
        !          1306:          lineno++;
        !          1307:        }
        !          1308:       obstack_1grow (this_obstack, c);
        !          1309:     }
        !          1310:   while (c != matching_char);
        !          1311: }
        !          1312: 
        !          1313: static int nextyychar = YYEMPTY;
        !          1314: static YYSTYPE nextyylval;
        !          1315: 
        !          1316: struct pending_input {
        !          1317:   int nextchar, yychar, nextyychar, eof;
        !          1318:   YYSTYPE yylval, nextyylval;
        !          1319:   struct obstack token_obstack;
        !          1320:   int first_token;
        !          1321: };
        !          1322: 
        !          1323: struct pending_input *
        !          1324: save_pending_input ()
        !          1325: {
        !          1326:   struct pending_input *p;
        !          1327:   p = (struct pending_input *) xmalloc (sizeof (struct pending_input));
        !          1328:   p->nextchar = nextchar;
        !          1329:   p->yychar = yychar;
        !          1330:   p->nextyychar = nextyychar;
        !          1331:   p->yylval = yylval;
        !          1332:   p->nextyylval = nextyylval;
        !          1333:   p->eof = end_of_file;
        !          1334:   yychar = nextyychar = YYEMPTY;
        !          1335:   nextchar = -1;
        !          1336:   p->first_token = first_token;
        !          1337:   p->token_obstack = token_obstack;
        !          1338: 
        !          1339:   first_token = 0;
        !          1340:   gcc_obstack_init (&token_obstack);
        !          1341:   end_of_file = 0;
        !          1342:   return p;
        !          1343: }
        !          1344: 
        !          1345: void
        !          1346: restore_pending_input (p)
        !          1347:      struct pending_input *p;
        !          1348: {
        !          1349:   my_friendly_assert (nextchar == -1, 229);
        !          1350:   nextchar = p->nextchar;
        !          1351:   my_friendly_assert (yychar == YYEMPTY || yychar == END_OF_SAVED_INPUT, 230);
        !          1352:   yychar = p->yychar;
        !          1353:   my_friendly_assert (nextyychar == YYEMPTY, 231);
        !          1354:   nextyychar = p->nextyychar;
        !          1355:   yylval = p->yylval;
        !          1356:   nextyylval = p->nextyylval;
        !          1357:   first_token = p->first_token;
        !          1358:   obstack_free (&token_obstack, (char *) 0);
        !          1359:   token_obstack = p->token_obstack;
        !          1360:   end_of_file = p->eof;
        !          1361:   free (p);
        !          1362: }
        !          1363: 
        !          1364: /* Return next non-whitespace input character, which may come
        !          1365:    from `finput', or from `nextchar'.  */
        !          1366: static int
        !          1367: yynextch ()
        !          1368: {
        !          1369:   int c;
        !          1370: 
        !          1371:   if (nextchar >= 0)
        !          1372:     {
        !          1373:       c = nextchar;
        !          1374:       nextchar = -1;
        !          1375:     }
        !          1376:   else c = getch ();
        !          1377:   return skip_white_space (c);
        !          1378: }
        !          1379: 
        !          1380: /* Unget character CH from the input stream.
        !          1381:    If RESCAN is non-zero, then we want to `see' this
        !          1382:    character as the next input token.  */
        !          1383: void
        !          1384: yyungetc (ch, rescan)
        !          1385:      int ch;
        !          1386:      int rescan;
        !          1387: {
        !          1388:   /* Unget a character from the input stream.  */
        !          1389:   if (yychar == YYEMPTY || rescan == 0)
        !          1390:     {
        !          1391:       if (nextchar >= 0)
        !          1392:        put_back (nextchar);
        !          1393:       nextchar = ch;
        !          1394:     }
        !          1395:   else
        !          1396:     {
        !          1397:       my_friendly_assert (nextyychar == YYEMPTY, 232);
        !          1398:       nextyychar = yychar;
        !          1399:       nextyylval = yylval;
        !          1400:       yychar = ch;
        !          1401:     }
        !          1402: }
        !          1403: 
        !          1404: /* This function stores away the text for an inline function that should
        !          1405:    be processed later.  It decides how much later, and may need to move
        !          1406:    the info between obstacks; therefore, the caller should not refer to
        !          1407:    the T parameter after calling this function.
        !          1408: 
        !          1409:    This function also stores the list of template-parameter bindings that
        !          1410:    will be needed for expanding the template, if any.  */
        !          1411: 
        !          1412: static void
        !          1413: store_pending_inline (decl, t)
        !          1414:      tree decl;
        !          1415:      struct pending_inline *t;
        !          1416: {
        !          1417:   extern int processing_template_defn;
        !          1418:   int delay_to_eof = 0;
        !          1419:   struct pending_inline **inlines;
        !          1420: 
        !          1421:   t->fndecl = decl;
        !          1422:   /* Default: compile right away, and no extra bindings are needed.  */
        !          1423:   t->parm_vec = t->bindings = 0;
        !          1424:   if (processing_template_defn)
        !          1425:     {
        !          1426:       tree type = current_class_type;
        !          1427:       /* Assumption: In this (possibly) nested class sequence, only
        !          1428:         one name will have template parms.  */
        !          1429:       while (type && TREE_CODE_CLASS (TREE_CODE (type)) == 't')
        !          1430:        {
        !          1431:          tree decl = TYPE_NAME (type);
        !          1432:          tree tmpl = IDENTIFIER_TEMPLATE (DECL_NAME (decl));
        !          1433:          if (tmpl)
        !          1434:            {
        !          1435:              t->parm_vec = DECL_TEMPLATE_INFO (TREE_PURPOSE (tmpl))->parm_vec;
        !          1436:              t->bindings = TREE_VALUE (tmpl);
        !          1437:            }
        !          1438:          type = DECL_CONTEXT (decl);
        !          1439:        }
        !          1440:       if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
        !          1441:          || TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE)
        !          1442:        {
        !          1443:          if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
        !          1444:            my_friendly_assert (TYPE_MAX_VALUE (TREE_TYPE (decl)) == current_class_type,
        !          1445:                                233);
        !          1446: 
        !          1447:          /* Inline functions can be compiled immediately.  Other functions
        !          1448:             will be output separately, so if we're in interface-only mode,
        !          1449:             punt them now, or output them now if we're doing implementations
        !          1450:             and we know no overrides will exist.  Otherwise, we delay until
        !          1451:             end-of-file, to see if the definition is really required.  */
        !          1452:          if (DECL_INLINE (decl))
        !          1453:            /* delay_to_eof == 0 */;
        !          1454:          else if (current_class_type && !interface_unknown)
        !          1455:            {
        !          1456:              if (interface_only)
        !          1457:                {
        !          1458: #if 0
        !          1459:                  print_node_brief (stderr, "\ndiscarding text for ", decl, 0);
        !          1460: #endif
        !          1461:                  if (t->can_free)
        !          1462:                    obstack_free (&inline_text_obstack, t->buf);
        !          1463:                  DECL_PENDING_INLINE_INFO (decl) = 0;
        !          1464:                  return;
        !          1465:                }
        !          1466:            }
        !          1467:          /* Don't delay the processing of virtual functions.  */
        !          1468:          else if (DECL_VINDEX (decl) == NULL_TREE)
        !          1469:            delay_to_eof = 1;
        !          1470:        }
        !          1471:       else
        !          1472:        my_friendly_abort (58);
        !          1473:     }
        !          1474: 
        !          1475:   if (delay_to_eof)
        !          1476:     {
        !          1477:       extern struct pending_inline *pending_template_expansions;
        !          1478: 
        !          1479:       if (t->can_free)
        !          1480:        {
        !          1481:          char *free_to = t->buf;
        !          1482:          t->buf = (char *) obstack_copy (&permanent_obstack, t->buf,
        !          1483:                                          t->len + 1);
        !          1484:          t = (struct pending_inline *) obstack_copy (&permanent_obstack, 
        !          1485:                                                      (char *)t, sizeof (*t));
        !          1486:          obstack_free (&inline_text_obstack, free_to);
        !          1487:        }
        !          1488:       inlines = &pending_template_expansions;
        !          1489:       t->can_free = 0;
        !          1490:     }
        !          1491:   else
        !          1492:     {
        !          1493:       inlines = &pending_inlines;
        !          1494:       DECL_PENDING_INLINE_INFO (decl) = t;
        !          1495:     }
        !          1496: 
        !          1497:   /* Because we use obstacks, we must process these in precise order.  */
        !          1498:   t->next = *inlines;
        !          1499:   *inlines = t;
        !          1500: }
        !          1501: 
        !          1502: void reinit_parse_for_block ();
        !          1503: 
        !          1504: void
        !          1505: reinit_parse_for_method (yychar, decl)
        !          1506:      int yychar;
        !          1507:      tree decl;
        !          1508: {
        !          1509:   int len;
        !          1510:   int starting_lineno = lineno;
        !          1511:   char *starting_filename = input_filename;
        !          1512: 
        !          1513:   reinit_parse_for_block (yychar, &inline_text_obstack, 0);
        !          1514: 
        !          1515:   len = obstack_object_size (&inline_text_obstack);
        !          1516:   current_base_init_list = NULL_TREE;
        !          1517:   current_member_init_list = NULL_TREE;
        !          1518:   if (decl == void_type_node
        !          1519:       || (current_class_type && TYPE_REDEFINED (current_class_type)))
        !          1520:     {
        !          1521:       /* Happens when we get two declarations of the same
        !          1522:         function in the same scope.  */
        !          1523:       char *buf = obstack_finish (&inline_text_obstack);
        !          1524:       obstack_free (&inline_text_obstack, buf);
        !          1525:       return;
        !          1526:     }
        !          1527:   else
        !          1528:     {
        !          1529:       struct pending_inline *t;
        !          1530:       char *buf = obstack_finish (&inline_text_obstack);
        !          1531: 
        !          1532:       t = (struct pending_inline *) obstack_alloc (&inline_text_obstack,
        !          1533:                                                   sizeof (struct pending_inline));
        !          1534:       t->lineno = starting_lineno;
        !          1535:       t->filename = starting_filename;
        !          1536:       t->token = YYEMPTY;
        !          1537:       t->token_value = 0;
        !          1538:       t->buf = buf;
        !          1539:       t->len = len;
        !          1540:       t->can_free = 1;
        !          1541:       t->deja_vu = 0;
        !          1542:       if (interface_unknown && processing_template_defn && flag_external_templates && ! DECL_IN_SYSTEM_HEADER (decl))
        !          1543:        warn_if_unknown_interface ();
        !          1544:       t->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2));
        !          1545:       store_pending_inline (decl, t);
        !          1546:     }
        !          1547: }
        !          1548: 
        !          1549: /* Consume a block -- actually, a method or template definition beginning
        !          1550:    with `:' or `{' -- and save it away on the specified obstack.
        !          1551: 
        !          1552:    Argument IS_TEMPLATE indicates which set of error messages should be
        !          1553:    output if something goes wrong.  This should really be cleaned up somehow,
        !          1554:    without loss of clarity.  */
        !          1555: void
        !          1556: reinit_parse_for_block (yychar, obstackp, is_template)
        !          1557:      int yychar;
        !          1558:      struct obstack *obstackp;
        !          1559:      int is_template;
        !          1560: {
        !          1561:   register int c = 0;
        !          1562:   int blev = 1;
        !          1563:   int starting_lineno = lineno;
        !          1564:   char *starting_filename = input_filename;
        !          1565:   int len;
        !          1566:   int look_for_semicolon = 0;
        !          1567:   int look_for_lbrac = 0;
        !          1568: 
        !          1569:   if (yychar == '{')
        !          1570:     obstack_1grow (obstackp, '{');
        !          1571:   else if (yychar == '=')
        !          1572:     look_for_semicolon = 1;
        !          1573:   else if (yychar != ':' && (yychar != RETURN || is_template))
        !          1574:     {
        !          1575:       yyerror (is_template
        !          1576:               ? "parse error in template specification"
        !          1577:               : "parse error in method specification");
        !          1578:       obstack_1grow (obstackp, '{');
        !          1579:     }
        !          1580:   else
        !          1581:     {
        !          1582:       obstack_1grow (obstackp, yychar);
        !          1583:       look_for_lbrac = 1;
        !          1584:       blev = 0;
        !          1585:     }
        !          1586: 
        !          1587:   if (nextchar != EOF)
        !          1588:     {
        !          1589:       c = nextchar;
        !          1590:       nextchar = EOF;
        !          1591:     }
        !          1592:   else
        !          1593:     c = getch ();
        !          1594:   
        !          1595:   while (c != EOF)
        !          1596:     {
        !          1597:       int this_lineno = lineno;
        !          1598: 
        !          1599:       c = skip_white_space (c);
        !          1600: 
        !          1601:       /* Don't lose our cool if there are lots of comments.  */
        !          1602:       if (lineno == this_lineno + 1)
        !          1603:        obstack_1grow (obstackp, '\n');
        !          1604:       else if (lineno == this_lineno)
        !          1605:        ;
        !          1606:       else if (lineno - this_lineno < 10)
        !          1607:        {
        !          1608:          int i;
        !          1609:          for (i = lineno - this_lineno; i > 0; i--)
        !          1610:            obstack_1grow (obstackp, '\n');
        !          1611:        }
        !          1612:       else
        !          1613:        {
        !          1614:          char buf[16];
        !          1615:          sprintf (buf, "\n# %d \"", lineno);
        !          1616:          len = strlen (buf);
        !          1617:          obstack_grow (obstackp, buf, len);
        !          1618: 
        !          1619:          len = strlen (input_filename);
        !          1620:          obstack_grow (obstackp, input_filename, len);
        !          1621:          obstack_1grow (obstackp, '\"');
        !          1622:          obstack_1grow (obstackp, '\n');
        !          1623:        }
        !          1624: 
        !          1625:       while (c > ' ')          /* ASCII dependent...  */
        !          1626:        {
        !          1627:          obstack_1grow (obstackp, c);
        !          1628:          if (c == '{')
        !          1629:            {
        !          1630:              look_for_lbrac = 0;
        !          1631:              blev++;
        !          1632:            }
        !          1633:          else if (c == '}')
        !          1634:            {
        !          1635:              blev--;
        !          1636:              if (blev == 0 && !look_for_semicolon)
        !          1637:                goto done;
        !          1638:            }
        !          1639:          else if (c == '\\')
        !          1640:            {
        !          1641:              /* Don't act on the next character...e.g, doing an escaped
        !          1642:                 double-quote.  */
        !          1643:              c = getch ();
        !          1644:              if (c == EOF)
        !          1645:                {
        !          1646:                  error_with_file_and_line (starting_filename,
        !          1647:                                            starting_lineno,
        !          1648:                                            "end of file read inside definition");
        !          1649:                  goto done;
        !          1650:                }
        !          1651:              obstack_1grow (obstackp, c);
        !          1652:            }
        !          1653:          else if (c == '\"')
        !          1654:            consume_string (obstackp, c);
        !          1655:          else if (c == '\'')
        !          1656:            consume_string (obstackp, c);
        !          1657:          else if (c == ';')
        !          1658:            {
        !          1659:              if (look_for_lbrac)
        !          1660:                {
        !          1661:                  error (is_template
        !          1662:                         ? "template body missing"
        !          1663:                         : "function body for constructor missing");
        !          1664:                  obstack_1grow (obstackp, '{');
        !          1665:                  obstack_1grow (obstackp, '}');
        !          1666:                  len += 2;
        !          1667:                  goto done;
        !          1668:                }
        !          1669:              else if (look_for_semicolon && blev == 0)
        !          1670:                goto done;
        !          1671:            }
        !          1672:          c = getch ();
        !          1673:        }
        !          1674: 
        !          1675:       if (c == EOF)
        !          1676:        {
        !          1677:          error_with_file_and_line (starting_filename,
        !          1678:                                    starting_lineno,
        !          1679:                                    "end of file read inside definition");
        !          1680:          goto done;
        !          1681:        }
        !          1682:       else if (c != '\n')
        !          1683:        {
        !          1684:          obstack_1grow (obstackp, c);
        !          1685:          c = getch ();
        !          1686:        }
        !          1687:     }
        !          1688:  done:
        !          1689:   obstack_1grow (obstackp, '\0');
        !          1690: }
        !          1691: 
        !          1692: /* Build a default function named NAME for type TYPE.
        !          1693:    KIND says what to build.
        !          1694: 
        !          1695:    When KIND == 0, build default destructor.
        !          1696:    When KIND == 1, build virtual destructor.
        !          1697:    When KIND == 2, build default constructor.
        !          1698:    When KIND == 3, build default X(const X&) constructor.
        !          1699:    When KIND == 4, build default X(X&) constructor.
        !          1700:    When KIND == 5, build default operator = (const X&).
        !          1701:    When KIND == 6, build default operator = (X&).  */
        !          1702: 
        !          1703: tree
        !          1704: cons_up_default_function (type, name, kind)
        !          1705:      tree type, name;
        !          1706:      int kind;
        !          1707: {
        !          1708:   extern tree void_list_node;
        !          1709:   char *func_buf = NULL;
        !          1710:   int func_len = 0;
        !          1711:   tree declspecs = NULL_TREE;
        !          1712:   tree fn, args;
        !          1713:   tree argtype;
        !          1714:   int retref = 0;
        !          1715: 
        !          1716:   name = constructor_name (name);
        !          1717:   switch (kind)
        !          1718:     {
        !          1719:       /* Destructors.  */
        !          1720:     case 1:
        !          1721:       declspecs = build_decl_list (NULL_TREE, ridpointers [(int) RID_VIRTUAL]);
        !          1722:       /* Fall through...  */
        !          1723:     case 0:
        !          1724:       name = build_parse_node (BIT_NOT_EXPR, name);
        !          1725:       /* Fall through...  */
        !          1726:     case 2:
        !          1727:       /* Default constructor.  */
        !          1728:       args = void_list_node;
        !          1729:       break;
        !          1730: 
        !          1731:     case 3:
        !          1732:       type = build_type_variant (type, 1, 0);
        !          1733:       /* Fall through...  */
        !          1734:     case 4:
        !          1735:       /* According to ARM $12.8, the default copy ctor will be declared, but
        !          1736:         not defined, unless it's needed.  */
        !          1737:       argtype = build_reference_type (type);
        !          1738:       args = tree_cons (NULL_TREE,
        !          1739:                        build_tree_list (hash_tree_chain (argtype, NULL_TREE),
        !          1740:                                         get_identifier ("_ctor_arg")),
        !          1741:                        void_list_node);
        !          1742:       break;
        !          1743: 
        !          1744:     case 5:
        !          1745:       type = build_type_variant (type, 1, 0);
        !          1746:       /* Fall through...  */
        !          1747:     case 6:
        !          1748:       retref = 1;
        !          1749:       declspecs = build_decl_list (NULL_TREE, name);
        !          1750: 
        !          1751:       name = ansi_opname [(int) MODIFY_EXPR];
        !          1752: 
        !          1753:       argtype = build_reference_type (type);
        !          1754:       args = tree_cons (NULL_TREE,
        !          1755:                        build_tree_list (hash_tree_chain (argtype, NULL_TREE),
        !          1756:                                         get_identifier ("_ctor_arg")),
        !          1757:                        void_list_node);
        !          1758:       break;
        !          1759: 
        !          1760:     default:
        !          1761:       my_friendly_abort (59);
        !          1762:     }
        !          1763: 
        !          1764:   declspecs = decl_tree_cons (NULL_TREE, ridpointers [(int) RID_INLINE],
        !          1765:                              declspecs);
        !          1766: 
        !          1767:   TREE_PARMLIST (args) = 1;
        !          1768: 
        !          1769:   {
        !          1770:     tree declarator = build_parse_node (CALL_EXPR, name, args, NULL_TREE);
        !          1771:     if (retref)
        !          1772:       declarator = build_parse_node (ADDR_EXPR, declarator);
        !          1773:     
        !          1774:     fn = grokfield (declarator, declspecs, NULL_TREE, NULL_TREE, NULL_TREE);
        !          1775:   }
        !          1776:   
        !          1777:   if (fn == void_type_node)
        !          1778:     return fn;
        !          1779: 
        !          1780:   if (CLASSTYPE_TEMPLATE_INSTANTIATION (type))
        !          1781:     SET_DECL_IMPLICIT_INSTANTIATION (fn);
        !          1782: 
        !          1783:   /* This kludge should go away when synthesized methods are handled
        !          1784:      properly, i.e. only when needed.  */
        !          1785:   {
        !          1786:     struct pending_inline *t;
        !          1787:     t = (struct pending_inline *)
        !          1788:       obstack_alloc (&synth_obstack, sizeof (struct pending_inline));
        !          1789:     t->lineno = -kind;
        !          1790:     t->can_free = 0;
        !          1791:     t->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2));
        !          1792:     store_pending_inline (fn, t);
        !          1793:   }
        !          1794: 
        !          1795: #ifdef DEBUG_DEFAULT_FUNCTIONS
        !          1796:   { char *fn_type = NULL;
        !          1797:     tree t = name;
        !          1798:     switch (kind)
        !          1799:       {
        !          1800:       case 0: fn_type = "default destructor"; break;
        !          1801:       case 1: fn_type = "virtual destructor"; break;
        !          1802:       case 2: fn_type = "default constructor"; break;
        !          1803:       case 3: fn_type = "default X(const X&)"; break;
        !          1804:       case 4: fn_type = "default X(X&)"; break;
        !          1805:       }
        !          1806:     if (fn_type)
        !          1807:       {
        !          1808:        if (TREE_CODE (name) == BIT_NOT_EXPR)
        !          1809:          t = TREE_OPERAND (name, 0);
        !          1810:        fprintf (stderr, "[[[[ %s for %s:\n%s]]]]\n", fn_type,
        !          1811:                 IDENTIFIER_POINTER (t), func_buf);
        !          1812:       }
        !          1813:   }
        !          1814: #endif /* DEBUG_DEFAULT_FUNCTIONS */
        !          1815: 
        !          1816:   /* Show that this function was generated by the compiler.  */
        !          1817:   SET_DECL_ARTIFICIAL (fn);
        !          1818:   
        !          1819:   return fn;
        !          1820: }
        !          1821: 
        !          1822: #if 0
        !          1823: /* Used by default_copy_constructor_body.  For the anonymous union
        !          1824:    in TYPE, return the member that is at least as large as the rest
        !          1825:    of the members, so we can copy it.  */
        !          1826: static tree
        !          1827: largest_union_member (type)
        !          1828:      tree type;
        !          1829: {
        !          1830:   tree f, type_size = TYPE_SIZE (type);
        !          1831: 
        !          1832:   for (f = TYPE_FIELDS (type); f; f = TREE_CHAIN (f))
        !          1833:     if (simple_cst_equal (DECL_SIZE (f), type_size))
        !          1834:       return f;
        !          1835: 
        !          1836:   /* We should always find one.  */
        !          1837:   my_friendly_abort (323);
        !          1838:   return NULL_TREE;
        !          1839: }
        !          1840: 
        !          1841: /* Construct the body of a default assignment operator.
        !          1842:    Mostly copied directly from default_copy_constructor_body.  */
        !          1843: static void
        !          1844: default_assign_ref_body (bufp, lenp, type, fields)
        !          1845:      char **bufp;
        !          1846:      int *lenp;
        !          1847:      tree type, fields;
        !          1848: {
        !          1849:   static struct obstack body;
        !          1850:   static int inited = FALSE;
        !          1851:   int n_bases = CLASSTYPE_N_BASECLASSES (type);
        !          1852:   char *tbuf;
        !          1853:   int tgot, tneed;
        !          1854: 
        !          1855:   if (!inited)
        !          1856:     {
        !          1857:       obstack_init (&body);
        !          1858:       inited = TRUE;
        !          1859:     }
        !          1860:   body.next_free = body.object_base;
        !          1861: 
        !          1862:   obstack_1grow (&body, '{');
        !          1863: 
        !          1864:   /* Small buffer for sprintf().  */
        !          1865: 
        !          1866:   tgot = 100;
        !          1867:   tbuf = (char *) alloca (tgot);
        !          1868: 
        !          1869:   /* If we don't need a real op=, just do a bitwise copy.  */
        !          1870:   if (! TYPE_HAS_COMPLEX_ASSIGN_REF (type))
        !          1871:     {
        !          1872:       tbuf = "{__builtin_memcpy(this,&_ctor_arg,sizeof(_ctor_arg));return *this;}";
        !          1873:       *lenp = strlen (tbuf);
        !          1874:       *bufp = obstack_alloc (&inline_text_obstack, *lenp + 1);
        !          1875:       strcpy (*bufp, tbuf);
        !          1876:       return;
        !          1877:     }
        !          1878: 
        !          1879:   if (TREE_CODE (type) == UNION_TYPE)
        !          1880:     {
        !          1881:       if (fields)
        !          1882:        {
        !          1883:          tree main = fields;
        !          1884:          char * s;
        !          1885:          tree f;
        !          1886: 
        !          1887:          for (f = TREE_CHAIN (fields); f; f = TREE_CHAIN (f))
        !          1888:            if (tree_int_cst_lt (TYPE_SIZE (TREE_TYPE (main)),
        !          1889:                                 TYPE_SIZE (TREE_TYPE (f))))
        !          1890:              main = f;
        !          1891: 
        !          1892:          s = IDENTIFIER_POINTER (DECL_NAME (main));
        !          1893: 
        !          1894:          tneed = (2 * strlen (s)) + 28;
        !          1895:          if (tgot < tneed)
        !          1896:            {
        !          1897:              tgot = tneed;
        !          1898:              tbuf = (char *) alloca (tgot);
        !          1899:            }
        !          1900: 
        !          1901:          sprintf (tbuf, "{%s=_ctor_arg.%s;return *this;}", s, s);
        !          1902:        }
        !          1903:       else
        !          1904:        tbuf = "{}";
        !          1905:       
        !          1906:       *lenp = strlen (tbuf);
        !          1907:       *bufp = obstack_alloc (&inline_text_obstack, *lenp + 1);
        !          1908:       strcpy (*bufp, tbuf);
        !          1909:       return;
        !          1910:     }
        !          1911: 
        !          1912:   /* Construct base classes...
        !          1913:      FIXME: Does not deal with multiple inheritance and virtual bases
        !          1914:      correctly.  See g++.old-deja/g++.jason/opeq5.C for a testcase.
        !          1915:      We need to do wacky things if everything between us and the virtual
        !          1916:      base (by all paths) has a "complex" op=.  */
        !          1917: 
        !          1918:   if (n_bases)
        !          1919:     {
        !          1920:       tree bases = TYPE_BINFO_BASETYPES (type);
        !          1921:       int i = 0;
        !          1922: 
        !          1923:       for (i = 0; i < n_bases; i++)
        !          1924:        {
        !          1925:          tree binfo = TREE_VEC_ELT (bases, i);
        !          1926:          tree btype, name;
        !          1927:          char *s;
        !          1928: 
        !          1929:          btype = BINFO_TYPE (binfo);
        !          1930:          name = TYPE_NESTED_NAME (btype);
        !          1931:          s = IDENTIFIER_POINTER (name);
        !          1932: 
        !          1933:          tneed = (2 * strlen (s)) + 42;
        !          1934:          if (tgot < tneed)
        !          1935:            {
        !          1936:              tgot = tneed;
        !          1937:              tbuf = (char *) alloca (tgot);
        !          1938:            }
        !          1939: 
        !          1940:          sprintf (tbuf, "%s::operator=((%s%s ::%s&)_ctor_arg);", s,
        !          1941:                   TYPE_READONLY (type) ? "const " : "",
        !          1942:                   CLASSTYPE_DECLARED_CLASS (btype) ? "class" : "struct",
        !          1943:                   s);
        !          1944:          obstack_grow (&body, tbuf, strlen (tbuf));
        !          1945:        }
        !          1946:     }
        !          1947: 
        !          1948:   /* Construct fields.  */
        !          1949: 
        !          1950:   if (fields)
        !          1951:     {
        !          1952:       tree f;
        !          1953: 
        !          1954:       for (f = fields; f; f = TREE_CHAIN (f))
        !          1955:        {
        !          1956:          if (TREE_CODE (f) == FIELD_DECL && ! DECL_VIRTUAL_P (f))
        !          1957:            {
        !          1958:              char *s;
        !          1959:              tree x;
        !          1960:              tree t = TREE_TYPE (f);
        !          1961: 
        !          1962:              if (DECL_NAME (f))
        !          1963:                x = f;
        !          1964:              else if (t != NULL_TREE
        !          1965:                       && TREE_CODE (t) == UNION_TYPE
        !          1966:                       && ((TREE_CODE (TYPE_NAME (t)) == IDENTIFIER_NODE
        !          1967:                            && ANON_AGGRNAME_P (TYPE_NAME (t)))
        !          1968:                           || (TREE_CODE (TYPE_NAME (t)) == TYPE_DECL
        !          1969:                               && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))))
        !          1970:                       && TYPE_FIELDS (t) != NULL_TREE)
        !          1971:                x = largest_union_member (t);
        !          1972:              else
        !          1973:                continue;
        !          1974: 
        !          1975:              s = IDENTIFIER_POINTER (DECL_NAME (x));
        !          1976:              tneed = (2 * strlen (s)) + 13;
        !          1977:              if (tgot < tneed)
        !          1978:                {
        !          1979:                  tgot = tneed;
        !          1980:                  tbuf = (char *) alloca (tgot);
        !          1981:                }
        !          1982: 
        !          1983:              sprintf (tbuf, "%s=_ctor_arg.%s;", s, s);
        !          1984:              obstack_grow (&body, tbuf, strlen (tbuf));
        !          1985:            }
        !          1986:        }
        !          1987:     }
        !          1988: 
        !          1989:   obstack_grow (&body, "return *this;}", 15);
        !          1990: 
        !          1991:   *lenp = obstack_object_size (&body) - 1;
        !          1992:   *bufp = obstack_alloc (&inline_text_obstack, *lenp);
        !          1993: 
        !          1994:   strcpy (*bufp, body.object_base);
        !          1995: }
        !          1996: 
        !          1997: /* Construct the body of a default copy constructor.  */
        !          1998: static void
        !          1999: default_copy_constructor_body (bufp, lenp, type, fields)
        !          2000:      char **bufp;
        !          2001:      int *lenp;
        !          2002:      tree type, fields;
        !          2003: {
        !          2004:   static struct obstack prologue;
        !          2005:   static int inited = FALSE;
        !          2006:   int n_bases = CLASSTYPE_N_BASECLASSES (type);
        !          2007:   char sep = ':';
        !          2008:   char *tbuf;
        !          2009:   int tgot, tneed;
        !          2010: 
        !          2011:   /* Create a buffer to call base class constructors and construct members
        !          2012:      (fields).  */
        !          2013: 
        !          2014:   if (!inited)
        !          2015:     {
        !          2016:       obstack_init (&prologue);
        !          2017:       inited = TRUE;
        !          2018:     }
        !          2019:   prologue.next_free = prologue.object_base;
        !          2020: 
        !          2021:   /* If we don't need a real copy ctor, just do a bitwise copy.  */
        !          2022:   if (! TYPE_HAS_COMPLEX_INIT_REF (type))
        !          2023:     {
        !          2024:       tbuf = "{__builtin_memcpy(this,&_ctor_arg,sizeof(_ctor_arg));}";
        !          2025:       *lenp = strlen (tbuf);
        !          2026:       *bufp = obstack_alloc (&inline_text_obstack, *lenp + 1);
        !          2027:       strcpy (*bufp, tbuf);
        !          2028:       return;
        !          2029:     }
        !          2030: 
        !          2031:   /* Small buffer for sprintf().  */
        !          2032: 
        !          2033:   tgot = 100;
        !          2034:   tbuf = (char *) alloca (tgot);
        !          2035: 
        !          2036:   if (TREE_CODE (type) == UNION_TYPE)
        !          2037:     {
        !          2038:       if (fields)
        !          2039:        {
        !          2040:          tree main = fields;
        !          2041:          char * s;
        !          2042:          tree f;
        !          2043: 
        !          2044:          for (f = TREE_CHAIN (fields); f; f = TREE_CHAIN (f))
        !          2045:            if (tree_int_cst_lt (TYPE_SIZE (TREE_TYPE (main)),
        !          2046:                                 TYPE_SIZE (TREE_TYPE (f))))
        !          2047:              main = f;
        !          2048: 
        !          2049:          s = IDENTIFIER_POINTER (DECL_NAME (main));
        !          2050:          tneed = (2 * strlen (s)) + 16;
        !          2051:          if (tgot < tneed)
        !          2052:            {
        !          2053:              tgot = tneed;
        !          2054:              tbuf = (char *) alloca (tgot);
        !          2055:            }
        !          2056: 
        !          2057:          sprintf (tbuf, ":%s(_ctor_arg.%s){}", s, s);
        !          2058:        }
        !          2059:       else
        !          2060:        tbuf = "{}";
        !          2061: 
        !          2062:       *lenp = strlen (tbuf);
        !          2063:       *bufp = obstack_alloc (&inline_text_obstack, *lenp + 1);
        !          2064:       strcpy (*bufp, tbuf);
        !          2065:       return;
        !          2066:     }
        !          2067: 
        !          2068:   /* Construct base classes... */
        !          2069: 
        !          2070:   if (n_bases)
        !          2071:     {
        !          2072:       /* Note that CLASSTYPE_VBASECLASSES isn't set yet... */
        !          2073:       tree v = get_vbase_types (type);
        !          2074:       tree bases = TYPE_BINFO_BASETYPES (type);
        !          2075:       int i = 0;
        !          2076: 
        !          2077:       for (;;)
        !          2078:        {
        !          2079:          tree binfo, btype, name;
        !          2080:          char *s;
        !          2081: 
        !          2082:          if (v)
        !          2083:            {
        !          2084:              binfo = v;
        !          2085:              v = TREE_CHAIN (v);
        !          2086:            }
        !          2087:          else if (i < n_bases)
        !          2088:            {
        !          2089:              binfo = TREE_VEC_ELT (bases, i++);
        !          2090:              if (TREE_VIA_VIRTUAL (binfo))
        !          2091:                continue;
        !          2092:            }
        !          2093:          else
        !          2094:            break;
        !          2095: 
        !          2096:          btype = BINFO_TYPE (binfo);
        !          2097:          name = TYPE_NESTED_NAME (btype);
        !          2098:          s = IDENTIFIER_POINTER (name);
        !          2099: 
        !          2100:          tneed = (2 * strlen (s)) + 39;
        !          2101:          if (tgot < tneed)
        !          2102:            {
        !          2103:              tgot = tneed;
        !          2104:              tbuf = (char *) alloca (tgot);
        !          2105:            }
        !          2106: 
        !          2107:          sprintf (tbuf, "%c%s((%s%s ::%s&)_ctor_arg)", sep, s,
        !          2108:                   TYPE_READONLY (type) ? "const " : "",
        !          2109:                   CLASSTYPE_DECLARED_CLASS (btype) ? "class" : "struct",
        !          2110:                   s);
        !          2111:          sep = ',';
        !          2112:          obstack_grow (&prologue, tbuf, strlen (tbuf));
        !          2113:        }
        !          2114:     }
        !          2115: 
        !          2116:   /* Construct fields.  */
        !          2117: 
        !          2118:   if (fields)
        !          2119:     {
        !          2120:       tree f;
        !          2121: 
        !          2122:       for (f = fields; f; f = TREE_CHAIN (f))
        !          2123:        {
        !          2124:          if (TREE_CODE (f) == FIELD_DECL && ! DECL_VIRTUAL_P (f))
        !          2125:            {
        !          2126:              char *s;
        !          2127:              tree x;
        !          2128:              tree t = TREE_TYPE (f);
        !          2129: 
        !          2130:              if (DECL_NAME (f))
        !          2131:                x = f;
        !          2132:              else if (t != NULL_TREE
        !          2133:                       && TREE_CODE (t) == UNION_TYPE
        !          2134:                       && ((TREE_CODE (TYPE_NAME (t)) == IDENTIFIER_NODE
        !          2135:                            && ANON_AGGRNAME_P (TYPE_NAME (t)))
        !          2136:                           || (TREE_CODE (TYPE_NAME (t)) == TYPE_DECL
        !          2137:                               && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))))
        !          2138:                       && TYPE_FIELDS (t) != NULL_TREE)
        !          2139:                x = largest_union_member (t);
        !          2140:              else
        !          2141:                continue;
        !          2142: 
        !          2143:              s = IDENTIFIER_POINTER (DECL_NAME (x));
        !          2144:              tneed = (2 * strlen (s)) + 30;
        !          2145:              if (tgot < tneed)
        !          2146:                {
        !          2147:                  tgot = tneed;
        !          2148:                  tbuf = (char *) alloca (tgot);
        !          2149:                }
        !          2150: 
        !          2151:              sprintf (tbuf, "%c%s(_ctor_arg.%s)", sep, s, s);
        !          2152:              sep = ',';
        !          2153:              obstack_grow (&prologue, tbuf, strlen (tbuf));
        !          2154:            }
        !          2155:        }
        !          2156:     }
        !          2157: 
        !          2158:   /* Concatenate constructor body to prologue.  */
        !          2159: 
        !          2160:   *lenp = obstack_object_size (&prologue) + 2;
        !          2161:   *bufp = obstack_alloc (&inline_text_obstack, *lenp + 1);
        !          2162: 
        !          2163:   obstack_1grow (&prologue, '\0');
        !          2164: 
        !          2165:   strcpy (*bufp, prologue.object_base);
        !          2166:   strcat (*bufp, "{}");
        !          2167: }
        !          2168: #endif
        !          2169: 
        !          2170: /* Heuristic to tell whether the user is missing a semicolon
        !          2171:    after a struct or enum declaration.  Emit an error message
        !          2172:    if we know the user has blown it.  */
        !          2173: void
        !          2174: check_for_missing_semicolon (type)
        !          2175:      tree type;
        !          2176: {
        !          2177:   if (yychar < 0)
        !          2178:     yychar = yylex ();
        !          2179: 
        !          2180:   if ((yychar > 255
        !          2181:        && yychar != SCSPEC
        !          2182:        && yychar != IDENTIFIER
        !          2183:        && yychar != TYPENAME)
        !          2184:       || end_of_file)
        !          2185:     {
        !          2186:       if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (type)))
        !          2187:        error ("semicolon missing after %s declaration",
        !          2188:               TREE_CODE (type) == ENUMERAL_TYPE ? "enum" : "struct");
        !          2189:       else
        !          2190:        cp_error ("semicolon missing after declaration of `%T'", type);
        !          2191:       shadow_tag (build_tree_list (0, type));
        !          2192:     }
        !          2193:   /* Could probably also hack cases where class { ... } f (); appears.  */
        !          2194:   clear_anon_tags ();
        !          2195: }
        !          2196: 
        !          2197: void
        !          2198: note_got_semicolon (type)
        !          2199:      tree type;
        !          2200: {
        !          2201:   if (TREE_CODE_CLASS (TREE_CODE (type)) != 't')
        !          2202:     my_friendly_abort (60);
        !          2203:   if (IS_AGGR_TYPE (type))
        !          2204:     CLASSTYPE_GOT_SEMICOLON (type) = 1;
        !          2205: }
        !          2206: 
        !          2207: void
        !          2208: note_list_got_semicolon (declspecs)
        !          2209:      tree declspecs;
        !          2210: {
        !          2211:   tree link;
        !          2212: 
        !          2213:   for (link = declspecs; link; link = TREE_CHAIN (link))
        !          2214:     {
        !          2215:       tree type = TREE_VALUE (link);
        !          2216:       if (TREE_CODE_CLASS (TREE_CODE (type)) == 't')
        !          2217:        note_got_semicolon (type);
        !          2218:     }
        !          2219:   clear_anon_tags ();
        !          2220: }
        !          2221: 
        !          2222: /* If C is not whitespace, return C.
        !          2223:    Otherwise skip whitespace and return first nonwhite char read.  */
        !          2224: 
        !          2225: static int
        !          2226: skip_white_space (c)
        !          2227:      register int c;
        !          2228: {
        !          2229:   for (;;)
        !          2230:     {
        !          2231:       switch (c)
        !          2232:        {
        !          2233:        case '\n':
        !          2234:          c = check_newline ();
        !          2235:          break;
        !          2236: 
        !          2237:        case ' ':
        !          2238:        case '\t':
        !          2239:        case '\f':
        !          2240:        case '\r':
        !          2241:        case '\v':
        !          2242:        case '\b':
        !          2243:          do
        !          2244:            c = getch ();
        !          2245:          while (c == ' ' || c == '\t');
        !          2246:          break;
        !          2247: 
        !          2248:        case '\\':
        !          2249:          c = getch ();
        !          2250:          if (c == '\n')
        !          2251:            lineno++;
        !          2252:          else
        !          2253:            error ("stray '\\' in program");
        !          2254:          c = getch ();
        !          2255:          break;
        !          2256: 
        !          2257:        default:
        !          2258:          return (c);
        !          2259:        }
        !          2260:     }
        !          2261: }
        !          2262: 
        !          2263: 
        !          2264: 
        !          2265: /* Make the token buffer longer, preserving the data in it.
        !          2266:    P should point to just beyond the last valid character in the old buffer.
        !          2267:    The value we return is a pointer to the new buffer
        !          2268:    at a place corresponding to P.  */
        !          2269: 
        !          2270: static char *
        !          2271: extend_token_buffer (p)
        !          2272:      char *p;
        !          2273: {
        !          2274:   int offset = p - token_buffer;
        !          2275: 
        !          2276:   maxtoken = maxtoken * 2 + 10;
        !          2277:   token_buffer = (char *) xrealloc (token_buffer, maxtoken + 2);
        !          2278: 
        !          2279:   return token_buffer + offset;
        !          2280: }
        !          2281: 
        !          2282: static int
        !          2283: get_last_nonwhite_on_line ()
        !          2284: {
        !          2285:   register int c;
        !          2286: 
        !          2287:   /* Is this the last nonwhite stuff on the line?  */
        !          2288:   if (nextchar >= 0)
        !          2289:     c = nextchar, nextchar = -1;
        !          2290:   else
        !          2291:     c = getch ();
        !          2292: 
        !          2293:   while (c == ' ' || c == '\t')
        !          2294:     c = getch ();
        !          2295:   return c;
        !          2296: }
        !          2297: 
        !          2298: /* At the beginning of a line, increment the line number
        !          2299:    and process any #-directive on this line.
        !          2300:    If the line is a #-directive, read the entire line and return a newline.
        !          2301:    Otherwise, return the line's first non-whitespace character.  */
        !          2302: 
        !          2303: int
        !          2304: check_newline ()
        !          2305: {
        !          2306:   register int c;
        !          2307:   register int token;
        !          2308: 
        !          2309:   /* Read first nonwhite char on the line.  Do this before incrementing the
        !          2310:      line number, in case we're at the end of saved text.  */
        !          2311: 
        !          2312:   do
        !          2313:     c = getch ();
        !          2314:   while (c == ' ' || c == '\t');
        !          2315: 
        !          2316:   lineno++;
        !          2317: 
        !          2318:   if (c != '#')
        !          2319:     {
        !          2320:       /* If not #, return it so caller will use it.  */
        !          2321:       return c;
        !          2322:     }
        !          2323: 
        !          2324:   /* Read first nonwhite char after the `#'.  */
        !          2325: 
        !          2326:   do
        !          2327:     c = getch ();
        !          2328:   while (c == ' ' || c == '\t');
        !          2329: 
        !          2330:   /* If a letter follows, then if the word here is `line', skip
        !          2331:      it and ignore it; otherwise, ignore the line, with an error
        !          2332:      if the word isn't `pragma'.  */
        !          2333: 
        !          2334:   if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
        !          2335:     {
        !          2336:       if (c == 'p')
        !          2337:        {
        !          2338:          if (getch () == 'r'
        !          2339:              && getch () == 'a'
        !          2340:              && getch () == 'g'
        !          2341:              && getch () == 'm'
        !          2342:              && getch () == 'a')
        !          2343:            {
        !          2344:              /* Read first nonwhite char after the `#pragma'.  */
        !          2345: 
        !          2346:              do
        !          2347:                c = getch ();
        !          2348:              while (c == ' ' || c == '\t');
        !          2349: 
        !          2350:              if (c == 'v'
        !          2351:                  && getch () == 't'
        !          2352:                  && getch () == 'a'
        !          2353:                  && getch () == 'b'
        !          2354:                  && getch () == 'l'
        !          2355:                  && getch () == 'e'
        !          2356:                  && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
        !          2357:                {
        !          2358:                  extern tree pending_vtables;
        !          2359: 
        !          2360:                  /* More follows: it must be a string constant (class name).  */
        !          2361:                  token = real_yylex ();
        !          2362:                  if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
        !          2363:                    {
        !          2364:                      error ("invalid #pragma vtable");
        !          2365:                      goto skipline;
        !          2366:                    }
        !          2367:                  if (write_virtuals != 2)
        !          2368:                    {
        !          2369:                      warning ("use `+e2' option to enable #pragma vtable");
        !          2370:                      goto skipline;
        !          2371:                    }
        !          2372:                  pending_vtables = perm_tree_cons (NULL_TREE, get_identifier (TREE_STRING_POINTER (yylval.ttype)), pending_vtables);
        !          2373:                  if (nextchar < 0)
        !          2374:                    nextchar = getch ();
        !          2375:                  c = nextchar;
        !          2376:                  if (c != '\n')
        !          2377:                    warning ("trailing characters ignored");
        !          2378:                }
        !          2379:              else if (c == 'u'
        !          2380:                       && getch () == 'n'
        !          2381:                       && getch () == 'i'
        !          2382:                       && getch () == 't'
        !          2383:                       && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
        !          2384:                {
        !          2385:                  /* More follows: it must be a string constant (unit name).  */
        !          2386:                  token = real_yylex ();
        !          2387:                  if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
        !          2388:                    {
        !          2389:                      error ("invalid #pragma unit");
        !          2390:                      goto skipline;
        !          2391:                    }
        !          2392:                  current_unit_name = get_identifier (TREE_STRING_POINTER (yylval.ttype));
        !          2393:                  current_unit_language = current_lang_name;
        !          2394:                  if (nextchar < 0)
        !          2395:                    nextchar = getch ();
        !          2396:                  c = nextchar;
        !          2397:                  if (c != '\n')
        !          2398:                    warning ("trailing characters ignored");
        !          2399:                }
        !          2400:              else if (c == 'i')
        !          2401:                {
        !          2402:                  tree fileinfo = IDENTIFIER_CLASS_VALUE (get_time_identifier (input_filename));
        !          2403:                  c = getch ();
        !          2404: 
        !          2405:                  if (c == 'n'
        !          2406:                      && getch () == 't'
        !          2407:                      && getch () == 'e'
        !          2408:                      && getch () == 'r'
        !          2409:                      && getch () == 'f'
        !          2410:                      && getch () == 'a'
        !          2411:                      && getch () == 'c'
        !          2412:                      && getch () == 'e'
        !          2413:                      && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
        !          2414:                    {
        !          2415:                      int warned_already = 0;
        !          2416:                      char *main_filename = input_filename;
        !          2417: 
        !          2418:                      main_filename = FILE_NAME_NONDIRECTORY (main_filename);
        !          2419:                      while (c == ' ' || c == '\t')
        !          2420:                        c = getch ();
        !          2421:                      if (c != '\n')
        !          2422:                        {
        !          2423:                          put_back (c);
        !          2424:                          token = real_yylex ();
        !          2425:                          if (token != STRING
        !          2426:                              || TREE_CODE (yylval.ttype) != STRING_CST)
        !          2427:                            {
        !          2428:                              error ("invalid `#pragma interface'");
        !          2429:                              goto skipline;
        !          2430:                            }
        !          2431:                          main_filename = TREE_STRING_POINTER (yylval.ttype);
        !          2432:                          c = getch();
        !          2433:                          put_back (c);
        !          2434:                        }
        !          2435: 
        !          2436:                      while (c == ' ' || c == '\t')
        !          2437:                        c = getch ();
        !          2438: 
        !          2439:                      while (c != '\n')
        !          2440:                        {
        !          2441:                          if (!warned_already && extra_warnings
        !          2442:                              && c != ' ' && c != '\t' && c != '\n')
        !          2443:                            {
        !          2444:                              warning ("garbage after `#pragma interface' ignored");
        !          2445:                              warned_already = 1;
        !          2446:                            }
        !          2447:                          c = getch ();
        !          2448:                        }
        !          2449: 
        !          2450:                      write_virtuals = 3;
        !          2451: 
        !          2452:                      if (impl_file_chain == 0)
        !          2453:                        {
        !          2454:                          /* If this is zero at this point, then we are
        !          2455:                             auto-implementing.  */
        !          2456:                          if (main_input_filename == 0)
        !          2457:                            main_input_filename = input_filename;
        !          2458: 
        !          2459: #ifdef AUTO_IMPLEMENT
        !          2460:                          filename = FILE_NAME_NONDIRECTORY (main_input_filename);
        !          2461:                          fi = get_time_identifier (filename);
        !          2462:                          fi = IDENTIFIER_CLASS_VALUE (fi);
        !          2463:                          TREE_INT_CST_LOW (fi) = 0;
        !          2464:                          TREE_INT_CST_HIGH (fi) = 1;
        !          2465:                          /* Get default.  */
        !          2466:                          impl_file_chain = (struct impl_files *)permalloc (sizeof (struct impl_files));
        !          2467:                          impl_file_chain->filename = filename;
        !          2468:                          impl_file_chain->next = 0;
        !          2469: #endif
        !          2470:                        }
        !          2471: 
        !          2472:                      interface_only = interface_strcmp (main_filename);
        !          2473:                      interface_unknown = 0;
        !          2474:                      TREE_INT_CST_LOW (fileinfo) = interface_only;
        !          2475:                      TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
        !          2476:                    }
        !          2477:                  else if (c == 'm'
        !          2478:                           && getch () == 'p'
        !          2479:                           && getch () == 'l'
        !          2480:                           && getch () == 'e'
        !          2481:                           && getch () == 'm'
        !          2482:                           && getch () == 'e'
        !          2483:                           && getch () == 'n'
        !          2484:                           && getch () == 't'
        !          2485:                           && getch () == 'a'
        !          2486:                           && getch () == 't'
        !          2487:                           && getch () == 'i'
        !          2488:                           && getch () == 'o'
        !          2489:                           && getch () == 'n'
        !          2490:                           && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
        !          2491:                    {
        !          2492:                      int warned_already = 0;
        !          2493:                      char *main_filename = main_input_filename ? main_input_filename : input_filename;
        !          2494: 
        !          2495:                      main_filename = FILE_NAME_NONDIRECTORY (main_filename);
        !          2496:                      while (c == ' ' || c == '\t')
        !          2497:                        c = getch ();
        !          2498:                      if (c != '\n')
        !          2499:                        {
        !          2500:                          put_back (c);
        !          2501:                          token = real_yylex ();
        !          2502:                          if (token != STRING
        !          2503:                              || TREE_CODE (yylval.ttype) != STRING_CST)
        !          2504:                            {
        !          2505:                              error ("invalid `#pragma implementation'");
        !          2506:                              goto skipline;
        !          2507:                            }
        !          2508:                          main_filename = TREE_STRING_POINTER (yylval.ttype);
        !          2509:                          c = getch();
        !          2510:                          put_back (c);
        !          2511:                        }
        !          2512: 
        !          2513:                      while (c == ' ' || c == '\t')
        !          2514:                        c = getch ();
        !          2515: 
        !          2516:                      while (c != '\n')
        !          2517:                        {
        !          2518:                          if (!warned_already && extra_warnings
        !          2519:                              && c != ' ' && c != '\t' && c != '\n')
        !          2520:                            {
        !          2521:                              warning ("garbage after `#pragma implementation' ignored");
        !          2522:                              warned_already = 1;
        !          2523:                            }
        !          2524:                          c = getch ();
        !          2525:                        }
        !          2526: 
        !          2527:                      if (write_virtuals == 3)
        !          2528:                        {
        !          2529:                          struct impl_files *ifiles = impl_file_chain;
        !          2530:                          while (ifiles)
        !          2531:                            {
        !          2532:                              if (! strcmp (ifiles->filename, main_filename))
        !          2533:                                break;
        !          2534:                              ifiles = ifiles->next;
        !          2535:                            }
        !          2536:                          if (ifiles == 0)
        !          2537:                            {
        !          2538:                              ifiles = (struct impl_files*) permalloc (sizeof (struct impl_files));
        !          2539:                              ifiles->filename = main_filename;
        !          2540:                              ifiles->next = impl_file_chain;
        !          2541:                              impl_file_chain = ifiles;
        !          2542:                            }
        !          2543:                        }
        !          2544:                      else if ((main_input_filename != 0
        !          2545:                                && ! strcmp (main_input_filename, input_filename))
        !          2546:                               || ! strcmp (input_filename, main_filename))
        !          2547:                        {
        !          2548:                          write_virtuals = 3;
        !          2549:                          if (impl_file_chain == 0)
        !          2550:                            {
        !          2551:                              impl_file_chain = (struct impl_files*) permalloc (sizeof (struct impl_files));
        !          2552:                              impl_file_chain->filename = main_filename;
        !          2553:                              impl_file_chain->next = 0;
        !          2554:                            }
        !          2555:                        }
        !          2556:                      else
        !          2557:                        error ("`#pragma implementation' can only appear at top-level");
        !          2558:                      interface_only = 0;
        !          2559: #if 1
        !          2560:                      /* We make this non-zero so that we infer decl linkage
        !          2561:                         in the impl file only for variables first declared
        !          2562:                         in the interface file.  */
        !          2563:                      interface_unknown = 1;
        !          2564: #else
        !          2565:                      /* We make this zero so that templates in the impl
        !          2566:                          file will be emitted properly. */
        !          2567:                      interface_unknown = 0;
        !          2568: #endif
        !          2569:                      TREE_INT_CST_LOW (fileinfo) = interface_only;
        !          2570:                      TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
        !          2571:                    }
        !          2572:                }
        !          2573:            }
        !          2574:          goto skipline;
        !          2575:        }
        !          2576:       else if (c == 'd')
        !          2577:        {
        !          2578:          if (getch () == 'e'
        !          2579:              && getch () == 'f'
        !          2580:              && getch () == 'i'
        !          2581:              && getch () == 'n'
        !          2582:              && getch () == 'e'
        !          2583:              && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
        !          2584:            {
        !          2585: #ifdef DWARF_DEBUGGING_INFO
        !          2586:              if ((debug_info_level == DINFO_LEVEL_VERBOSE)
        !          2587:                  && (write_symbols == DWARF_DEBUG))
        !          2588:                dwarfout_define (lineno, get_directive_line (finput));
        !          2589: #endif /* DWARF_DEBUGGING_INFO */
        !          2590:              goto skipline;
        !          2591:            }
        !          2592:        }
        !          2593:       else if (c == 'u')
        !          2594:        {
        !          2595:          if (getch () == 'n'
        !          2596:              && getch () == 'd'
        !          2597:              && getch () == 'e'
        !          2598:              && getch () == 'f'
        !          2599:              && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
        !          2600:            {
        !          2601: #ifdef DWARF_DEBUGGING_INFO
        !          2602:              if ((debug_info_level == DINFO_LEVEL_VERBOSE)
        !          2603:                  && (write_symbols == DWARF_DEBUG))
        !          2604:                dwarfout_undef (lineno, get_directive_line (finput));
        !          2605: #endif /* DWARF_DEBUGGING_INFO */
        !          2606:              goto skipline;
        !          2607:            }
        !          2608:        }
        !          2609:       else if (c == 'l')
        !          2610:        {
        !          2611:          if (getch () == 'i'
        !          2612:              && getch () == 'n'
        !          2613:              && getch () == 'e'
        !          2614:              && ((c = getch ()) == ' ' || c == '\t'))
        !          2615:            goto linenum;
        !          2616:        }
        !          2617:       else if (c == 'i')
        !          2618:        {
        !          2619:          if (getch () == 'd'
        !          2620:              && getch () == 'e'
        !          2621:              && getch () == 'n'
        !          2622:              && getch () == 't'
        !          2623:              && ((c = getch ()) == ' ' || c == '\t'))
        !          2624:            {
        !          2625: #ifdef ASM_OUTPUT_IDENT
        !          2626:               extern FILE *asm_out_file;
        !          2627: #endif
        !          2628:              /* #ident.  The pedantic warning is now in cccp.c.  */
        !          2629: 
        !          2630:              /* Here we have just seen `#ident '.
        !          2631:                 A string constant should follow.  */
        !          2632: 
        !          2633:              while (c == ' ' || c == '\t')
        !          2634:                c = getch ();
        !          2635: 
        !          2636:              /* If no argument, ignore the line.  */
        !          2637:              if (c == '\n')
        !          2638:                return c;
        !          2639: 
        !          2640:              put_back (c);
        !          2641:              token = real_yylex ();
        !          2642:              if (token != STRING
        !          2643:                  || TREE_CODE (yylval.ttype) != STRING_CST)
        !          2644:                {
        !          2645:                  error ("invalid #ident");
        !          2646:                  goto skipline;
        !          2647:                }
        !          2648: 
        !          2649:              if (! flag_no_ident)
        !          2650:                {
        !          2651: #ifdef ASM_OUTPUT_IDENT
        !          2652:                  ASM_OUTPUT_IDENT (asm_out_file,
        !          2653:                                    TREE_STRING_POINTER (yylval.ttype));
        !          2654: #endif
        !          2655:                }
        !          2656: 
        !          2657:              /* Skip the rest of this line.  */
        !          2658:              goto skipline;
        !          2659:            }
        !          2660:        }
        !          2661:       else if (c == 'n')
        !          2662:        {
        !          2663:          if (getch () == 'e'
        !          2664:              && getch () == 'w'
        !          2665:              && getch () == 'w'
        !          2666:              && getch () == 'o'
        !          2667:              && getch () == 'r'
        !          2668:              && getch () == 'l'
        !          2669:              && getch () == 'd'
        !          2670:              && ((c = getch ()) == ' ' || c == '\t'))
        !          2671:            {
        !          2672:              /* Used to test incremental compilation.  */
        !          2673:              sorry ("#pragma newworld");
        !          2674:              goto skipline;
        !          2675:            }
        !          2676:        }
        !          2677:       error ("undefined or invalid # directive");
        !          2678:       goto skipline;
        !          2679:     }
        !          2680: 
        !          2681: linenum:
        !          2682:   /* Here we have either `#line' or `# <nonletter>'.
        !          2683:      In either case, it should be a line number; a digit should follow.  */
        !          2684: 
        !          2685:   while (c == ' ' || c == '\t')
        !          2686:     c = getch ();
        !          2687: 
        !          2688:   /* If the # is the only nonwhite char on the line,
        !          2689:      just ignore it.  Check the new newline.  */
        !          2690:   if (c == '\n')
        !          2691:     return c;
        !          2692: 
        !          2693:   /* Something follows the #; read a token.  */
        !          2694: 
        !          2695:   put_back (c);
        !          2696:   token = real_yylex ();
        !          2697: 
        !          2698:   if (token == CONSTANT
        !          2699:       && TREE_CODE (yylval.ttype) == INTEGER_CST)
        !          2700:     {
        !          2701:       int old_lineno = lineno;
        !          2702:       enum { act_none, act_push, act_pop } action = act_none;
        !          2703:       int entering_system_header = 0;
        !          2704:       int entering_c_header = 0;
        !          2705: 
        !          2706:       /* subtract one, because it is the following line that
        !          2707:         gets the specified number */
        !          2708: 
        !          2709:       int l = TREE_INT_CST_LOW (yylval.ttype) - 1;
        !          2710:       c = get_last_nonwhite_on_line ();
        !          2711:       if (c == '\n')
        !          2712:        {
        !          2713:          /* No more: store the line number and check following line.  */
        !          2714:          lineno = l;
        !          2715:          return c;
        !          2716:        }
        !          2717:       put_back (c);
        !          2718: 
        !          2719:       /* More follows: it must be a string constant (filename).  */
        !          2720: 
        !          2721:       /* Read the string constant, but don't treat \ as special.  */
        !          2722:       ignore_escape_flag = 1;
        !          2723:       token = real_yylex ();
        !          2724:       ignore_escape_flag = 0;
        !          2725: 
        !          2726:       if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
        !          2727:        {
        !          2728:          error ("invalid #line");
        !          2729:          goto skipline;
        !          2730:        }
        !          2731: 
        !          2732:       /* Changing files again.  This means currently collected time
        !          2733:         is charged against header time, and body time starts back
        !          2734:         at 0.  */
        !          2735:       if (flag_detailed_statistics)
        !          2736:        {
        !          2737:          int this_time = my_get_run_time ();
        !          2738:          tree time_identifier = get_time_identifier (TREE_STRING_POINTER (yylval.ttype));
        !          2739:          header_time += this_time - body_time;
        !          2740:          TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time))
        !          2741:            += this_time - body_time;
        !          2742:          this_filename_time = time_identifier;
        !          2743:          body_time = this_time;
        !          2744:        }
        !          2745: 
        !          2746:       if (flag_cadillac)
        !          2747:        cadillac_note_source ();
        !          2748: 
        !          2749:       input_filename
        !          2750:        = (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1);
        !          2751:       strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype));
        !          2752:       lineno = l;
        !          2753:       GNU_xref_file (input_filename);
        !          2754:       
        !          2755:       if (main_input_filename == 0)
        !          2756:        {
        !          2757:          struct impl_files *ifiles = impl_file_chain;
        !          2758: 
        !          2759:          if (ifiles)
        !          2760:            {
        !          2761:              while (ifiles->next)
        !          2762:                ifiles = ifiles->next;
        !          2763:              ifiles->filename = FILE_NAME_NONDIRECTORY (input_filename);
        !          2764:            }
        !          2765: 
        !          2766:          main_input_filename = input_filename;
        !          2767:          if (write_virtuals == 3)
        !          2768:            walk_vtables (set_typedecl_interface_info, set_vardecl_interface_info);
        !          2769:        }
        !          2770: 
        !          2771:       extract_interface_info ();
        !          2772: 
        !          2773:       c = get_last_nonwhite_on_line ();
        !          2774:       if (c != '\n')
        !          2775:        {
        !          2776:          put_back (c);
        !          2777: 
        !          2778:          token = real_yylex ();
        !          2779: 
        !          2780:          /* `1' after file name means entering new file.
        !          2781:             `2' after file name means just left a file.  */
        !          2782: 
        !          2783:          if (token == CONSTANT
        !          2784:              && TREE_CODE (yylval.ttype) == INTEGER_CST)
        !          2785:            {
        !          2786:              if (TREE_INT_CST_LOW (yylval.ttype) == 1)
        !          2787:                action = act_push;
        !          2788:              else if (TREE_INT_CST_LOW (yylval.ttype) == 2)
        !          2789:                action = act_pop;
        !          2790: 
        !          2791:              if (action)
        !          2792:                {
        !          2793:                  c = get_last_nonwhite_on_line ();
        !          2794:                  if (c != '\n')
        !          2795:                    {
        !          2796:                      put_back (c);
        !          2797:                      token = real_yylex ();
        !          2798:                    }
        !          2799:                }
        !          2800:            }
        !          2801: 
        !          2802:          /* `3' after file name means this is a system header file.  */
        !          2803: 
        !          2804:          if (token == CONSTANT
        !          2805:              && TREE_CODE (yylval.ttype) == INTEGER_CST
        !          2806:              && TREE_INT_CST_LOW (yylval.ttype) == 3)
        !          2807:            {
        !          2808:              entering_system_header = 1;
        !          2809: 
        !          2810:              c = get_last_nonwhite_on_line ();
        !          2811:              if (c != '\n')
        !          2812:                {
        !          2813:                  put_back (c);
        !          2814:                  token = real_yylex ();
        !          2815:                }
        !          2816:            }
        !          2817: 
        !          2818:          /* `4' after file name means this is a C header file.  */
        !          2819: 
        !          2820:          if (token == CONSTANT
        !          2821:              && TREE_CODE (yylval.ttype) == INTEGER_CST
        !          2822:              && TREE_INT_CST_LOW (yylval.ttype) == 4)
        !          2823:            {
        !          2824:              entering_c_header = 1;
        !          2825: 
        !          2826:              c = get_last_nonwhite_on_line ();
        !          2827:              if (c != '\n')
        !          2828:                {
        !          2829:                  put_back (c);
        !          2830:                  token = real_yylex ();
        !          2831:                }
        !          2832:            }
        !          2833: 
        !          2834:          /* Do the actions implied by the preceeding numbers.  */
        !          2835: 
        !          2836:          if (action == act_push)
        !          2837:            {
        !          2838:              /* Pushing to a new file.  */
        !          2839:              struct file_stack *p;
        !          2840: 
        !          2841:              p = (struct file_stack *) xmalloc (sizeof (struct file_stack));
        !          2842:              input_file_stack->line = old_lineno;
        !          2843:              p->next = input_file_stack;
        !          2844:              p->name = input_filename;
        !          2845:              input_file_stack = p;
        !          2846:              input_file_stack_tick++;
        !          2847: #ifdef DWARF_DEBUGGING_INFO
        !          2848:              if (debug_info_level == DINFO_LEVEL_VERBOSE
        !          2849:                  && write_symbols == DWARF_DEBUG)
        !          2850:                dwarfout_start_new_source_file (input_filename);
        !          2851: #endif /* DWARF_DEBUGGING_INFO */
        !          2852:              if (flag_cadillac)
        !          2853:                cadillac_push_source ();
        !          2854:              in_system_header = entering_system_header;
        !          2855:              if (c_header_level)
        !          2856:                ++c_header_level;
        !          2857:              else if (entering_c_header)
        !          2858:                {
        !          2859:                  c_header_level = 1;
        !          2860:                  ++pending_lang_change;
        !          2861:                }
        !          2862:            }
        !          2863:          else if (action == act_pop)
        !          2864:            {
        !          2865:              /* Popping out of a file.  */
        !          2866:              if (input_file_stack->next)
        !          2867:                {
        !          2868:                  struct file_stack *p;
        !          2869: 
        !          2870:                  if (c_header_level && --c_header_level == 0)
        !          2871:                    {
        !          2872:                      if (entering_c_header)
        !          2873:                        warning ("badly nested C headers from preprocessor");
        !          2874:                      --pending_lang_change;
        !          2875:                    }
        !          2876:                  if (flag_cadillac)
        !          2877:                    cadillac_pop_source ();
        !          2878:                  in_system_header = entering_system_header;
        !          2879: 
        !          2880:                  p = input_file_stack;
        !          2881:                  input_file_stack = p->next;
        !          2882:                  free (p);
        !          2883:                  input_file_stack_tick++;
        !          2884: #ifdef DWARF_DEBUGGING_INFO
        !          2885:                  if (debug_info_level == DINFO_LEVEL_VERBOSE
        !          2886:                      && write_symbols == DWARF_DEBUG)
        !          2887:                    dwarfout_resume_previous_source_file (input_file_stack->line);
        !          2888: #endif /* DWARF_DEBUGGING_INFO */
        !          2889:                }
        !          2890:              else
        !          2891:                error ("#-lines for entering and leaving files don't match");
        !          2892:            }
        !          2893:          else
        !          2894:            {
        !          2895:              in_system_header = entering_system_header;
        !          2896:              if (flag_cadillac)
        !          2897:                cadillac_switch_source (-1);
        !          2898:            }
        !          2899:        }
        !          2900: 
        !          2901:       /* If NEXTCHAR is not end of line, we don't care what it is.  */
        !          2902:       if (nextchar == '\n')
        !          2903:        return '\n';
        !          2904:     }
        !          2905:   else
        !          2906:     error ("invalid #-line");
        !          2907: 
        !          2908:   /* skip the rest of this line.  */
        !          2909:  skipline:
        !          2910:   if (c == '\n')
        !          2911:     return c;
        !          2912:   while ((c = getch ()) != EOF && c != '\n');
        !          2913:   return c;
        !          2914: }
        !          2915: 
        !          2916: void
        !          2917: do_pending_lang_change ()
        !          2918: {
        !          2919:   for (; pending_lang_change > 0; --pending_lang_change)
        !          2920:     push_lang_context (lang_name_c);
        !          2921:   for (; pending_lang_change < 0; ++pending_lang_change)
        !          2922:     pop_lang_context ();
        !          2923: }
        !          2924: 
        !          2925: #if 0
        !          2926: #define isalnum(char) (char >= 'a' ? char <= 'z' : char >= '0' ? char <= '9' || (char >= 'A' && char <= 'Z') : 0)
        !          2927: #define isdigit(char) (char >= '0' && char <= '9')
        !          2928: #else
        !          2929: #include <ctype.h>
        !          2930: #endif
        !          2931: 
        !          2932: #define ENDFILE -1  /* token that represents end-of-file */
        !          2933: 
        !          2934: /* Read an escape sequence, returning its equivalent as a character,
        !          2935:    or store 1 in *ignore_ptr if it is backslash-newline.  */
        !          2936: 
        !          2937: static int
        !          2938: readescape (ignore_ptr)
        !          2939:      int *ignore_ptr;
        !          2940: {
        !          2941:   register int c = getch ();
        !          2942:   register int code;
        !          2943:   register unsigned count;
        !          2944:   unsigned firstdig;
        !          2945:   int nonnull;
        !          2946: 
        !          2947:   switch (c)
        !          2948:     {
        !          2949:     case 'x':
        !          2950:       if (warn_traditional)
        !          2951:        warning ("the meaning of `\\x' varies with -traditional");
        !          2952: 
        !          2953:       if (flag_traditional)
        !          2954:        return c;
        !          2955: 
        !          2956:       code = 0;
        !          2957:       count = 0;
        !          2958:       nonnull = 0;
        !          2959:       while (1)
        !          2960:        {
        !          2961:          c = getch ();
        !          2962:          if (! isxdigit (c))
        !          2963:            {
        !          2964:              put_back (c);
        !          2965:              break;
        !          2966:            }
        !          2967:          code *= 16;
        !          2968:          if (c >= 'a' && c <= 'f')
        !          2969:            code += c - 'a' + 10;
        !          2970:          if (c >= 'A' && c <= 'F')
        !          2971:            code += c - 'A' + 10;
        !          2972:          if (c >= '0' && c <= '9')
        !          2973:            code += c - '0';
        !          2974:          if (code != 0 || count != 0)
        !          2975:            {
        !          2976:              if (count == 0)
        !          2977:                firstdig = code;
        !          2978:              count++;
        !          2979:            }
        !          2980:          nonnull = 1;
        !          2981:        }
        !          2982:       if (! nonnull)
        !          2983:        error ("\\x used with no following hex digits");
        !          2984:       else if (count == 0)
        !          2985:        /* Digits are all 0's.  Ok.  */
        !          2986:        ;
        !          2987:       else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node)
        !          2988:               || (count > 1
        !          2989:                   && ((1 << (TYPE_PRECISION (integer_type_node) - (count - 1) * 4))
        !          2990:                       <= firstdig)))
        !          2991:        pedwarn ("hex escape out of range");
        !          2992:       return code;
        !          2993: 
        !          2994:     case '0':  case '1':  case '2':  case '3':  case '4':
        !          2995:     case '5':  case '6':  case '7':
        !          2996:       code = 0;
        !          2997:       count = 0;
        !          2998:       while ((c <= '7') && (c >= '0') && (count++ < 3))
        !          2999:        {
        !          3000:          code = (code * 8) + (c - '0');
        !          3001:          c = getch ();
        !          3002:        }
        !          3003:       put_back (c);
        !          3004:       return code;
        !          3005: 
        !          3006:     case '\\': case '\'': case '"':
        !          3007:       return c;
        !          3008: 
        !          3009:     case '\n':
        !          3010:       lineno++;
        !          3011:       *ignore_ptr = 1;
        !          3012:       return 0;
        !          3013: 
        !          3014:     case 'n':
        !          3015:       return TARGET_NEWLINE;
        !          3016: 
        !          3017:     case 't':
        !          3018:       return TARGET_TAB;
        !          3019: 
        !          3020:     case 'r':
        !          3021:       return TARGET_CR;
        !          3022: 
        !          3023:     case 'f':
        !          3024:       return TARGET_FF;
        !          3025: 
        !          3026:     case 'b':
        !          3027:       return TARGET_BS;
        !          3028: 
        !          3029:     case 'a':
        !          3030:       if (warn_traditional)
        !          3031:        warning ("the meaning of `\\a' varies with -traditional");
        !          3032: 
        !          3033:       if (flag_traditional)
        !          3034:        return c;
        !          3035:       return TARGET_BELL;
        !          3036: 
        !          3037:     case 'v':
        !          3038:       return TARGET_VT;
        !          3039: 
        !          3040:     case 'e':
        !          3041:     case 'E':
        !          3042:       if (pedantic)
        !          3043:        pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
        !          3044:       return 033;
        !          3045: 
        !          3046:     case '?':
        !          3047:       return c;
        !          3048: 
        !          3049:       /* `\(', etc, are used at beginning of line to avoid confusing Emacs.  */
        !          3050:     case '(':
        !          3051:     case '{':
        !          3052:     case '[':
        !          3053:       /* `\%' is used to prevent SCCS from getting confused.  */
        !          3054:     case '%':
        !          3055:       if (pedantic)
        !          3056:        pedwarn ("unknown escape sequence `\\%c'", c);
        !          3057:       return c;
        !          3058:     }
        !          3059:   if (c >= 040 && c < 0177)
        !          3060:     pedwarn ("unknown escape sequence `\\%c'", c);
        !          3061:   else
        !          3062:     pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c);
        !          3063:   return c;
        !          3064: }
        !          3065: 
        !          3066: /* Value is 1 (or 2) if we should try to make the next identifier look like
        !          3067:    a typename (when it may be a local variable or a class variable).
        !          3068:    Value is 0 if we treat this name in a default fashion.  */
        !          3069: int looking_for_typename = 0;
        !          3070: 
        !          3071: #if 0
        !          3072: /* NO LONGER USED: Value is -1 if we must not see a type name.  */
        !          3073: void
        !          3074: dont_see_typename ()
        !          3075: {
        !          3076:   looking_for_typename = -1;
        !          3077:   if (yychar == TYPENAME || yychar == PTYPENAME)
        !          3078:     {
        !          3079:       yychar = IDENTIFIER;
        !          3080:       lastiddecl = 0;
        !          3081:     }
        !          3082: }
        !          3083: #endif
        !          3084: 
        !          3085: #ifdef __GNUC__
        !          3086: extern __inline int identifier_type ();
        !          3087: __inline
        !          3088: #endif
        !          3089: int
        !          3090: identifier_type (decl)
        !          3091:      tree decl;
        !          3092: {
        !          3093:   if (TREE_CODE (decl) == TEMPLATE_DECL
        !          3094:       && DECL_TEMPLATE_IS_CLASS (decl))
        !          3095:     return PTYPENAME;
        !          3096:   if (TREE_CODE (decl) != TYPE_DECL)
        !          3097:     return IDENTIFIER;
        !          3098:   return TYPENAME;
        !          3099: }
        !          3100: 
        !          3101: void
        !          3102: see_typename ()
        !          3103: {
        !          3104:   looking_for_typename = 0;
        !          3105:   if (yychar == IDENTIFIER)
        !          3106:     {
        !          3107:       lastiddecl = lookup_name (yylval.ttype, -2);
        !          3108:       if (lastiddecl == 0)
        !          3109:        {
        !          3110:          if (flag_labels_ok)
        !          3111:            lastiddecl = IDENTIFIER_LABEL_VALUE (yylval.ttype);
        !          3112:        }
        !          3113:       else
        !          3114:        yychar = identifier_type (lastiddecl);
        !          3115:     }
        !          3116: }
        !          3117: 
        !          3118: tree
        !          3119: do_identifier (token)
        !          3120:      register tree token;
        !          3121: {
        !          3122:   register tree id = lastiddecl;
        !          3123: 
        !          3124:   if (yychar == YYEMPTY)
        !          3125:     yychar = yylex ();
        !          3126:   /* Scope class declarations before global
        !          3127:      declarations.  */
        !          3128:   if (id == IDENTIFIER_GLOBAL_VALUE (token)
        !          3129:       && current_class_type != 0
        !          3130:       && TYPE_SIZE (current_class_type) == 0
        !          3131:       && TREE_CODE (current_class_type) != UNINSTANTIATED_P_TYPE)
        !          3132:     {
        !          3133:       /* Could be from one of the base classes.  */
        !          3134:       tree field = lookup_field (current_class_type, token, 1, 0);
        !          3135:       if (field == 0)
        !          3136:        ;
        !          3137:       else if (field == error_mark_node)
        !          3138:        /* We have already generated the error message.
        !          3139:           But we still want to return this value.  */
        !          3140:        id = lookup_field (current_class_type, token, 0, 0);
        !          3141:       else if (TREE_CODE (field) == VAR_DECL
        !          3142:               || TREE_CODE (field) == CONST_DECL)
        !          3143:        id = field;
        !          3144:       else if (TREE_CODE (field) != FIELD_DECL)
        !          3145:        my_friendly_abort (61);
        !          3146:       else
        !          3147:        {
        !          3148:          cp_error ("invalid use of member `%D' from base class `%T'", field,
        !          3149:                      DECL_FIELD_CONTEXT (field));
        !          3150:          id = error_mark_node;
        !          3151:          return id;
        !          3152:        }
        !          3153:     }
        !          3154: 
        !          3155:   /* Remember that this name has been used in the class definition, as per
        !          3156:      [class.scope0] */
        !          3157:   if (id && current_class_type
        !          3158:       && TYPE_BEING_DEFINED (current_class_type)
        !          3159:       && ! IDENTIFIER_CLASS_VALUE (token))
        !          3160:     pushdecl_class_level (id);
        !          3161:     
        !          3162:   if (!id || id == error_mark_node)
        !          3163:     {
        !          3164:       if (id == error_mark_node && current_class_type != NULL_TREE)
        !          3165:        {
        !          3166:          id = lookup_nested_field (token, 1);
        !          3167:          /* In lookup_nested_field(), we marked this so we can gracefully
        !          3168:             leave this whole mess.  */
        !          3169:          if (id && id != error_mark_node && TREE_TYPE (id) == error_mark_node)
        !          3170:            return id;
        !          3171:        }
        !          3172:       if (yychar == '(' || yychar == LEFT_RIGHT)
        !          3173:        {
        !          3174:          id = implicitly_declare (token);
        !          3175:        }
        !          3176:       else if (current_function_decl == 0)
        !          3177:        {
        !          3178:          cp_error ("`%D' was not declared in this scope", token);
        !          3179:          id = error_mark_node;
        !          3180:        }
        !          3181:       else
        !          3182:        {
        !          3183:          if (IDENTIFIER_GLOBAL_VALUE (token) != error_mark_node
        !          3184:              || IDENTIFIER_ERROR_LOCUS (token) != current_function_decl)
        !          3185:            {
        !          3186:              static int undeclared_variable_notice;
        !          3187: 
        !          3188:              cp_error ("`%D' undeclared (first use this function)", token);
        !          3189: 
        !          3190:              if (! undeclared_variable_notice)
        !          3191:                {
        !          3192:                  error ("(Each undeclared identifier is reported only once");
        !          3193:                  error ("for each function it appears in.)");
        !          3194:                  undeclared_variable_notice = 1;
        !          3195:                }
        !          3196:            }
        !          3197:          id = error_mark_node;
        !          3198:          /* Prevent repeated error messages.  */
        !          3199:          IDENTIFIER_GLOBAL_VALUE (token) = error_mark_node;
        !          3200:          SET_IDENTIFIER_ERROR_LOCUS (token, current_function_decl);
        !          3201:        }
        !          3202:     }
        !          3203:   /* TREE_USED is set in `hack_identifier'.  */
        !          3204:   if (TREE_CODE (id) == CONST_DECL)
        !          3205:     {
        !          3206:       if (IDENTIFIER_CLASS_VALUE (token) == id)
        !          3207:        {
        !          3208:          /* Check access.  */
        !          3209:          enum access_type access
        !          3210:            = compute_access (TYPE_BINFO (current_class_type), id);
        !          3211:          if (access == access_private)
        !          3212:            cp_error ("enum `%D' is private", id);
        !          3213:          /* protected is OK, since it's an enum of `this'.  */
        !          3214:        }
        !          3215:       id = DECL_INITIAL (id);
        !          3216:     }
        !          3217:   else
        !          3218:     id = hack_identifier (id, token, yychar);
        !          3219:   return id;
        !          3220: }
        !          3221: 
        !          3222: tree
        !          3223: identifier_typedecl_value (node)
        !          3224:      tree node;
        !          3225: {
        !          3226:   tree t, type;
        !          3227:   type = IDENTIFIER_TYPE_VALUE (node);
        !          3228:   if (type == NULL_TREE)
        !          3229:     return NULL_TREE;
        !          3230: #define do(X) \
        !          3231:   { \
        !          3232:     t = (X); \
        !          3233:     if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type) \
        !          3234:       return t; \
        !          3235:   }
        !          3236:   do (IDENTIFIER_LOCAL_VALUE (node));
        !          3237:   do (IDENTIFIER_CLASS_VALUE (node));
        !          3238:   do (IDENTIFIER_GLOBAL_VALUE (node));
        !          3239: #undef do
        !          3240:   /* Will this one ever happen?  */
        !          3241:   if (TYPE_NAME (type))
        !          3242:     return TYPE_NAME (type);
        !          3243: 
        !          3244:   /* We used to do an internal error of 62 here, but instead we will
        !          3245:      handle the return of a null appropriately in the callers.  */
        !          3246:   return NULL_TREE;
        !          3247: }
        !          3248: 
        !          3249: struct try_type
        !          3250: {
        !          3251:   tree *node_var;
        !          3252:   char unsigned_flag;
        !          3253:   char long_flag;
        !          3254:   char long_long_flag;
        !          3255: };
        !          3256: 
        !          3257: struct try_type type_sequence[] = 
        !          3258: {
        !          3259:   { &integer_type_node, 0, 0, 0},
        !          3260:   { &unsigned_type_node, 1, 0, 0},
        !          3261:   { &long_integer_type_node, 0, 1, 0},
        !          3262:   { &long_unsigned_type_node, 1, 1, 0},
        !          3263:   { &long_long_integer_type_node, 0, 1, 1},
        !          3264:   { &long_long_unsigned_type_node, 1, 1, 1}
        !          3265: };
        !          3266: 
        !          3267: int
        !          3268: real_yylex ()
        !          3269: {
        !          3270:   register int c;
        !          3271:   register int value;
        !          3272:   int wide_flag = 0;
        !          3273:   int dollar_seen = 0;
        !          3274:   int i;
        !          3275: 
        !          3276:   if (nextchar >= 0)
        !          3277:     c = nextchar, nextchar = -1;
        !          3278:   else
        !          3279:     c = getch ();
        !          3280: 
        !          3281:   /* Effectively do c = skip_white_space (c)
        !          3282:      but do it faster in the usual cases.  */
        !          3283:   while (1)
        !          3284:     switch (c)
        !          3285:       {
        !          3286:       case ' ':
        !          3287:       case '\t':
        !          3288:       case '\f':
        !          3289:       case '\v':
        !          3290:       case '\b':
        !          3291:        c = getch ();
        !          3292:        break;
        !          3293: 
        !          3294:       case '\r':
        !          3295:        /* Call skip_white_space so we can warn if appropriate.  */
        !          3296: 
        !          3297:       case '\n':
        !          3298:       case '/':
        !          3299:       case '\\':
        !          3300:        c = skip_white_space (c);
        !          3301:       default:
        !          3302:        goto found_nonwhite;
        !          3303:       }
        !          3304:  found_nonwhite:
        !          3305: 
        !          3306:   token_buffer[0] = c;
        !          3307:   token_buffer[1] = 0;
        !          3308: 
        !          3309: /*  yylloc.first_line = lineno; */
        !          3310: 
        !          3311:   switch (c)
        !          3312:     {
        !          3313:     case EOF:
        !          3314:       token_buffer[0] = '\0';
        !          3315:       end_of_file = 1;
        !          3316:       if (input_redirected ())
        !          3317:        value = END_OF_SAVED_INPUT;
        !          3318:       else if (do_pending_expansions ())
        !          3319:        /* this will set yychar for us */
        !          3320:        return yychar;
        !          3321:       else
        !          3322:        value = ENDFILE;
        !          3323:       break;
        !          3324: 
        !          3325:     case '$':
        !          3326:       if (dollars_in_ident)
        !          3327:        {
        !          3328:          dollar_seen = 1;
        !          3329:          goto letter;
        !          3330:        }
        !          3331:       value = '$';
        !          3332:       goto done;
        !          3333: 
        !          3334:     case 'L':
        !          3335:       /* Capital L may start a wide-string or wide-character constant.  */
        !          3336:       {
        !          3337:        register int c = getch ();
        !          3338:        if (c == '\'')
        !          3339:          {
        !          3340:            wide_flag = 1;
        !          3341:            goto char_constant;
        !          3342:          }
        !          3343:        if (c == '"')
        !          3344:          {
        !          3345:            wide_flag = 1;
        !          3346:            goto string_constant;
        !          3347:          }
        !          3348:        put_back (c);
        !          3349:       }
        !          3350: 
        !          3351:     case 'A':  case 'B':  case 'C':  case 'D':  case 'E':
        !          3352:     case 'F':  case 'G':  case 'H':  case 'I':  case 'J':
        !          3353:     case 'K':            case 'M':  case 'N':  case 'O':
        !          3354:     case 'P':  case 'Q':  case 'R':  case 'S':  case 'T':
        !          3355:     case 'U':  case 'V':  case 'W':  case 'X':  case 'Y':
        !          3356:     case 'Z':
        !          3357:     case 'a':  case 'b':  case 'c':  case 'd':  case 'e':
        !          3358:     case 'f':  case 'g':  case 'h':  case 'i':  case 'j':
        !          3359:     case 'k':  case 'l':  case 'm':  case 'n':  case 'o':
        !          3360:     case 'p':  case 'q':  case 'r':  case 's':  case 't':
        !          3361:     case 'u':  case 'v':  case 'w':  case 'x':  case 'y':
        !          3362:     case 'z':
        !          3363:     case '_':
        !          3364:     letter:
        !          3365:       {
        !          3366:        register char *p;
        !          3367: 
        !          3368:        p = token_buffer;
        !          3369:        if (input == 0)
        !          3370:          {
        !          3371:            /* We know that `token_buffer' can hold at least on char,
        !          3372:               so we install C immediately.
        !          3373:               We may have to read the value in `putback_char', so call
        !          3374:               `getch' once.  */
        !          3375:            *p++ = c;
        !          3376:            c = getch ();
        !          3377: 
        !          3378:            /* Make this run fast.  We know that we are reading straight
        !          3379:               from FINPUT in this case (since identifiers cannot straddle
        !          3380:               input sources.  */
        !          3381:            while (isalnum (c) || (c == '_') || c == '$')
        !          3382:              {
        !          3383:                if (c == '$' && ! dollars_in_ident)
        !          3384:                  break;
        !          3385:                if (p >= token_buffer + maxtoken)
        !          3386:                  p = extend_token_buffer (p);
        !          3387: 
        !          3388:                *p++ = c;
        !          3389:                c = getc (finput);
        !          3390:              }
        !          3391:          }
        !          3392:        else
        !          3393:          {
        !          3394:            /* We know that `token_buffer' can hold at least on char,
        !          3395:               so we install C immediately.  */
        !          3396:            *p++ = c;
        !          3397:            c = getch ();
        !          3398: 
        !          3399:            while (isalnum (c) || (c == '_') || c == '$')
        !          3400:              {
        !          3401:                if (c == '$' && ! dollars_in_ident)
        !          3402:                  break;
        !          3403:                if (p >= token_buffer + maxtoken)
        !          3404:                  p = extend_token_buffer (p);
        !          3405: 
        !          3406:                *p++ = c;
        !          3407:                c = getch ();
        !          3408:              }
        !          3409:          }
        !          3410: 
        !          3411:        *p = 0;
        !          3412:        nextchar = c;
        !          3413: 
        !          3414:        value = IDENTIFIER;
        !          3415:        yylval.itype = 0;
        !          3416: 
        !          3417:       /* Try to recognize a keyword.  Uses minimum-perfect hash function */
        !          3418: 
        !          3419:        {
        !          3420:          register struct resword *ptr;
        !          3421: 
        !          3422:          if (ptr = is_reserved_word (token_buffer, p - token_buffer))
        !          3423:            {
        !          3424:              if (ptr->rid)
        !          3425:                {
        !          3426:                  tree old_ttype = ridpointers[(int) ptr->rid];
        !          3427: 
        !          3428:                  /* If this provides a type for us, then revert lexical
        !          3429:                     state to standard state.  */
        !          3430:                  if (TREE_CODE (old_ttype) == IDENTIFIER_NODE
        !          3431:                      && IDENTIFIER_GLOBAL_VALUE (old_ttype) != 0
        !          3432:                      && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (old_ttype)) == TYPE_DECL)
        !          3433:                    looking_for_typename = 0;
        !          3434:                  else if (ptr->token == AGGR || ptr->token == ENUM)
        !          3435:                    looking_for_typename = 1;
        !          3436: 
        !          3437:                  /* Check if this is a language-type declaration.
        !          3438:                     Just glimpse the next non-white character.  */
        !          3439:                  nextchar = skip_white_space (nextchar);
        !          3440:                  if (nextchar == '"')
        !          3441:                    {
        !          3442:                      /* We are looking at a string.  Complain
        !          3443:                         if the token before the string is no `extern'.
        !          3444:                         
        !          3445:                         Could cheat some memory by placing this string
        !          3446:                         on the temporary_, instead of the saveable_
        !          3447:                         obstack.  */
        !          3448: 
        !          3449:                      if (ptr->rid != RID_EXTERN)
        !          3450:                        error ("invalid modifier `%s' for language string",
        !          3451:                               ptr->name);
        !          3452:                      real_yylex ();
        !          3453:                      value = EXTERN_LANG_STRING;
        !          3454:                      yylval.ttype = get_identifier (TREE_STRING_POINTER (yylval.ttype));
        !          3455:                      break;
        !          3456:                    }
        !          3457:                  if (ptr->token == VISSPEC)
        !          3458:                    {
        !          3459:                      switch (ptr->rid)
        !          3460:                        {
        !          3461:                        case RID_PUBLIC:
        !          3462:                          yylval.itype = access_public;
        !          3463:                          break;
        !          3464:                        case RID_PRIVATE:
        !          3465:                          yylval.itype = access_private;
        !          3466:                          break;
        !          3467:                        case RID_PROTECTED:
        !          3468:                          yylval.itype = access_protected;
        !          3469:                          break;
        !          3470:                        default:
        !          3471:                          my_friendly_abort (63);
        !          3472:                        }
        !          3473:                    }
        !          3474:                  else
        !          3475:                    yylval.ttype = old_ttype;
        !          3476:                }
        !          3477:              value = (int) ptr->token;
        !          3478:            }
        !          3479:        }
        !          3480: 
        !          3481:        /* If we did not find a keyword, look for an identifier
        !          3482:           (or a typename).  */
        !          3483: 
        !          3484:        if (strcmp ("catch", token_buffer) == 0
        !          3485:            || strcmp ("throw", token_buffer) == 0
        !          3486:            || strcmp ("try", token_buffer) == 0)
        !          3487:          {
        !          3488:            static int did_warn = 0;
        !          3489:            if (! did_warn  && ! flag_handle_exceptions)
        !          3490:              {
        !          3491:                pedwarn ("`catch', `throw', and `try' are all C++ reserved words");
        !          3492:                did_warn = 1;
        !          3493:              }
        !          3494:          }
        !          3495: 
        !          3496:        if (value == IDENTIFIER || value == TYPESPEC)
        !          3497:          GNU_xref_ref (current_function_decl, token_buffer);
        !          3498: 
        !          3499:        if (value == IDENTIFIER)
        !          3500:          {
        !          3501:            register tree tmp = get_identifier (token_buffer);
        !          3502: 
        !          3503: #if !defined(VMS) && defined(JOINER)
        !          3504:            /* Make sure that user does not collide with our internal
        !          3505:               naming scheme.  */
        !          3506:            if (JOINER == '$'
        !          3507:                && dollar_seen
        !          3508:                && (THIS_NAME_P (tmp)
        !          3509:                    || VPTR_NAME_P (tmp)
        !          3510:                    || DESTRUCTOR_NAME_P (tmp)
        !          3511:                    || VTABLE_NAME_P (tmp)
        !          3512:                    || TEMP_NAME_P (tmp)
        !          3513:                    || ANON_AGGRNAME_P (tmp)
        !          3514:                    || ANON_PARMNAME_P (tmp)))
        !          3515:              warning ("identifier name `%s' conflicts with GNU C++ internal naming strategy",
        !          3516:                       token_buffer);
        !          3517: #endif
        !          3518: 
        !          3519:            yylval.ttype = tmp;
        !          3520: 
        !          3521:            /* A user-invisible read-only initialized variable
        !          3522:               should be replaced by its value.  We only handle strings
        !          3523:               since that's the only case used in C (and C++).  */
        !          3524:            /* Note we go right after the local value for the identifier
        !          3525:               (e.g., __FUNCTION__ or __PRETTY_FUNCTION__).  We used to
        !          3526:               call lookup_name, but that could result in an error about
        !          3527:               ambiguities.  */
        !          3528:            tmp = IDENTIFIER_LOCAL_VALUE (yylval.ttype);
        !          3529:            if (tmp != NULL_TREE
        !          3530:                && TREE_CODE (tmp) == VAR_DECL
        !          3531:                && DECL_IGNORED_P (tmp)
        !          3532:                && TREE_READONLY (tmp)
        !          3533:                && DECL_INITIAL (tmp) != NULL_TREE
        !          3534:                && TREE_CODE (DECL_INITIAL (tmp)) == STRING_CST)
        !          3535:              {
        !          3536:                yylval.ttype = DECL_INITIAL (tmp);
        !          3537:                value = STRING;
        !          3538:              }
        !          3539:          }
        !          3540:        if (value == NEW && ! global_bindings_p ())
        !          3541:          {
        !          3542:            value = NEW;
        !          3543:            goto done;
        !          3544:          }
        !          3545:       }
        !          3546:       break;
        !          3547: 
        !          3548:     case '.':
        !          3549:       {
        !          3550:        register int c1 = getch ();
        !          3551:        token_buffer[0] = c;
        !          3552:        token_buffer[1] = c1;
        !          3553:        if (c1 == '*')
        !          3554:          {
        !          3555:            value = DOT_STAR;
        !          3556:            token_buffer[2] = 0;
        !          3557:            goto done;
        !          3558:          }
        !          3559:        if (c1 == '.')
        !          3560:          {
        !          3561:            c1 = getch ();
        !          3562:            if (c1 == '.')
        !          3563:              {
        !          3564:                token_buffer[2] = c1;
        !          3565:                token_buffer[3] = 0;
        !          3566:                value = ELLIPSIS;
        !          3567:                goto done;
        !          3568:              }
        !          3569:            error ("parse error at `..'");
        !          3570:          }
        !          3571:        if (isdigit (c1))
        !          3572:          {
        !          3573:            put_back (c1);
        !          3574:            goto resume_numerical_scan;
        !          3575:          }
        !          3576:        nextchar = c1;
        !          3577:        value = '.';
        !          3578:        token_buffer[1] = 0;
        !          3579:        goto done;
        !          3580:       }
        !          3581:     case '0':  case '1':
        !          3582:        /* Optimize for most frequent case.  */
        !          3583:       {
        !          3584:        register int c1 = getch ();
        !          3585:        if (! isalnum (c1) && c1 != '.')
        !          3586:          {
        !          3587:            /* Terminate string.  */
        !          3588:            token_buffer[0] = c;
        !          3589:            token_buffer[1] = 0;
        !          3590:            if (c == '0')
        !          3591:              yylval.ttype = integer_zero_node;
        !          3592:            else
        !          3593:              yylval.ttype = integer_one_node;
        !          3594:            nextchar = c1;
        !          3595:            value = CONSTANT;
        !          3596:            goto done;
        !          3597:          }
        !          3598:        put_back (c1);
        !          3599:       }
        !          3600:       /* fall through... */
        !          3601:                          case '2':  case '3':  case '4':
        !          3602:     case '5':  case '6':  case '7':  case '8':  case '9':
        !          3603:     resume_numerical_scan:
        !          3604:       {
        !          3605:        register char *p;
        !          3606:        int base = 10;
        !          3607:        int count = 0;
        !          3608:        int largest_digit = 0;
        !          3609:        int numdigits = 0;
        !          3610:        /* for multi-precision arithmetic,
        !          3611:           we actually store only HOST_BITS_PER_CHAR bits in each part.
        !          3612:           The number of parts is chosen so as to be sufficient to hold
        !          3613:           the enough bits to fit into the two HOST_WIDE_INTs that contain
        !          3614:           the integer value (this is always at least as many bits as are
        !          3615:           in a target `long long' value, but may be wider).  */
        !          3616: #define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2 + 2)
        !          3617:        int parts[TOTAL_PARTS];
        !          3618:        int overflow = 0;
        !          3619: 
        !          3620:        enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag
        !          3621:          = NOT_FLOAT;
        !          3622: 
        !          3623:        p = token_buffer;
        !          3624:        *p++ = c;
        !          3625: 
        !          3626:        for (count = 0; count < TOTAL_PARTS; count++)
        !          3627:          parts[count] = 0;
        !          3628: 
        !          3629:        if (c == '0')
        !          3630:          {
        !          3631:            *p++ = (c = getch ());
        !          3632:            if ((c == 'x') || (c == 'X'))
        !          3633:              {
        !          3634:                base = 16;
        !          3635:                *p++ = (c = getch ());
        !          3636:              }
        !          3637:            /* Leading 0 forces octal unless the 0 is the only digit.  */
        !          3638:            else if (c >= '0' && c <= '9')
        !          3639:              {
        !          3640:                base = 8;
        !          3641:                numdigits++;
        !          3642:              }
        !          3643:            else
        !          3644:              numdigits++;
        !          3645:          }
        !          3646: 
        !          3647:        /* Read all the digits-and-decimal-points.  */
        !          3648: 
        !          3649:        while (c == '.'
        !          3650:               || (isalnum (c) && (c != 'l') && (c != 'L')
        !          3651:                   && (c != 'u') && (c != 'U')
        !          3652:                   && (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F')))))
        !          3653:          {
        !          3654:            if (c == '.')
        !          3655:              {
        !          3656:                if (base == 16)
        !          3657:                  error ("floating constant may not be in radix 16");
        !          3658:                if (floatflag == AFTER_POINT)
        !          3659:                  {
        !          3660:                    error ("malformed floating constant");
        !          3661:                    floatflag = TOO_MANY_POINTS;
        !          3662:                  }
        !          3663:                else
        !          3664:                  floatflag = AFTER_POINT;
        !          3665: 
        !          3666:                base = 10;
        !          3667:                *p++ = c = getch ();
        !          3668:                /* Accept '.' as the start of a floating-point number
        !          3669:                   only when it is followed by a digit.
        !          3670:                   Otherwise, unread the following non-digit
        !          3671:                   and use the '.' as a structural token.  */
        !          3672:                if (p == token_buffer + 2 && !isdigit (c))
        !          3673:                  {
        !          3674:                    if (c == '.')
        !          3675:                      {
        !          3676:                        c = getch ();
        !          3677:                        if (c == '.')
        !          3678:                          {
        !          3679:                            *p++ = '.';
        !          3680:                            *p = '\0';
        !          3681:                            value = ELLIPSIS;
        !          3682:                            goto done;
        !          3683:                          }
        !          3684:                        error ("parse error at `..'");
        !          3685:                      }
        !          3686:                    nextchar = c;
        !          3687:                    token_buffer[1] = '\0';
        !          3688:                    value = '.';
        !          3689:                    goto done;
        !          3690:                  }
        !          3691:              }
        !          3692:            else
        !          3693:              {
        !          3694:                /* It is not a decimal point.
        !          3695:                   It should be a digit (perhaps a hex digit).  */
        !          3696: 
        !          3697:                if (isdigit (c))
        !          3698:                  {
        !          3699:                    c = c - '0';
        !          3700:                  }
        !          3701:                else if (base <= 10)
        !          3702:                  {
        !          3703:                    if (c == 'e' || c == 'E')
        !          3704:                      {
        !          3705:                        base = 10;
        !          3706:                        floatflag = AFTER_POINT;
        !          3707:                        break;   /* start of exponent */
        !          3708:                      }
        !          3709:                    error ("nondigits in number and not hexadecimal");
        !          3710:                    c = 0;
        !          3711:                  }
        !          3712:                else if (c >= 'a')
        !          3713:                  {
        !          3714:                    c = c - 'a' + 10;
        !          3715:                  }
        !          3716:                else
        !          3717:                  {
        !          3718:                    c = c - 'A' + 10;
        !          3719:                  }
        !          3720:                if (c >= largest_digit)
        !          3721:                  largest_digit = c;
        !          3722:                numdigits++;
        !          3723: 
        !          3724:                for (count = 0; count < TOTAL_PARTS; count++)
        !          3725:                  {
        !          3726:                    parts[count] *= base;
        !          3727:                    if (count)
        !          3728:                      {
        !          3729:                        parts[count]
        !          3730:                          += (parts[count-1] >> HOST_BITS_PER_CHAR);
        !          3731:                        parts[count-1]
        !          3732:                          &= (1 << HOST_BITS_PER_CHAR) - 1;
        !          3733:                      }
        !          3734:                    else
        !          3735:                      parts[0] += c;
        !          3736:                  }
        !          3737: 
        !          3738:                /* If the extra highest-order part ever gets anything in it,
        !          3739:                   the number is certainly too big.  */
        !          3740:                if (parts[TOTAL_PARTS - 1] != 0)
        !          3741:                  overflow = 1;
        !          3742: 
        !          3743:                if (p >= token_buffer + maxtoken - 3)
        !          3744:                  p = extend_token_buffer (p);
        !          3745:                *p++ = (c = getch ());
        !          3746:              }
        !          3747:          }
        !          3748: 
        !          3749:        if (numdigits == 0)
        !          3750:          error ("numeric constant with no digits");
        !          3751: 
        !          3752:        if (largest_digit >= base)
        !          3753:          error ("numeric constant contains digits beyond the radix");
        !          3754: 
        !          3755:        /* Remove terminating char from the token buffer and delimit the string */
        !          3756:        *--p = 0;
        !          3757: 
        !          3758:        if (floatflag != NOT_FLOAT)
        !          3759:          {
        !          3760:            tree type = double_type_node;
        !          3761:            char f_seen = 0;
        !          3762:            char l_seen = 0;
        !          3763:            int garbage_chars = 0;
        !          3764:            REAL_VALUE_TYPE value;
        !          3765:            jmp_buf handler;
        !          3766: 
        !          3767:            /* Read explicit exponent if any, and put it in tokenbuf.  */
        !          3768: 
        !          3769:            if ((c == 'e') || (c == 'E'))
        !          3770:              {
        !          3771:                if (p >= token_buffer + maxtoken - 3)
        !          3772:                  p = extend_token_buffer (p);
        !          3773:                *p++ = c;
        !          3774:                c = getch ();
        !          3775:                if ((c == '+') || (c == '-'))
        !          3776:                  {
        !          3777:                    *p++ = c;
        !          3778:                    c = getch ();
        !          3779:                  }
        !          3780:                if (! isdigit (c))
        !          3781:                  error ("floating constant exponent has no digits");
        !          3782:                while (isdigit (c))
        !          3783:                  {
        !          3784:                    if (p >= token_buffer + maxtoken - 3)
        !          3785:                      p = extend_token_buffer (p);
        !          3786:                    *p++ = c;
        !          3787:                    c = getch ();
        !          3788:                  }
        !          3789:              }
        !          3790: 
        !          3791:            *p = 0;
        !          3792:            errno = 0;
        !          3793: 
        !          3794:            /* Convert string to a double, checking for overflow.  */
        !          3795:            if (setjmp (handler))
        !          3796:              {
        !          3797:                error ("floating constant out of range");
        !          3798:                value = dconst0;
        !          3799:              }
        !          3800:            else
        !          3801:              {
        !          3802:                set_float_handler (handler);
        !          3803:                /*  The second argument, machine_mode, of REAL_VALUE_ATOF
        !          3804:                    tells the desired precision of the binary result of
        !          3805:                    decimal-to-binary conversion. */
        !          3806: 
        !          3807:                /* Read the suffixes to choose a data type.  */
        !          3808:                switch (c)
        !          3809:                  {
        !          3810:                  case 'f': case 'F':
        !          3811:                    type = float_type_node;
        !          3812:                    value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type));
        !          3813:                    garbage_chars = -1;
        !          3814:                    break;
        !          3815: 
        !          3816:                  case 'l': case 'L':
        !          3817:                    type = long_double_type_node;
        !          3818:                    value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type));
        !          3819:                    garbage_chars = -1;
        !          3820:                    break;
        !          3821: 
        !          3822:                  default:
        !          3823:                    value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type));
        !          3824:                  }
        !          3825:                set_float_handler (NULL_PTR);
        !          3826:              }
        !          3827:            if (pedantic
        !          3828:                && (REAL_VALUE_ISINF (value)
        !          3829: #ifdef ERANGE
        !          3830:                    || (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
        !          3831:                        && errno == ERANGE
        !          3832:                        /* ERANGE is also reported for underflow, so test the
        !          3833:                           value to distinguish overflow from that.  */
        !          3834:                        && (REAL_VALUES_LESS (dconst1, value)
        !          3835:                            || REAL_VALUES_LESS (value, dconstm1)))
        !          3836: #endif
        !          3837:                    ))
        !          3838:              {
        !          3839:                pedwarn ("floating point number exceeds range of `%s'",
        !          3840:                         IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
        !          3841:              }
        !          3842:            /* Note: garbage_chars is -1 if first char is *not* garbage.  */
        !          3843:            while (isalnum (c))
        !          3844:              {
        !          3845:                if (c == 'f' || c == 'F')
        !          3846:                  {
        !          3847:                    if (f_seen)
        !          3848:                      error ("two `f's in floating constant");
        !          3849:                    f_seen = 1;
        !          3850:                  }
        !          3851:                if (c == 'l' || c == 'L')
        !          3852:                  {
        !          3853:                    if (l_seen)
        !          3854:                      error ("two `l's in floating constant");
        !          3855:                    l_seen = 1;
        !          3856:                  }
        !          3857:                if (p >= token_buffer + maxtoken - 3)
        !          3858:                  p = extend_token_buffer (p);
        !          3859:                *p++ = c;
        !          3860:                c = getch ();
        !          3861:                garbage_chars++;
        !          3862:              }
        !          3863: 
        !          3864:            if (garbage_chars > 0)
        !          3865:              error ("garbage at end of number");
        !          3866: 
        !          3867:            /* Create a node with determined type and value.  */
        !          3868:            yylval.ttype = build_real (type, value);
        !          3869: 
        !          3870:            put_back (c);
        !          3871:            *p = 0;
        !          3872:          }
        !          3873:        else
        !          3874:          {
        !          3875:            tree type;
        !          3876:            HOST_WIDE_INT high, low;
        !          3877:            int spec_unsigned = 0;
        !          3878:            int spec_long = 0;
        !          3879:            int spec_long_long = 0;
        !          3880:            int bytes, warn;
        !          3881: 
        !          3882:            while (1)
        !          3883:              {
        !          3884:                if (c == 'u' || c == 'U')
        !          3885:                  {
        !          3886:                    if (spec_unsigned)
        !          3887:                      error ("two `u's in integer constant");
        !          3888:                    spec_unsigned = 1;
        !          3889:                  }
        !          3890:                else if (c == 'l' || c == 'L')
        !          3891:                  {
        !          3892:                    if (spec_long)
        !          3893:                      {
        !          3894:                        if (spec_long_long)
        !          3895:                          error ("three `l's in integer constant");
        !          3896:                        else if (pedantic)
        !          3897:                          pedwarn ("ANSI C++ forbids long long integer constants");
        !          3898:                        spec_long_long = 1;
        !          3899:                      }
        !          3900:                    spec_long = 1;
        !          3901:                  }
        !          3902:                else
        !          3903:                  {
        !          3904:                    if (isalnum (c))
        !          3905:                      {
        !          3906:                        error ("garbage at end of number");
        !          3907:                        while (isalnum (c))
        !          3908:                          {
        !          3909:                            if (p >= token_buffer + maxtoken - 3)
        !          3910:                              p = extend_token_buffer (p);
        !          3911:                            *p++ = c;
        !          3912:                            c = getch ();
        !          3913:                          }
        !          3914:                      }
        !          3915:                    break;
        !          3916:                  }
        !          3917:                if (p >= token_buffer + maxtoken - 3)
        !          3918:                  p = extend_token_buffer (p);
        !          3919:                *p++ = c;
        !          3920:                c = getch ();
        !          3921:              }
        !          3922: 
        !          3923:            put_back (c);
        !          3924: 
        !          3925:            /* If the constant is not long long and it won't fit in an
        !          3926:               unsigned long, or if the constant is long long and won't fit
        !          3927:               in an unsigned long long, then warn that the constant is out
        !          3928:               of range.  */
        !          3929: 
        !          3930:            /* ??? This assumes that long long and long integer types are
        !          3931:               a multiple of 8 bits.  This better than the original code
        !          3932:               though which assumed that long was exactly 32 bits and long
        !          3933:               long was exactly 64 bits.  */
        !          3934: 
        !          3935:            if (spec_long_long)
        !          3936:              bytes = TYPE_PRECISION (long_long_integer_type_node) / 8;
        !          3937:            else
        !          3938:              bytes = TYPE_PRECISION (long_integer_type_node) / 8;
        !          3939: 
        !          3940:            warn = overflow;
        !          3941:            for (i = bytes; i < TOTAL_PARTS; i++)
        !          3942:              if (parts[i])
        !          3943:                warn = 1;
        !          3944:            if (warn)
        !          3945:              pedwarn ("integer constant out of range");
        !          3946: 
        !          3947:            /* This is simplified by the fact that our constant
        !          3948:               is always positive.  */
        !          3949:            high = low = 0;
        !          3950: 
        !          3951:            for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; i++)
        !          3952:              {
        !          3953:                high |= ((HOST_WIDE_INT) parts[i + (HOST_BITS_PER_WIDE_INT
        !          3954:                                                    / HOST_BITS_PER_CHAR)]
        !          3955:                         << (i * HOST_BITS_PER_CHAR));
        !          3956:                low |= (HOST_WIDE_INT) parts[i] << (i * HOST_BITS_PER_CHAR);
        !          3957:              }
        !          3958:            
        !          3959:            
        !          3960:            yylval.ttype = build_int_2 (low, high);
        !          3961:            TREE_TYPE (yylval.ttype) = long_long_unsigned_type_node;
        !          3962: 
        !          3963: #if 0
        !          3964:            /* Find the first allowable type that the value fits in.  */
        !          3965:            type = 0;
        !          3966:            for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]);
        !          3967:                 i++)
        !          3968:              if (!(spec_long && !type_sequence[i].long_flag)
        !          3969:                  && !(spec_long_long && !type_sequence[i].long_long_flag)
        !          3970:                  && !(spec_unsigned && !type_sequence[i].unsigned_flag)
        !          3971:                  /* A hex or octal constant traditionally is unsigned.  */
        !          3972:                  && !(base != 10 && flag_traditional
        !          3973:                       && !type_sequence[i].unsigned_flag)
        !          3974:                  /* A decimal constant can't be unsigned int
        !          3975:                     unless explicitly specified.  */
        !          3976:                  && !(base == 10 && !spec_unsigned
        !          3977:                       && *type_sequence[i].node_var == unsigned_type_node))
        !          3978:                if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var))
        !          3979:                  {
        !          3980:                    type = *type_sequence[i].node_var;
        !          3981:                    break;
        !          3982:                  }
        !          3983:            if (flag_traditional && type == long_unsigned_type_node
        !          3984:                && !spec_unsigned)
        !          3985:              type = long_integer_type_node;
        !          3986:              
        !          3987:            if (type == 0)
        !          3988:              {
        !          3989:                type = long_long_integer_type_node;
        !          3990:                warning ("integer constant out of range");
        !          3991:              }
        !          3992: 
        !          3993:            /* Warn about some cases where the type of a given constant
        !          3994:               changes from traditional C to ANSI C.  */
        !          3995:            if (warn_traditional)
        !          3996:              {
        !          3997:                tree other_type = 0;
        !          3998: 
        !          3999:                /* This computation is the same as the previous one
        !          4000:                   except that flag_traditional is used backwards.  */
        !          4001:                for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]);
        !          4002:                     i++)
        !          4003:                  if (!(spec_long && !type_sequence[i].long_flag)
        !          4004:                      && !(spec_long_long && !type_sequence[i].long_long_flag)
        !          4005:                      && !(spec_unsigned && !type_sequence[i].unsigned_flag)
        !          4006:                      /* A hex or octal constant traditionally is unsigned.  */
        !          4007:                      && !(base != 10 && !flag_traditional
        !          4008:                           && !type_sequence[i].unsigned_flag)
        !          4009:                      /* A decimal constant can't be unsigned int
        !          4010:                         unless explicitly specified.  */
        !          4011:                      && !(base == 10 && !spec_unsigned
        !          4012:                           && *type_sequence[i].node_var == unsigned_type_node))
        !          4013:                    if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var))
        !          4014:                      {
        !          4015:                        other_type = *type_sequence[i].node_var;
        !          4016:                        break;
        !          4017:                      }
        !          4018:                if (!flag_traditional && type == long_unsigned_type_node
        !          4019:                    && !spec_unsigned)
        !          4020:                  type = long_integer_type_node;
        !          4021:              
        !          4022:                if (other_type != 0 && other_type != type)
        !          4023:                  {
        !          4024:                    if (flag_traditional)
        !          4025:                      warning ("type of integer constant would be different without -traditional");
        !          4026:                    else
        !          4027:                      warning ("type of integer constant would be different with -traditional");
        !          4028:                  }
        !          4029:              }
        !          4030: 
        !          4031: #else /* 1 */
        !          4032:            if (!spec_long && !spec_unsigned
        !          4033:                && !(flag_traditional && base != 10)
        !          4034:                && int_fits_type_p (yylval.ttype, integer_type_node))
        !          4035:              {
        !          4036: #if 0
        !          4037:                if (warn_traditional && base != 10)
        !          4038:                  warning ("small nondecimal constant becomes signed in ANSI C++");
        !          4039: #endif
        !          4040:                type = integer_type_node;
        !          4041:              }
        !          4042:            else if (!spec_long && (base != 10 || spec_unsigned)
        !          4043:                     && int_fits_type_p (yylval.ttype, unsigned_type_node))
        !          4044:              {
        !          4045:                /* Nondecimal constants try unsigned even in traditional C.  */
        !          4046:                type = unsigned_type_node;
        !          4047:              }
        !          4048: 
        !          4049:            else if (!spec_unsigned && !spec_long_long
        !          4050:                     && int_fits_type_p (yylval.ttype, long_integer_type_node))
        !          4051:              type = long_integer_type_node;
        !          4052: 
        !          4053:            else if (! spec_long_long
        !          4054:                     && int_fits_type_p (yylval.ttype,
        !          4055:                                         long_unsigned_type_node))
        !          4056:              {
        !          4057: #if 0
        !          4058:                if (warn_traditional && !spec_unsigned)
        !          4059:                  warning ("large integer constant becomes unsigned in ANSI C++");
        !          4060: #endif
        !          4061:                if (flag_traditional && !spec_unsigned)
        !          4062:                  type = long_integer_type_node;
        !          4063:                else
        !          4064:                  type = long_unsigned_type_node;
        !          4065:              }
        !          4066: 
        !          4067:            else if (! spec_unsigned
        !          4068:                     /* Verify value does not overflow into sign bit.  */
        !          4069:                     && TREE_INT_CST_HIGH (yylval.ttype) >= 0
        !          4070:                     && int_fits_type_p (yylval.ttype,
        !          4071:                                         long_long_integer_type_node))
        !          4072:              type = long_long_integer_type_node;
        !          4073: 
        !          4074:            else if (int_fits_type_p (yylval.ttype,
        !          4075:                                      long_long_unsigned_type_node))
        !          4076:              {
        !          4077: #if 0
        !          4078:                if (warn_traditional && !spec_unsigned)
        !          4079:                  warning ("large nondecimal constant is unsigned in ANSI C++");
        !          4080: #endif
        !          4081: 
        !          4082:                if (flag_traditional && !spec_unsigned)
        !          4083:                  type = long_long_integer_type_node;
        !          4084:                else
        !          4085:                  type = long_long_unsigned_type_node;
        !          4086:              }
        !          4087: 
        !          4088:            else
        !          4089:              {
        !          4090:                type = long_long_integer_type_node;
        !          4091:                warning ("integer constant out of range");
        !          4092: 
        !          4093:                if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type))
        !          4094:                  warning ("decimal integer constant is so large that it is unsigned");
        !          4095:              }
        !          4096: #endif
        !          4097: 
        !          4098:            TREE_TYPE (yylval.ttype) = type;
        !          4099:            *p = 0;
        !          4100:          }
        !          4101: 
        !          4102:        value = CONSTANT; break;
        !          4103:       }
        !          4104: 
        !          4105:     case '\'':
        !          4106:     char_constant:
        !          4107:       {
        !          4108:        register int result = 0;
        !          4109:        register int num_chars = 0;
        !          4110:        unsigned width = TYPE_PRECISION (char_type_node);
        !          4111:        int max_chars;
        !          4112: 
        !          4113:        if (wide_flag)
        !          4114:          {
        !          4115:            width = WCHAR_TYPE_SIZE;
        !          4116: #ifdef MULTIBYTE_CHARS
        !          4117:            max_chars = MB_CUR_MAX;
        !          4118: #else
        !          4119:            max_chars = 1;
        !          4120: #endif
        !          4121:          }
        !          4122:        else
        !          4123:          max_chars = TYPE_PRECISION (integer_type_node) / width;
        !          4124: 
        !          4125:        while (1)
        !          4126:          {
        !          4127:          tryagain:
        !          4128: 
        !          4129:            c = getch ();
        !          4130: 
        !          4131:            if (c == '\'' || c == EOF)
        !          4132:              break;
        !          4133: 
        !          4134:            if (c == '\\')
        !          4135:              {
        !          4136:                int ignore = 0;
        !          4137:                c = readescape (&ignore);
        !          4138:                if (ignore)
        !          4139:                  goto tryagain;
        !          4140:                if (width < HOST_BITS_PER_INT
        !          4141:                    && (unsigned) c >= (1 << width))
        !          4142:                  pedwarn ("escape sequence out of range for character");
        !          4143: #ifdef MAP_CHARACTER
        !          4144:                if (isprint (c))
        !          4145:                  c = MAP_CHARACTER (c);
        !          4146: #endif
        !          4147:              }
        !          4148:            else if (c == '\n')
        !          4149:              {
        !          4150:                if (pedantic)
        !          4151:                  pedwarn ("ANSI C++ forbids newline in character constant");
        !          4152:                lineno++;
        !          4153:              }
        !          4154: #ifdef MAP_CHARACTER
        !          4155:            else
        !          4156:              c = MAP_CHARACTER (c);
        !          4157: #endif
        !          4158: 
        !          4159:            num_chars++;
        !          4160:            if (num_chars > maxtoken - 4)
        !          4161:              extend_token_buffer (token_buffer);
        !          4162: 
        !          4163:            token_buffer[num_chars] = c;
        !          4164: 
        !          4165:            /* Merge character into result; ignore excess chars.  */
        !          4166:            if (num_chars < max_chars + 1)
        !          4167:              {
        !          4168:                if (width < HOST_BITS_PER_INT)
        !          4169:                  result = (result << width) | (c & ((1 << width) - 1));
        !          4170:                else
        !          4171:                  result = c;
        !          4172:              }
        !          4173:          }
        !          4174: 
        !          4175:        token_buffer[num_chars + 1] = '\'';
        !          4176:        token_buffer[num_chars + 2] = 0;
        !          4177: 
        !          4178:        if (c != '\'')
        !          4179:          error ("malformatted character constant");
        !          4180:        else if (num_chars == 0)
        !          4181:          error ("empty character constant");
        !          4182:        else if (num_chars > max_chars)
        !          4183:          {
        !          4184:            num_chars = max_chars;
        !          4185:            error ("character constant too long");
        !          4186:          }
        !          4187:        else if (num_chars != 1 && ! flag_traditional)
        !          4188:          warning ("multi-character character constant");
        !          4189: 
        !          4190:        /* If char type is signed, sign-extend the constant.  */
        !          4191:        if (! wide_flag)
        !          4192:          {
        !          4193:            int num_bits = num_chars * width;
        !          4194:            if (num_bits == 0)
        !          4195:              /* We already got an error; avoid invalid shift.  */
        !          4196:              yylval.ttype = build_int_2 (0, 0);
        !          4197:            else if (TREE_UNSIGNED (char_type_node)
        !          4198:                     || ((result >> (num_bits - 1)) & 1) == 0)
        !          4199:              yylval.ttype
        !          4200:                = build_int_2 (result & ((unsigned HOST_WIDE_INT) ~0
        !          4201:                                         >> (HOST_BITS_PER_WIDE_INT - num_bits)),
        !          4202:                               0);
        !          4203:            else
        !          4204:              yylval.ttype
        !          4205:                = build_int_2 (result | ~((unsigned HOST_WIDE_INT) ~0
        !          4206:                                          >> (HOST_BITS_PER_WIDE_INT - num_bits)),
        !          4207:                               -1);
        !          4208:            if (num_chars<=1)
        !          4209:              TREE_TYPE (yylval.ttype) = char_type_node;
        !          4210:            else
        !          4211:              TREE_TYPE (yylval.ttype) = integer_type_node;
        !          4212:          }
        !          4213:        else
        !          4214:          {
        !          4215: #ifdef MULTIBYTE_CHARS
        !          4216:            /* Set the initial shift state and convert the next sequence.  */
        !          4217:            result = 0;
        !          4218:            /* In all locales L'\0' is zero and mbtowc will return zero,
        !          4219:               so don't use it.  */
        !          4220:            if (num_chars > 1
        !          4221:                || (num_chars == 1 && token_buffer[1] != '\0'))
        !          4222:              {
        !          4223:                wchar_t wc;
        !          4224:                (void) mbtowc (NULL, NULL, 0);
        !          4225:                if (mbtowc (& wc, token_buffer + 1, num_chars) == num_chars)
        !          4226:                  result = wc;
        !          4227:                else
        !          4228:                  warning ("Ignoring invalid multibyte character");
        !          4229:              }
        !          4230: #endif
        !          4231:            yylval.ttype = build_int_2 (result, 0);
        !          4232:            TREE_TYPE (yylval.ttype) = wchar_type_node;
        !          4233:          }
        !          4234: 
        !          4235:        value = CONSTANT;
        !          4236:        break;
        !          4237:       }
        !          4238: 
        !          4239:     case '"':
        !          4240:     string_constant:
        !          4241:       {
        !          4242:        register char *p;
        !          4243: 
        !          4244:        c = getch ();
        !          4245:        p = token_buffer + 1;
        !          4246: 
        !          4247:        while (c != '"' && c >= 0)
        !          4248:          {
        !          4249:            /* ignore_escape_flag is set for reading the filename in #line.  */
        !          4250:            if (!ignore_escape_flag && c == '\\')
        !          4251:              {
        !          4252:                int ignore = 0;
        !          4253:                c = readescape (&ignore);
        !          4254:                if (ignore)
        !          4255:                  goto skipnewline;
        !          4256:                if (!wide_flag
        !          4257:                    && TYPE_PRECISION (char_type_node) < HOST_BITS_PER_INT
        !          4258:                    && c >= ((unsigned) 1 << TYPE_PRECISION (char_type_node)))
        !          4259:                  pedwarn ("escape sequence out of range for character");
        !          4260:              }
        !          4261:            else if (c == '\n')
        !          4262:              {
        !          4263:                if (pedantic)
        !          4264:                  pedwarn ("ANSI C++ forbids newline in string constant");
        !          4265:                lineno++;
        !          4266:              }
        !          4267: 
        !          4268:            if (p == token_buffer + maxtoken)
        !          4269:              p = extend_token_buffer (p);
        !          4270:            *p++ = c;
        !          4271: 
        !          4272:          skipnewline:
        !          4273:            c = getch ();
        !          4274:            if (c == EOF) {
        !          4275:                error("Unterminated string");
        !          4276:                break;
        !          4277:            }
        !          4278:          }
        !          4279:        *p = 0;
        !          4280: 
        !          4281:        /* We have read the entire constant.
        !          4282:           Construct a STRING_CST for the result.  */
        !          4283: 
        !          4284:        if (wide_flag)
        !          4285:          {
        !          4286:            /* If this is a L"..." wide-string, convert the multibyte string
        !          4287:               to a wide character string.  */
        !          4288:            char *widep = (char *) alloca ((p - token_buffer) * WCHAR_BYTES);
        !          4289:            int len;
        !          4290: 
        !          4291: #ifdef MULTIBYTE_CHARS
        !          4292:            len = mbstowcs ((wchar_t *) widep, token_buffer + 1, p - token_buffer);
        !          4293:            if (len < 0 || len >= (p - token_buffer))
        !          4294:              {
        !          4295:                warning ("Ignoring invalid multibyte string");
        !          4296:                len = 0;
        !          4297:              }
        !          4298:            bzero (widep + (len * WCHAR_BYTES), WCHAR_BYTES);
        !          4299: #else
        !          4300:            {
        !          4301:              union { long l; char c[sizeof (long)]; } u;
        !          4302:              int big_endian;
        !          4303:              char *wp, *cp;
        !          4304: 
        !          4305:              /* Determine whether host is little or big endian.  */
        !          4306:              u.l = 1;
        !          4307:              big_endian = u.c[sizeof (long) - 1];
        !          4308:              wp = widep + (big_endian ? WCHAR_BYTES - 1 : 0);
        !          4309: 
        !          4310:              bzero (widep, (p - token_buffer) * WCHAR_BYTES);
        !          4311:              for (cp = token_buffer + 1; cp < p; cp++)
        !          4312:                *wp = *cp, wp += WCHAR_BYTES;
        !          4313:              len = p - token_buffer - 1;
        !          4314:            }
        !          4315: #endif
        !          4316:            yylval.ttype = build_string ((len + 1) * WCHAR_BYTES, widep);
        !          4317:            TREE_TYPE (yylval.ttype) = wchar_array_type_node;
        !          4318:          }
        !          4319:        else
        !          4320:          {
        !          4321:            yylval.ttype = build_string (p - token_buffer, token_buffer + 1);
        !          4322:            TREE_TYPE (yylval.ttype) = char_array_type_node;
        !          4323:          }
        !          4324: 
        !          4325:        *p++ = '"';
        !          4326:        *p = 0;
        !          4327: 
        !          4328:        value = STRING; break;
        !          4329:       }
        !          4330: 
        !          4331:     case '+':
        !          4332:     case '-':
        !          4333:     case '&':
        !          4334:     case '|':
        !          4335:     case '<':
        !          4336:     case '>':
        !          4337:     case '*':
        !          4338:     case '/':
        !          4339:     case '%':
        !          4340:     case '^':
        !          4341:     case '!':
        !          4342:     case '=':
        !          4343:       {
        !          4344:        register int c1;
        !          4345: 
        !          4346:       combine:
        !          4347: 
        !          4348:        switch (c)
        !          4349:          {
        !          4350:          case '+':
        !          4351:            yylval.code = PLUS_EXPR; break;
        !          4352:          case '-':
        !          4353:            yylval.code = MINUS_EXPR; break;
        !          4354:          case '&':
        !          4355:            yylval.code = BIT_AND_EXPR; break;
        !          4356:          case '|':
        !          4357:            yylval.code = BIT_IOR_EXPR; break;
        !          4358:          case '*':
        !          4359:            yylval.code = MULT_EXPR; break;
        !          4360:          case '/':
        !          4361:            yylval.code = TRUNC_DIV_EXPR; break;
        !          4362:          case '%':
        !          4363:            yylval.code = TRUNC_MOD_EXPR; break;
        !          4364:          case '^':
        !          4365:            yylval.code = BIT_XOR_EXPR; break;
        !          4366:          case LSHIFT:
        !          4367:            yylval.code = LSHIFT_EXPR; break;
        !          4368:          case RSHIFT:
        !          4369:            yylval.code = RSHIFT_EXPR; break;
        !          4370:          case '<':
        !          4371:            yylval.code = LT_EXPR; break;
        !          4372:          case '>':
        !          4373:            yylval.code = GT_EXPR; break;
        !          4374:          }
        !          4375: 
        !          4376:        token_buffer[1] = c1 = getch ();
        !          4377:        token_buffer[2] = 0;
        !          4378: 
        !          4379:        if (c1 == '=')
        !          4380:          {
        !          4381:            switch (c)
        !          4382:              {
        !          4383:              case '<':
        !          4384:                value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done;
        !          4385:              case '>':
        !          4386:                value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done;
        !          4387:              case '!':
        !          4388:                value = EQCOMPARE; yylval.code = NE_EXPR; goto done;
        !          4389:              case '=':
        !          4390:                value = EQCOMPARE; yylval.code = EQ_EXPR; goto done;
        !          4391:              }
        !          4392:            value = ASSIGN; goto done;
        !          4393:          }
        !          4394:        else if (c == c1)
        !          4395:          switch (c)
        !          4396:            {
        !          4397:            case '+':
        !          4398:              value = PLUSPLUS; goto done;
        !          4399:            case '-':
        !          4400:              value = MINUSMINUS; goto done;
        !          4401:            case '&':
        !          4402:              value = ANDAND; goto done;
        !          4403:            case '|':
        !          4404:              value = OROR; goto done;
        !          4405:            case '<':
        !          4406:              c = LSHIFT;
        !          4407:              goto combine;
        !          4408:            case '>':
        !          4409:              c = RSHIFT;
        !          4410:              goto combine;
        !          4411:            }
        !          4412:        else if ((c == '-') && (c1 == '>'))
        !          4413:          {
        !          4414:            nextchar = skip_white_space (getch ());
        !          4415:            if (nextchar == '*')
        !          4416:              {
        !          4417:                nextchar = -1;
        !          4418:                value = POINTSAT_STAR;
        !          4419:              }
        !          4420:            else
        !          4421:              value = POINTSAT;
        !          4422:            goto done;
        !          4423:          }
        !          4424:        else if (c1 == '?' && (c == '<' || c == '>'))
        !          4425:          {
        !          4426:            token_buffer[3] = 0;
        !          4427: 
        !          4428:            c1 = getch ();
        !          4429:            yylval.code = (c == '<' ? MIN_EXPR : MAX_EXPR);
        !          4430:            if (c1 == '=')
        !          4431:              {
        !          4432:                /* <?= or >?= expression.  */
        !          4433:                token_buffer[2] = c1;
        !          4434:                value = ASSIGN;
        !          4435:              }
        !          4436:            else
        !          4437:              {
        !          4438:                value = MIN_MAX;
        !          4439:                nextchar = c1;
        !          4440:              }
        !          4441:            if (flag_ansi)
        !          4442:              pedwarn ("use of `operator %s' is not standard C++",
        !          4443:                       token_buffer);
        !          4444:            goto done;
        !          4445:          }
        !          4446: 
        !          4447:        nextchar = c1;
        !          4448:        token_buffer[1] = 0;
        !          4449: 
        !          4450:        value = c;
        !          4451:        goto done;
        !          4452:       }
        !          4453: 
        !          4454:     case ':':
        !          4455:       c = getch ();
        !          4456:       if (c == ':')
        !          4457:        {
        !          4458:          token_buffer[1] = ':';
        !          4459:          token_buffer[2] = '\0';
        !          4460:          value = SCOPE;
        !          4461:          yylval.itype = 1;
        !          4462:        }
        !          4463:       else
        !          4464:        {
        !          4465:          nextchar = c;
        !          4466:          value = ':';
        !          4467:        }
        !          4468:       break;
        !          4469: 
        !          4470:     case 0:
        !          4471:       /* Don't make yyparse think this is eof.  */
        !          4472:       value = 1;
        !          4473:       break;
        !          4474: 
        !          4475:     case '(':
        !          4476:       /* try, weakly, to handle casts to pointers to functions.  */
        !          4477:       nextchar = skip_white_space (getch ());
        !          4478:       if (nextchar == '*')
        !          4479:        {
        !          4480:          int next_c = skip_white_space (getch ());
        !          4481:          if (next_c == ')')
        !          4482:            {
        !          4483:              nextchar = -1;
        !          4484:              yylval.ttype = build1 (INDIRECT_REF, 0, 0);
        !          4485:              value = PAREN_STAR_PAREN;
        !          4486:            }
        !          4487:          else
        !          4488:            {
        !          4489:              put_back (next_c);
        !          4490:              value = c;
        !          4491:            }
        !          4492:        }
        !          4493:       else if (nextchar == ')')
        !          4494:        {
        !          4495:          nextchar = -1;
        !          4496:          yylval.ttype = NULL_TREE;
        !          4497:          value = LEFT_RIGHT;
        !          4498:        }
        !          4499:       else value = c;
        !          4500:       break;
        !          4501: 
        !          4502:     default:
        !          4503:       value = c;
        !          4504:     }
        !          4505: 
        !          4506: done:
        !          4507: /*  yylloc.last_line = lineno; */
        !          4508: #ifdef GATHER_STATISTICS
        !          4509:   token_count[value] += 1;
        !          4510: #endif
        !          4511: 
        !          4512:   return value;
        !          4513: }
        !          4514: 
        !          4515: typedef enum
        !          4516: {
        !          4517:   d_kind, t_kind, s_kind, r_kind, e_kind, c_kind,
        !          4518:   id_kind, op_id_kind, perm_list_kind, temp_list_kind,
        !          4519:   vec_kind, x_kind, lang_decl, lang_type, all_kinds
        !          4520: } tree_node_kind;
        !          4521: extern int tree_node_counts[];
        !          4522: extern int tree_node_sizes[];
        !          4523: extern char *tree_node_kind_names[];
        !          4524: 
        !          4525: /* Place to save freed lang_decls which were allocated on the
        !          4526:    permanent_obstack.  @@ Not currently used.  */
        !          4527: tree free_lang_decl_chain;
        !          4528: 
        !          4529: tree
        !          4530: build_lang_decl (code, name, type)
        !          4531:      enum tree_code code;
        !          4532:      tree name;
        !          4533:      tree type;
        !          4534: {
        !          4535:   register tree t = build_decl (code, name, type);
        !          4536:   struct obstack *obstack = current_obstack;
        !          4537:   register int i = sizeof (struct lang_decl) / sizeof (int);
        !          4538:   register int *pi;
        !          4539: 
        !          4540:   if (! TREE_PERMANENT (t))
        !          4541:     obstack = saveable_obstack;
        !          4542:   else
        !          4543:     /* Could be that saveable is permanent and current is not.  */
        !          4544:     obstack = &permanent_obstack;
        !          4545: 
        !          4546:   if (free_lang_decl_chain && obstack == &permanent_obstack)
        !          4547:     {
        !          4548:       pi = (int *)free_lang_decl_chain;
        !          4549:       free_lang_decl_chain = TREE_CHAIN (free_lang_decl_chain);
        !          4550:     }
        !          4551:   else
        !          4552:     pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl));
        !          4553: 
        !          4554:   while (i > 0)
        !          4555:     pi[--i] = 0;
        !          4556: 
        !          4557:   DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi;
        !          4558:   LANG_DECL_PERMANENT ((struct lang_decl *) pi)
        !          4559:     = obstack == &permanent_obstack;
        !          4560:   my_friendly_assert (LANG_DECL_PERMANENT ((struct lang_decl *) pi)
        !          4561:          == TREE_PERMANENT  (t), 234);
        !          4562:   DECL_MAIN_VARIANT (t) = t;
        !          4563:   if (current_lang_name == lang_name_cplusplus)
        !          4564:     {
        !          4565:       DECL_LANGUAGE (t) = lang_cplusplus;
        !          4566: #if 0
        !          4567: #ifndef NO_AUTO_OVERLOAD
        !          4568:       if (code == FUNCTION_DECL && name != 0
        !          4569:          && ! (IDENTIFIER_LENGTH (name) == 4
        !          4570:                && IDENTIFIER_POINTER (name)[0] == 'm'
        !          4571:                && strcmp (IDENTIFIER_POINTER (name), "main") == 0)
        !          4572:          && ! (IDENTIFIER_LENGTH (name) > 10
        !          4573:                && IDENTIFIER_POINTER (name)[0] == '_'
        !          4574:                && IDENTIFIER_POINTER (name)[1] == '_'
        !          4575:                && strncmp (IDENTIFIER_POINTER (name)+2, "builtin_", 8) == 0))
        !          4576:        TREE_OVERLOADED (name) = 1;
        !          4577: #endif
        !          4578: #endif
        !          4579:     }
        !          4580:   else if (current_lang_name == lang_name_c)
        !          4581:     DECL_LANGUAGE (t) = lang_c;
        !          4582:   else my_friendly_abort (64);
        !          4583: 
        !          4584: #if 0 /* not yet, should get fixed properly later */
        !          4585:   if (code == TYPE_DECL)
        !          4586:     {
        !          4587:       tree id;
        !          4588:       id = get_identifier (build_overload_name (type, 1, 1));
        !          4589:       DECL_ASSEMBLER_NAME (t) = id;
        !          4590:     }
        !          4591: 
        !          4592: #endif
        !          4593: #ifdef GATHER_STATISTICS
        !          4594:   tree_node_counts[(int)lang_decl] += 1;
        !          4595:   tree_node_sizes[(int)lang_decl] += sizeof(struct lang_decl);
        !          4596: #endif
        !          4597: 
        !          4598:   return t;
        !          4599: }
        !          4600: 
        !          4601: tree
        !          4602: build_lang_field_decl (code, name, type)
        !          4603:      enum tree_code code;
        !          4604:      tree name;
        !          4605:      tree type;
        !          4606: {
        !          4607:   extern struct obstack *current_obstack, *saveable_obstack;
        !          4608:   register tree t = build_decl (code, name, type);
        !          4609:   struct obstack *obstack = current_obstack;
        !          4610:   register int i = sizeof (struct lang_decl_flags) / sizeof (int);
        !          4611:   register int *pi;
        !          4612: #if 0 /* not yet, should get fixed properly later */
        !          4613: 
        !          4614:   if (code == TYPE_DECL)
        !          4615:     {
        !          4616:       tree id;
        !          4617:       id = get_identifier (build_overload_name (type, 1, 1));
        !          4618:       DECL_ASSEMBLER_NAME (t) = id;
        !          4619:     }
        !          4620: #endif
        !          4621: 
        !          4622:   if (! TREE_PERMANENT (t))
        !          4623:     obstack = saveable_obstack;
        !          4624:   else
        !          4625:     my_friendly_assert (obstack == &permanent_obstack, 235);
        !          4626: 
        !          4627:   pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl_flags));
        !          4628:   while (i > 0)
        !          4629:     pi[--i] = 0;
        !          4630: 
        !          4631:   DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi;
        !          4632:   return t;
        !          4633: }
        !          4634: 
        !          4635: void
        !          4636: copy_lang_decl (node)
        !          4637:      tree node;
        !          4638: {
        !          4639:   int size;
        !          4640:   int *pi;
        !          4641: 
        !          4642:   if (TREE_CODE (node) == FIELD_DECL)
        !          4643:     size = sizeof (struct lang_decl_flags);
        !          4644:   else
        !          4645:     size = sizeof (struct lang_decl);
        !          4646:   pi = (int *)obstack_alloc (&permanent_obstack, size);
        !          4647:   bcopy ((char *)DECL_LANG_SPECIFIC (node), (char *)pi, size);
        !          4648:   DECL_LANG_SPECIFIC (node) = (struct lang_decl *)pi;
        !          4649: }
        !          4650: 
        !          4651: tree
        !          4652: make_lang_type (code)
        !          4653:      enum tree_code code;
        !          4654: {
        !          4655:   extern struct obstack *current_obstack, *saveable_obstack;
        !          4656:   register tree t = make_node (code);
        !          4657:   struct obstack *obstack = current_obstack;
        !          4658:   register int i = sizeof (struct lang_type) / sizeof (int);
        !          4659:   register int *pi;
        !          4660: 
        !          4661:   /* Set up some flags that give proper default behavior.  */
        !          4662:   IS_AGGR_TYPE (t) = 1;
        !          4663: 
        !          4664:   if (! TREE_PERMANENT (t))
        !          4665:     obstack = saveable_obstack;
        !          4666:   else
        !          4667:     my_friendly_assert (obstack == &permanent_obstack, 236);
        !          4668: 
        !          4669:   pi = (int *) obstack_alloc (obstack, sizeof (struct lang_type));
        !          4670:   while (i > 0)
        !          4671:     pi[--i] = 0;
        !          4672: 
        !          4673:   TYPE_LANG_SPECIFIC (t) = (struct lang_type *) pi;
        !          4674:   CLASSTYPE_AS_LIST (t) = build_tree_list (NULL_TREE, t);
        !          4675:   SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
        !          4676:   CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
        !          4677:   CLASSTYPE_VBASE_SIZE (t) = integer_zero_node;
        !          4678:   TYPE_BINFO (t) = make_binfo (integer_zero_node, t, NULL_TREE, NULL_TREE,
        !          4679:                               NULL_TREE);
        !          4680:   CLASSTYPE_BINFO_AS_LIST (t) = build_tree_list (NULL_TREE, TYPE_BINFO (t));
        !          4681: 
        !          4682:   /* Make sure this is laid out, for ease of use later.
        !          4683:      In the presence of parse errors, the normal was of assuring
        !          4684:      this might not ever get executed, so we lay it out *immediately*.  */
        !          4685:   build_pointer_type (t);
        !          4686: 
        !          4687: #ifdef GATHER_STATISTICS
        !          4688:   tree_node_counts[(int)lang_type] += 1;
        !          4689:   tree_node_sizes[(int)lang_type] += sizeof(struct lang_type);
        !          4690: #endif
        !          4691: 
        !          4692:   return t;
        !          4693: }
        !          4694: 
        !          4695: void
        !          4696: copy_decl_lang_specific (decl)
        !          4697:      tree decl;
        !          4698: {
        !          4699:   extern struct obstack *current_obstack, *saveable_obstack;
        !          4700:   register int *old = (int *)DECL_LANG_SPECIFIC (decl);
        !          4701:   struct obstack *obstack = current_obstack;
        !          4702:   register int i = sizeof (struct lang_decl) / sizeof (int);
        !          4703:   register int *pi;
        !          4704: 
        !          4705:   if (! TREE_PERMANENT (decl))
        !          4706:     obstack = saveable_obstack;
        !          4707:   else
        !          4708:     my_friendly_assert (obstack == &permanent_obstack, 237);
        !          4709: 
        !          4710:   pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl));
        !          4711:   while (i-- > 0)
        !          4712:     pi[i] = old[i];
        !          4713: 
        !          4714:   DECL_LANG_SPECIFIC (decl) = (struct lang_decl *) pi;
        !          4715: 
        !          4716: #ifdef GATHER_STATISTICS
        !          4717:   tree_node_counts[(int)lang_decl] += 1;
        !          4718:   tree_node_sizes[(int)lang_decl] += sizeof(struct lang_decl);
        !          4719: #endif
        !          4720: }
        !          4721: 
        !          4722: void
        !          4723: dump_time_statistics ()
        !          4724: {
        !          4725:   register tree prev = 0, decl, next;
        !          4726:   int this_time = my_get_run_time ();
        !          4727:   TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time))
        !          4728:     += this_time - body_time;
        !          4729: 
        !          4730:   fprintf (stderr, "\n******\n");
        !          4731:   print_time ("header files (total)", header_time);
        !          4732:   print_time ("main file (total)", this_time - body_time);
        !          4733:   fprintf (stderr, "ratio = %g : 1\n",
        !          4734:           (double)header_time / (double)(this_time - body_time));
        !          4735:   fprintf (stderr, "\n******\n");
        !          4736: 
        !          4737:   for (decl = filename_times; decl; decl = next)
        !          4738:     {
        !          4739:       next = IDENTIFIER_GLOBAL_VALUE (decl);
        !          4740:       IDENTIFIER_GLOBAL_VALUE (decl) = prev;
        !          4741:       prev = decl;
        !          4742:     }
        !          4743: 
        !          4744:   for (decl = prev; decl; decl = IDENTIFIER_GLOBAL_VALUE (decl))
        !          4745:     print_time (IDENTIFIER_POINTER (decl),
        !          4746:                TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (decl)));
        !          4747: }
        !          4748: 
        !          4749: void
        !          4750: compiler_error (s, v, v2)
        !          4751:      char *s;
        !          4752:      HOST_WIDE_INT v, v2;                      /* @@also used as pointer */
        !          4753: {
        !          4754:   char buf[1024];
        !          4755:   sprintf (buf, s, v, v2);
        !          4756:   error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf);
        !          4757: }
        !          4758: 
        !          4759: void
        !          4760: compiler_error_with_decl (decl, s)
        !          4761:      tree decl;
        !          4762:      char *s;
        !          4763: {
        !          4764:   char *name;
        !          4765:   count_error (0);
        !          4766: 
        !          4767:   report_error_function (0);
        !          4768: 
        !          4769:   if (TREE_CODE (decl) == PARM_DECL)
        !          4770:     fprintf (stderr, "%s:%d: ",
        !          4771:             DECL_SOURCE_FILE (DECL_CONTEXT (decl)),
        !          4772:             DECL_SOURCE_LINE (DECL_CONTEXT (decl)));
        !          4773:   else
        !          4774:     fprintf (stderr, "%s:%d: ",
        !          4775:             DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
        !          4776: 
        !          4777:   name = lang_printable_name (decl);
        !          4778:   if (name)
        !          4779:     fprintf (stderr, s, name);
        !          4780:   else
        !          4781:     fprintf (stderr, s, "((anonymous))");
        !          4782:   fprintf (stderr, " (compiler error)\n");
        !          4783: }
        !          4784: 
        !          4785: void
        !          4786: yyerror (string)
        !          4787:      char *string;
        !          4788: {
        !          4789:   extern int end_of_file;
        !          4790:   char buf[200];
        !          4791: 
        !          4792:   strcpy (buf, string);
        !          4793: 
        !          4794:   /* We can't print string and character constants well
        !          4795:      because the token_buffer contains the result of processing escapes.  */
        !          4796:   if (end_of_file)
        !          4797:     strcat (buf, input_redirected ()
        !          4798:            ? " at end of saved text"
        !          4799:            : " at end of input");
        !          4800:   else if (token_buffer[0] == 0)
        !          4801:     strcat (buf, " at null character");
        !          4802:   else if (token_buffer[0] == '"')
        !          4803:     strcat (buf, " before string constant");
        !          4804:   else if (token_buffer[0] == '\'')
        !          4805:     strcat (buf, " before character constant");
        !          4806:   else if (token_buffer[0] < 040 || (unsigned char) token_buffer[0] >= 0177)
        !          4807:     sprintf (buf + strlen (buf), " before character 0%o",
        !          4808:             (unsigned char) token_buffer[0]);
        !          4809:   else
        !          4810:     strcat (buf, " before `%s'");
        !          4811: 
        !          4812:   error (buf, token_buffer);
        !          4813: }

unix.superglobalmegacorp.com

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