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 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: #include <sys/types.h>
        !            25: #include <stdio.h>
        !            26: #include <errno.h>
        !            27: #include <setjmp.h>
        !            28: #include <string.h>
        !            29: #include "config.h"
        !            30: #include "input.h"
        !            31: #include "tree.h"
        !            32: #include "cp-lex.h"
        !            33: #include "cp-parse.h"
        !            34: #include "cp-tree.h"
        !            35: #include "flags.h"
        !            36: #include "obstack.h"
        !            37: #include <assert.h>
        !            38: extern int errno;              /* needed for VAX.  */
        !            39: extern jmp_buf toplevel;
        !            40: 
        !            41: #define obstack_chunk_alloc xmalloc
        !            42: #define obstack_chunk_free free
        !            43: 
        !            44: extern int xmalloc ();
        !            45: extern void free ();
        !            46: 
        !            47: extern struct obstack *expression_obstack, permanent_obstack;
        !            48: extern struct obstack *current_obstack, *saveable_obstack;
        !            49: 
        !            50: extern double atof ();
        !            51: 
        !            52: extern char *get_directive_line ();    /* In c-common.c */
        !            53: 
        !            54: /* Given a file name X, return the nondirectory portion.
        !            55:    Keep in mind that X can be computed more than once.  */
        !            56: #ifndef FILE_NAME_NONDIRECTORY
        !            57: #define FILE_NAME_NONDIRECTORY(X)              \
        !            58:  (strrchr (X, '/') != 0 ? strrchr (X, '/') + 1 : X)
        !            59: #endif
        !            60: 
        !            61: /* If you don't have strrchr, but instead have rindex,
        !            62:    add your machine to this list, and send mail to
        !            63:    [email protected].  */
        !            64: #if defined(sequent) || defined(convex)
        !            65: #define strrchr rindex
        !            66: #endif
        !            67: extern char *strrchr ();
        !            68: void extract_interface_info ();
        !            69: 
        !            70: /* This obstack is needed to hold text.  It is not safe to use
        !            71:    TOKEN_BUFFER because `check_newline' calls `yylex'.  */
        !            72: static struct obstack inline_text_obstack;
        !            73: static char *inline_text_firstobj;
        !            74: 
        !            75: int end_of_file;
        !            76: 
        !            77: extern int first_token;
        !            78: extern struct obstack token_obstack;
        !            79: 
        !            80: /* ??? Don't really know where this goes yet.  */
        !            81: #if 1
        !            82: #include "cp-input.c"
        !            83: #else
        !            84: extern void put_back (/* int */);
        !            85: extern int input_redirected ();
        !            86: extern void feed_input (/* char *, int, struct obstack * */);
        !            87: #endif
        !            88: 
        !            89: /* Holds translations from TREE_CODEs to operator name strings,
        !            90:    i.e., opname_tab[PLUS_EXPR] == "+".  */
        !            91: char **opname_tab;
        !            92: char **assignop_tab;
        !            93: 
        !            94: #define YYEMPTY                -2
        !            95: extern int yychar;             /*  the lookahead symbol                */
        !            96: extern YYSTYPE yylval;         /*  the semantic value of the           */
        !            97:                                /*  lookahead symbol                    */
        !            98: 
        !            99: #if 0
        !           100: YYLTYPE yylloc;                        /*  location data for the lookahead     */
        !           101:                                /*  symbol                              */
        !           102: #endif
        !           103: 
        !           104: 
        !           105: /* the declaration found for the last IDENTIFIER token read in.
        !           106:    yylex must look this up to detect typedefs, which get token type TYPENAME,
        !           107:    so it is left around in case the identifier is not a typedef but is
        !           108:    used in a context which makes it a reference to a variable.  */
        !           109: extern tree lastiddecl;
        !           110: 
        !           111: /* C++ extensions */
        !           112: extern tree ridpointers[];     /* need this up here */
        !           113: 
        !           114: /* We may keep statistics about how long which files took to compile.  */
        !           115: static int header_time, body_time;
        !           116: static tree get_time_identifier ();
        !           117: static tree filename_times;
        !           118: static tree this_filename_time;
        !           119: 
        !           120: /* For implementing #pragma unit.  */
        !           121: tree current_unit_name;
        !           122: tree current_unit_language;
        !           123: 
        !           124: /* Array for holding counts of the numbers of tokens seen.  */
        !           125: extern int *token_count;
        !           126: 
        !           127: /* Textual definition used for default functions.  */
        !           128: static char default_def[] = "{}";
        !           129: 
        !           130: /* Return something to represent absolute declarators containing a *.
        !           131:    TARGET is the absolute declarator that the * contains.
        !           132:    TYPE_QUALS is a list of modifiers such as const or volatile
        !           133:    to apply to the pointer type, represented as identifiers.
        !           134: 
        !           135:    We return an INDIRECT_REF whose "contents" are TARGET
        !           136:    and whose type is the modifier list.  */
        !           137: 
        !           138: tree
        !           139: make_pointer_declarator (type_quals, target)
        !           140:      tree type_quals, target;
        !           141: {
        !           142:   if (target && TREE_CODE (target) == IDENTIFIER_NODE
        !           143:       && ANON_AGGRNAME_P (target))
        !           144:     error ("type name expected before `*'");
        !           145:   target = build_parse_node (INDIRECT_REF, target);
        !           146:   TREE_TYPE (target) = type_quals;
        !           147:   return target;
        !           148: }
        !           149: 
        !           150: /* Return something to represent absolute declarators containing a &.
        !           151:    TARGET is the absolute declarator that the & contains.
        !           152:    TYPE_QUALS is a list of modifiers such as const or volatile
        !           153:    to apply to the reference type, represented as identifiers.
        !           154: 
        !           155:    We return an ADDR_EXPR whose "contents" are TARGET
        !           156:    and whose type is the modifier list.  */
        !           157:    
        !           158: tree
        !           159: make_reference_declarator (type_quals, target)
        !           160:      tree type_quals, target;
        !           161: {
        !           162:   if (target)
        !           163:     {
        !           164:       if (TREE_CODE (target) == ADDR_EXPR)
        !           165:        {
        !           166:          error ("cannot declare references to references");
        !           167:          return target;
        !           168:        }
        !           169:       if (TREE_CODE (target) == INDIRECT_REF)
        !           170:        {
        !           171:          error ("cannot declare pointers to references");
        !           172:          return target;
        !           173:        }
        !           174:       if (TREE_CODE (target) == IDENTIFIER_NODE && ANON_AGGRNAME_P (target))
        !           175:          error ("type name expected before `&'");
        !           176:     }
        !           177:   target = build_parse_node (ADDR_EXPR, target);
        !           178:   TREE_TYPE (target) = type_quals;
        !           179:   return target;
        !           180: }
        !           181: 
        !           182: /* Build names and nodes for overloaded operators.  */
        !           183: 
        !           184: tree ansi_opname[LAST_CPLUS_TREE_CODE];
        !           185: tree ansi_assopname[LAST_CPLUS_TREE_CODE];
        !           186: 
        !           187: char *
        !           188: operator_name_string (name)
        !           189:      tree name;
        !           190: {
        !           191:   char *opname = IDENTIFIER_POINTER (name) + 2;
        !           192:   tree *opname_table;
        !           193:   int i, assign;
        !           194: 
        !           195:   /* Works for builtin and user defined types.  */
        !           196:   if (IDENTIFIER_GLOBAL_VALUE (name)
        !           197:       && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (name)) == TYPE_DECL)
        !           198:     return IDENTIFIER_POINTER (name);
        !           199: 
        !           200:   if (opname[0] == 'a' && opname[2] != '\0')
        !           201:     {
        !           202:       opname += 1;
        !           203:       assign = 1;
        !           204:       opname_table = ansi_assopname;
        !           205:     }
        !           206:   else
        !           207:     {
        !           208:       assign = 0;
        !           209:       opname_table = ansi_opname;
        !           210:     }
        !           211: 
        !           212:   for (i = 0; i < (int) LAST_CPLUS_TREE_CODE; i++)
        !           213:     {
        !           214:       if (opname[0] == IDENTIFIER_POINTER (opname_table[i])[2+assign]
        !           215:          && opname[1] == IDENTIFIER_POINTER (opname_table[i])[3+assign])
        !           216:        break;
        !           217:     }
        !           218: 
        !           219:   if (i == LAST_CPLUS_TREE_CODE)
        !           220:     return "<invalid operator>";
        !           221: 
        !           222:   if (assign)
        !           223:     return assignop_tab[i];
        !           224:   else
        !           225:     return opname_tab[i];
        !           226: }
        !           227: 
        !           228: int interface_only;            /* whether or not current file is only for
        !           229:                                   interface definitions.  */
        !           230: int interface_unknown;         /* whether or not we know this class
        !           231:                                   to behave according to #pragma interface.  */
        !           232: 
        !           233: /* lexical analyzer */
        !           234: 
        !           235: static int maxtoken;           /* Current nominal length of token buffer.  */
        !           236: char *token_buffer;            /* Pointer to token buffer.
        !           237:                                   Actual allocated length is maxtoken + 2.  */
        !           238: static int max_wide;           /* Current nominal length of wide_buffer.  */
        !           239: static int *wide_buffer;       /* Pointer to wide-string buffer.
        !           240:                                   Actual allocated length is max_wide + 1.  */
        !           241: 
        !           242: #define NORID RID_UNUSED
        !           243: 
        !           244: #include "cp-hash.h"
        !           245: 
        !           246: int check_newline ();
        !           247: 
        !           248: static int skip_white_space ();
        !           249: 
        !           250: static tree
        !           251: get_time_identifier (name)
        !           252:      char *name;
        !           253: {
        !           254:   tree time_identifier;
        !           255:   int len = strlen (name);
        !           256:   char *buf = (char *)alloca (len + 6);
        !           257:   strcpy (buf, "file ");
        !           258:   bcopy (name, buf+5, len);
        !           259:   buf[len+5] = '\0';
        !           260:   time_identifier = get_identifier (buf);
        !           261:   if (IDENTIFIER_LOCAL_VALUE (time_identifier) == NULL_TREE)
        !           262:     {
        !           263:       push_obstacks_nochange ();
        !           264:       end_temporary_allocation ();
        !           265:       IDENTIFIER_LOCAL_VALUE (time_identifier) = build_int_2 (0, 0);
        !           266:       IDENTIFIER_CLASS_VALUE (time_identifier) = build_int_2 (0, 1);
        !           267:       IDENTIFIER_GLOBAL_VALUE (time_identifier) = filename_times;
        !           268:       filename_times = time_identifier;
        !           269:       pop_obstacks ();
        !           270:     }
        !           271:   return time_identifier;
        !           272: }
        !           273: 
        !           274: #ifdef __GNUC__
        !           275: __inline
        !           276: #endif
        !           277: static int
        !           278: my_get_run_time ()
        !           279: {
        !           280:   int old_quiet_flag = quiet_flag;
        !           281:   int this_time;
        !           282:   quiet_flag = 0;
        !           283:   this_time = get_run_time ();
        !           284:   quiet_flag = old_quiet_flag;
        !           285:   return this_time;
        !           286: }
        !           287: 
        !           288: /* Table indexed by tree code giving a string containing a character
        !           289:    classifying the tree code.  Possibilities are
        !           290:    t, d, s, c, r, <, 1 and 2.  See cp-tree.def for details.  */
        !           291: 
        !           292: #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
        !           293: 
        !           294: char *cplus_tree_code_type[] = {
        !           295:   "x",
        !           296: #include "cp-tree.def"
        !           297: };
        !           298: #undef DEFTREECODE
        !           299: 
        !           300: /* Table indexed by tree code giving number of expression
        !           301:    operands beyond the fixed part of the node structure.
        !           302:    Not used for types or decls.  */
        !           303: 
        !           304: #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
        !           305: 
        !           306: int cplus_tree_code_length[] = {
        !           307:   0,
        !           308: #include "cp-tree.def"
        !           309: };
        !           310: #undef DEFTREECODE
        !           311: 
        !           312: /* Names of tree components.
        !           313:    Used for printing out the tree and error messages.  */
        !           314: #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
        !           315: 
        !           316: char *cplus_tree_code_name[] = {
        !           317:   "@@dummy",
        !           318: #include "cp-tree.def"
        !           319: };
        !           320: #undef DEFTREECODE
        !           321: 
        !           322: /* toplev.c needs to call these.  */
        !           323: 
        !           324: void
        !           325: lang_init ()
        !           326: {
        !           327:   /* the beginning of the file is a new line; check for # */
        !           328:   /* With luck, we discover the real source file's name from that
        !           329:      and put it in input_filename.  */
        !           330:   put_back (check_newline ());
        !           331: 
        !           332:   if (flag_cadillac)
        !           333:     cadillac_start ();
        !           334:   if (flag_gnu_xref) GNU_xref_begin (input_filename);
        !           335: }
        !           336: 
        !           337: void
        !           338: lang_finish ()
        !           339: {
        !           340:   extern int errorcount, sorrycount;
        !           341:   if (flag_gnu_xref) GNU_xref_end (errorcount+sorrycount);
        !           342: }
        !           343: 
        !           344: void
        !           345: init_filename_times ()
        !           346: {
        !           347:   this_filename_time = get_time_identifier ("<top level>");
        !           348:   if (flag_detailed_statistics)
        !           349:     {
        !           350:       header_time = 0;
        !           351:       body_time = my_get_run_time ();
        !           352:       TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time)) = body_time;
        !           353:     }
        !           354: }
        !           355: 
        !           356: /* Change by Bryan Boreham, Kewill, Thu Jul 27 09:46:05 1989.
        !           357:    Stuck this hack in to get the files open correctly; this is called
        !           358:    in place of init_lex if we are an unexec'd binary.    */
        !           359: void
        !           360: reinit_lang_specific ()
        !           361: {
        !           362:   init_filename_times ();
        !           363:   reinit_search_statistics ();
        !           364: }
        !           365: 
        !           366: void
        !           367: init_lex ()
        !           368: {
        !           369:   extern int *init_parse ();
        !           370:   extern char *(*decl_printable_name) ();
        !           371:   extern char *lang_printable_name ();
        !           372: 
        !           373:   int i;
        !           374: 
        !           375:   /* Initialize the lookahead machinery.  */
        !           376:   init_spew ();
        !           377: 
        !           378:   /* Make identifier nodes long enough for the language-specific slots.  */
        !           379:   set_identifier_size (sizeof (struct lang_identifier));
        !           380:   decl_printable_name = lang_printable_name;
        !           381: 
        !           382:   init_cplus_expand ();
        !           383: 
        !           384:   tree_code_type
        !           385:     = (char **) realloc (tree_code_type,
        !           386:                         sizeof (char *) * LAST_CPLUS_TREE_CODE);
        !           387:   tree_code_length
        !           388:     = (int *) realloc (tree_code_length,
        !           389:                       sizeof (int) * LAST_CPLUS_TREE_CODE);
        !           390:   tree_code_name
        !           391:     = (char **) realloc (tree_code_name,
        !           392:                         sizeof (char *) * LAST_CPLUS_TREE_CODE);
        !           393:   bcopy (cplus_tree_code_type,
        !           394:         tree_code_type + (int) LAST_AND_UNUSED_TREE_CODE,
        !           395:         (LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (char *));
        !           396:   bcopy (cplus_tree_code_length,
        !           397:         tree_code_length + (int) LAST_AND_UNUSED_TREE_CODE,
        !           398:         (LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (int));
        !           399:   bcopy (cplus_tree_code_name,
        !           400:         tree_code_name + (int) LAST_AND_UNUSED_TREE_CODE,
        !           401:         (LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (char *));
        !           402: 
        !           403:   opname_tab = (char **)oballoc ((int)LAST_CPLUS_TREE_CODE * sizeof (char *));
        !           404:   bzero (opname_tab, (int)LAST_CPLUS_TREE_CODE * sizeof (char *));
        !           405:   assignop_tab = (char **)oballoc ((int)LAST_CPLUS_TREE_CODE * sizeof (char *));
        !           406:   bzero (assignop_tab, (int)LAST_CPLUS_TREE_CODE * sizeof (char *));
        !           407: 
        !           408:   ansi_opname[0] = get_identifier ("<invalid operator>");
        !           409:   for (i = 0; i < LAST_CPLUS_TREE_CODE; i++)
        !           410:     {
        !           411:       ansi_opname[i] = ansi_opname[0];
        !           412:       ansi_assopname[i] = ansi_opname[0];
        !           413:     }
        !           414: 
        !           415:   ansi_opname[MULT_EXPR] = get_identifier ("__ml");
        !           416:   IDENTIFIER_OPNAME_P (ansi_opname[MULT_EXPR]) = 1;
        !           417:   ansi_opname[INDIRECT_REF] = ansi_opname[MULT_EXPR];
        !           418:   ansi_assopname[MULT_EXPR] = get_identifier ("__aml");
        !           419:   IDENTIFIER_OPNAME_P (ansi_assopname[MULT_EXPR]) = 1;
        !           420:   ansi_assopname[INDIRECT_REF] = ansi_assopname[MULT_EXPR];
        !           421:   ansi_opname[TRUNC_MOD_EXPR] = get_identifier ("__md");
        !           422:   IDENTIFIER_OPNAME_P (ansi_opname[TRUNC_MOD_EXPR]) = 1;
        !           423:   ansi_assopname[TRUNC_MOD_EXPR] = get_identifier ("__amd");
        !           424:   IDENTIFIER_OPNAME_P (ansi_assopname[TRUNC_MOD_EXPR]) = 1;
        !           425:   ansi_opname[CEIL_MOD_EXPR] = ansi_opname[TRUNC_MOD_EXPR];
        !           426:   ansi_opname[FLOOR_MOD_EXPR] = ansi_opname[TRUNC_MOD_EXPR];
        !           427:   ansi_opname[ROUND_MOD_EXPR] = ansi_opname[TRUNC_MOD_EXPR];
        !           428:   ansi_opname[MINUS_EXPR] = get_identifier ("__mi");
        !           429:   IDENTIFIER_OPNAME_P (ansi_opname[MINUS_EXPR]) = 1;
        !           430:   ansi_opname[NEGATE_EXPR] = ansi_opname[MINUS_EXPR];
        !           431:   ansi_assopname[MINUS_EXPR] = get_identifier ("__ami");
        !           432:   IDENTIFIER_OPNAME_P (ansi_assopname[MINUS_EXPR]) = 1;
        !           433:   ansi_assopname[NEGATE_EXPR] = ansi_assopname[MINUS_EXPR];
        !           434:   ansi_opname[RSHIFT_EXPR] = get_identifier ("__rs");
        !           435:   IDENTIFIER_OPNAME_P (ansi_opname[RSHIFT_EXPR]) = 1;
        !           436:   ansi_assopname[RSHIFT_EXPR] = get_identifier ("__ars");
        !           437:   IDENTIFIER_OPNAME_P (ansi_assopname[RSHIFT_EXPR]) = 1;
        !           438:   ansi_opname[NE_EXPR] = get_identifier ("__ne");
        !           439:   IDENTIFIER_OPNAME_P (ansi_opname[NE_EXPR]) = 1;
        !           440:   ansi_opname[GT_EXPR] = get_identifier ("__gt");
        !           441:   IDENTIFIER_OPNAME_P (ansi_opname[GT_EXPR]) = 1;
        !           442:   ansi_opname[GE_EXPR] = get_identifier ("__ge");
        !           443:   IDENTIFIER_OPNAME_P (ansi_opname[GE_EXPR]) = 1;
        !           444:   ansi_opname[BIT_IOR_EXPR] = get_identifier ("__or");
        !           445:   IDENTIFIER_OPNAME_P (ansi_opname[BIT_IOR_EXPR]) = 1;
        !           446:   ansi_assopname[BIT_IOR_EXPR] = get_identifier ("__aor");
        !           447:   IDENTIFIER_OPNAME_P (ansi_assopname[BIT_IOR_EXPR]) = 1;
        !           448:   ansi_opname[TRUTH_ANDIF_EXPR] = get_identifier ("__aa");
        !           449:   IDENTIFIER_OPNAME_P (ansi_opname[TRUTH_ANDIF_EXPR]) = 1;
        !           450:   ansi_opname[TRUTH_NOT_EXPR] = get_identifier ("__nt");
        !           451:   IDENTIFIER_OPNAME_P (ansi_opname[TRUTH_NOT_EXPR]) = 1;
        !           452:   ansi_opname[PREINCREMENT_EXPR] = get_identifier ("__pp");
        !           453:   IDENTIFIER_OPNAME_P (ansi_opname[PREINCREMENT_EXPR]) = 1;
        !           454:   ansi_opname[POSTINCREMENT_EXPR] = ansi_opname[PREINCREMENT_EXPR];
        !           455:   ansi_opname[MODIFY_EXPR] = get_identifier ("__as");
        !           456:   IDENTIFIER_OPNAME_P (ansi_opname[MODIFY_EXPR]) = 1;
        !           457:   ansi_assopname[NOP_EXPR] = ansi_opname[MODIFY_EXPR];
        !           458:   ansi_opname[COMPOUND_EXPR] = get_identifier ("__cm");
        !           459:   IDENTIFIER_OPNAME_P (ansi_opname[COMPOUND_EXPR]) = 1;
        !           460:   ansi_opname[EXACT_DIV_EXPR] = get_identifier ("__dv");
        !           461:   IDENTIFIER_OPNAME_P (ansi_opname[EXACT_DIV_EXPR]) = 1;
        !           462:   ansi_assopname[EXACT_DIV_EXPR] = get_identifier ("__adv");
        !           463:   IDENTIFIER_OPNAME_P (ansi_assopname[EXACT_DIV_EXPR]) = 1;
        !           464:   ansi_opname[TRUNC_DIV_EXPR] = ansi_opname[EXACT_DIV_EXPR];
        !           465:   ansi_opname[CEIL_DIV_EXPR] = ansi_opname[EXACT_DIV_EXPR];
        !           466:   ansi_opname[FLOOR_DIV_EXPR] = ansi_opname[EXACT_DIV_EXPR];
        !           467:   ansi_opname[ROUND_DIV_EXPR] = ansi_opname[EXACT_DIV_EXPR];
        !           468:   ansi_opname[PLUS_EXPR] = get_identifier ("__pl");
        !           469:   ansi_assopname[TRUNC_DIV_EXPR] = ansi_assopname[EXACT_DIV_EXPR];
        !           470:   ansi_assopname[CEIL_DIV_EXPR] = ansi_assopname[EXACT_DIV_EXPR];
        !           471:   ansi_assopname[FLOOR_DIV_EXPR] = ansi_assopname[EXACT_DIV_EXPR];
        !           472:   ansi_assopname[ROUND_DIV_EXPR] = ansi_assopname[EXACT_DIV_EXPR];
        !           473:   ansi_opname[PLUS_EXPR] = get_identifier ("__pl");
        !           474:   IDENTIFIER_OPNAME_P (ansi_opname[PLUS_EXPR]) = 1;
        !           475:   ansi_assopname[PLUS_EXPR] = get_identifier ("__apl");
        !           476:   IDENTIFIER_OPNAME_P (ansi_assopname[PLUS_EXPR]) = 1;
        !           477:   ansi_opname[CONVERT_EXPR] = ansi_opname[PLUS_EXPR];
        !           478:   ansi_assopname[CONVERT_EXPR] = ansi_assopname[PLUS_EXPR];
        !           479:   ansi_opname[LSHIFT_EXPR] = get_identifier ("__ls");
        !           480:   IDENTIFIER_OPNAME_P (ansi_opname[LSHIFT_EXPR]) = 1;
        !           481:   ansi_assopname[LSHIFT_EXPR] = get_identifier ("__als");
        !           482:   IDENTIFIER_OPNAME_P (ansi_assopname[LSHIFT_EXPR]) = 1;
        !           483:   ansi_opname[EQ_EXPR] = get_identifier ("__eq");
        !           484:   IDENTIFIER_OPNAME_P (ansi_opname[EQ_EXPR]) = 1;
        !           485:   ansi_opname[LT_EXPR] = get_identifier ("__lt");
        !           486:   IDENTIFIER_OPNAME_P (ansi_opname[LT_EXPR]) = 1;
        !           487:   ansi_opname[LE_EXPR] = get_identifier ("__le");
        !           488:   IDENTIFIER_OPNAME_P (ansi_opname[LE_EXPR]) = 1;
        !           489:   ansi_opname[BIT_AND_EXPR] = get_identifier ("__ad");
        !           490:   IDENTIFIER_OPNAME_P (ansi_opname[BIT_AND_EXPR]) = 1;
        !           491:   ansi_assopname[BIT_AND_EXPR] = get_identifier ("__aad");
        !           492:   IDENTIFIER_OPNAME_P (ansi_assopname[BIT_AND_EXPR]) = 1;
        !           493:   ansi_opname[ADDR_EXPR] = ansi_opname[BIT_AND_EXPR];
        !           494:   ansi_assopname[ADDR_EXPR] = ansi_assopname[BIT_AND_EXPR];
        !           495:   ansi_opname[BIT_XOR_EXPR] = get_identifier ("__er");
        !           496:   IDENTIFIER_OPNAME_P (ansi_opname[BIT_XOR_EXPR]) = 1;
        !           497:   ansi_assopname[BIT_XOR_EXPR] = get_identifier ("__aer");
        !           498:   IDENTIFIER_OPNAME_P (ansi_assopname[BIT_XOR_EXPR]) = 1;
        !           499:   ansi_opname[TRUTH_ORIF_EXPR] = get_identifier ("__oo");
        !           500:   IDENTIFIER_OPNAME_P (ansi_opname[TRUTH_ORIF_EXPR]) = 1;
        !           501:   ansi_opname[BIT_NOT_EXPR] = get_identifier ("__co");
        !           502:   IDENTIFIER_OPNAME_P (ansi_opname[BIT_NOT_EXPR]) = 1;
        !           503:   ansi_opname[PREDECREMENT_EXPR] = get_identifier ("__mm");
        !           504:   IDENTIFIER_OPNAME_P (ansi_opname[PREDECREMENT_EXPR]) = 1;
        !           505:   ansi_opname[POSTDECREMENT_EXPR] = ansi_opname[PREDECREMENT_EXPR];
        !           506:   ansi_opname[COMPONENT_REF] = get_identifier ("__rf");
        !           507:   IDENTIFIER_OPNAME_P (ansi_opname[COMPONENT_REF]) = 1;
        !           508:   ansi_opname[MEMBER_REF] = get_identifier ("__rm");
        !           509:   IDENTIFIER_OPNAME_P (ansi_opname[MEMBER_REF]) = 1;
        !           510:   ansi_opname[CALL_EXPR] = get_identifier ("__cl");
        !           511:   IDENTIFIER_OPNAME_P (ansi_opname[CALL_EXPR]) = 1;
        !           512:   ansi_opname[ARRAY_REF] = get_identifier ("__vc");
        !           513:   IDENTIFIER_OPNAME_P (ansi_opname[ARRAY_REF]) = 1;
        !           514:   ansi_opname[NEW_EXPR] = get_identifier ("__nw");
        !           515:   IDENTIFIER_OPNAME_P (ansi_opname[NEW_EXPR]) = 1;
        !           516:   ansi_opname[DELETE_EXPR] = get_identifier ("__dl");
        !           517:   IDENTIFIER_OPNAME_P (ansi_opname[DELETE_EXPR]) = 1;
        !           518:   ansi_opname[TYPE_EXPR] = get_identifier ("__op");
        !           519:   IDENTIFIER_OPNAME_P (ansi_opname[TYPE_EXPR]) = 1;
        !           520: 
        !           521:   /* This is not true: these operators are not defined in ANSI,
        !           522:      but we need them anyway.  */
        !           523:   ansi_opname[MIN_EXPR] = get_identifier ("__mn");
        !           524:   IDENTIFIER_OPNAME_P (ansi_opname[MIN_EXPR]) = 1;
        !           525:   ansi_opname[MAX_EXPR] = get_identifier ("__mx");
        !           526:   IDENTIFIER_OPNAME_P (ansi_opname[MAX_EXPR]) = 1;
        !           527:   ansi_opname[COND_EXPR] = get_identifier ("__cn");
        !           528:   IDENTIFIER_OPNAME_P (ansi_opname[COND_EXPR]) = 1;
        !           529:   ansi_opname[METHOD_CALL_EXPR] = get_identifier ("__wr");
        !           530:   IDENTIFIER_OPNAME_P (ansi_opname[METHOD_CALL_EXPR]) = 1;
        !           531: 
        !           532:   init_method ();
        !           533:   gcc_obstack_init (&inline_text_obstack);
        !           534:   inline_text_firstobj = (char *) obstack_alloc (&inline_text_obstack, 0);
        !           535: 
        !           536:   /* Start it at 0, because check_newline is called at the very beginning
        !           537:      and will increment it to 1.  */
        !           538:   lineno = 0;
        !           539:   current_function_decl = NULL;
        !           540: 
        !           541:   maxtoken = 40;
        !           542:   token_buffer = (char *) xmalloc (maxtoken + 2);
        !           543:   max_wide = 40;
        !           544:   wide_buffer = (int *) xmalloc (max_wide + 1);
        !           545: 
        !           546:   ridpointers[(int) RID_INT] = get_identifier ("int");
        !           547:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_INT],
        !           548:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]));
        !           549:   ridpointers[(int) RID_CHAR] = get_identifier ("char");
        !           550:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_CHAR],
        !           551:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]));
        !           552:   ridpointers[(int) RID_VOID] = get_identifier ("void");
        !           553:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VOID],
        !           554:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]));
        !           555:   ridpointers[(int) RID_FLOAT] = get_identifier ("float");
        !           556:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_FLOAT],
        !           557:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_FLOAT]));
        !           558:   ridpointers[(int) RID_DOUBLE] = get_identifier ("double");
        !           559:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_DOUBLE],
        !           560:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_DOUBLE]));
        !           561:   ridpointers[(int) RID_SHORT] = get_identifier ("short");
        !           562:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_SHORT],
        !           563:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_SHORT]));
        !           564:   ridpointers[(int) RID_LONG] = get_identifier ("long");
        !           565:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_LONG],
        !           566:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]));
        !           567:   ridpointers[(int) RID_UNSIGNED] = get_identifier ("unsigned");
        !           568:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_UNSIGNED],
        !           569:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_UNSIGNED]));
        !           570:   ridpointers[(int) RID_SIGNED] = get_identifier ("signed");
        !           571:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_SIGNED],
        !           572:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_SIGNED]));
        !           573:   ridpointers[(int) RID_INLINE] = get_identifier ("inline");
        !           574:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_INLINE],
        !           575:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_INLINE]));
        !           576:   ridpointers[(int) RID_CONST] = get_identifier ("const");
        !           577:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_CONST],
        !           578:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_CONST]));
        !           579:   ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile");
        !           580:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VOLATILE],
        !           581:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_VOLATILE]));
        !           582:   ridpointers[(int) RID_AUTO] = get_identifier ("auto");
        !           583:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_AUTO],
        !           584:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_AUTO]));
        !           585:   ridpointers[(int) RID_STATIC] = get_identifier ("static");
        !           586:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_STATIC],
        !           587:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]));
        !           588:   ridpointers[(int) RID_EXTERN] = get_identifier ("extern");
        !           589:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_EXTERN],
        !           590:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]));
        !           591:   ridpointers[(int) RID_TYPEDEF] = get_identifier ("typedef");
        !           592:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_TYPEDEF],
        !           593:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_TYPEDEF]));
        !           594:   ridpointers[(int) RID_REGISTER] = get_identifier ("register");
        !           595:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_REGISTER],
        !           596:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_REGISTER]));
        !           597: 
        !           598:   /* C++ extensions. These are probably not correctly named. */
        !           599:   class_type_node = build_int_2 (class_type, 0);
        !           600:   TREE_TYPE (class_type_node) = class_type_node;
        !           601:   ridpointers[(int) RID_CLASS] = class_type_node;
        !           602: 
        !           603:   record_type_node = build_int_2 (record_type, 0);
        !           604:   TREE_TYPE (record_type_node) = record_type_node;
        !           605:   ridpointers[(int) RID_RECORD] = record_type_node;
        !           606: 
        !           607:   union_type_node = build_int_2 (union_type, 0);
        !           608:   TREE_TYPE (union_type_node) = union_type_node;
        !           609:   ridpointers[(int) RID_UNION] = union_type_node;
        !           610: 
        !           611:   enum_type_node = build_int_2 (enum_type, 0);
        !           612:   TREE_TYPE (enum_type_node) = enum_type_node;
        !           613:   ridpointers[(int) RID_ENUM] = enum_type_node;
        !           614: 
        !           615:   ridpointers[(int) RID_VIRTUAL] = get_identifier ("virtual");
        !           616:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VIRTUAL],
        !           617:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_VIRTUAL]));
        !           618:   ridpointers[(int) RID_FRIEND] = get_identifier ("friend");
        !           619:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_FRIEND],
        !           620:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_FRIEND]));
        !           621: 
        !           622:   ridpointers[(int) RID_PUBLIC] = get_identifier ("public");
        !           623:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PUBLIC],
        !           624:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_PUBLIC]));
        !           625:   ridpointers[(int) RID_PRIVATE] = get_identifier ("private");
        !           626:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PRIVATE],
        !           627:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_PRIVATE]));
        !           628:   ridpointers[(int) RID_PROTECTED] = get_identifier ("protected");
        !           629:   SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PROTECTED],
        !           630:                          build_tree_list (NULL_TREE, ridpointers[(int) RID_PROTECTED]));
        !           631: 
        !           632:   /* Exception handling extensions.  */
        !           633:   exception_type_node = build_int_2 (exception_type, 0);
        !           634:   TREE_TYPE (exception_type_node) = exception_type_node;
        !           635:   ridpointers[(int) RID_EXCEPTION] = exception_type_node;
        !           636: 
        !           637:   opname_tab[(int) COMPONENT_REF] = "->";
        !           638:   opname_tab[(int) MEMBER_REF] = "->*";
        !           639:   opname_tab[(int) METHOD_CALL_EXPR] = "->()";
        !           640:   opname_tab[(int) INDIRECT_REF] = "(unary *)";
        !           641:   opname_tab[(int) ARRAY_REF] = "[]";
        !           642:   opname_tab[(int) MODIFY_EXPR] = "=";
        !           643:   opname_tab[(int) NEW_EXPR] = "new";
        !           644:   opname_tab[(int) DELETE_EXPR] = "delete";
        !           645:   opname_tab[(int) COND_EXPR] = "... ? ... : ...";
        !           646:   opname_tab[(int) CALL_EXPR] = "()";
        !           647:   opname_tab[(int) PLUS_EXPR] = "+";
        !           648:   opname_tab[(int) MINUS_EXPR] = "-";
        !           649:   opname_tab[(int) MULT_EXPR] = "*";
        !           650:   opname_tab[(int) TRUNC_DIV_EXPR] = "/";
        !           651:   opname_tab[(int) CEIL_DIV_EXPR] = "(ceiling /)";
        !           652:   opname_tab[(int) FLOOR_DIV_EXPR] = "(floor /)";
        !           653:   opname_tab[(int) ROUND_DIV_EXPR] = "(round /)";
        !           654:   opname_tab[(int) TRUNC_MOD_EXPR] = "%";
        !           655:   opname_tab[(int) CEIL_MOD_EXPR] = "(ceiling %)";
        !           656:   opname_tab[(int) FLOOR_MOD_EXPR] = "(floor %)";
        !           657:   opname_tab[(int) ROUND_MOD_EXPR] = "(round %)";
        !           658:   opname_tab[(int) NEGATE_EXPR] = "-";
        !           659:   opname_tab[(int) MIN_EXPR] = "<?";
        !           660:   opname_tab[(int) MAX_EXPR] = ">?";
        !           661:   opname_tab[(int) ABS_EXPR] = "abs";
        !           662:   opname_tab[(int) FFS_EXPR] = "ffs";
        !           663:   opname_tab[(int) LSHIFT_EXPR] = "<<";
        !           664:   opname_tab[(int) RSHIFT_EXPR] = ">>";
        !           665:   opname_tab[(int) BIT_IOR_EXPR] = "|";
        !           666:   opname_tab[(int) BIT_XOR_EXPR] = "^";
        !           667:   opname_tab[(int) BIT_AND_EXPR] = "&";
        !           668:   opname_tab[(int) BIT_ANDTC_EXPR] = "&~";
        !           669:   opname_tab[(int) BIT_NOT_EXPR] = "~";
        !           670:   opname_tab[(int) TRUTH_ANDIF_EXPR] = "&&";
        !           671:   opname_tab[(int) TRUTH_ORIF_EXPR] = "||";
        !           672:   opname_tab[(int) TRUTH_AND_EXPR] = "strict &&";
        !           673:   opname_tab[(int) TRUTH_OR_EXPR] = "strict ||";
        !           674:   opname_tab[(int) TRUTH_NOT_EXPR] = "!";
        !           675:   opname_tab[(int) LT_EXPR] = "<";
        !           676:   opname_tab[(int) LE_EXPR] = "<=";
        !           677:   opname_tab[(int) GT_EXPR] = ">";
        !           678:   opname_tab[(int) GE_EXPR] = ">=";
        !           679:   opname_tab[(int) EQ_EXPR] = "==";
        !           680:   opname_tab[(int) NE_EXPR] = "!=";
        !           681:   opname_tab[(int) IN_EXPR] = "in";
        !           682:   opname_tab[(int) SET_LE_EXPR] = "subset";
        !           683:   opname_tab[(int) CARD_EXPR] = "#";
        !           684:   opname_tab[(int) RANGE_EXPR] = "..";
        !           685:   opname_tab[(int) CONVERT_EXPR] = "(unary +)";
        !           686:   opname_tab[(int) ADDR_EXPR] = "(unary &)";
        !           687:   opname_tab[(int) PREDECREMENT_EXPR] = "--";
        !           688:   opname_tab[(int) PREINCREMENT_EXPR] = "++";
        !           689:   opname_tab[(int) POSTDECREMENT_EXPR] = "--";
        !           690:   opname_tab[(int) POSTINCREMENT_EXPR] = "++";
        !           691:   opname_tab[(int) COMPOUND_EXPR] = ",";
        !           692: 
        !           693:   assignop_tab[(int) NOP_EXPR] = "=";
        !           694:   assignop_tab[(int) PLUS_EXPR] =  "+=";
        !           695:   assignop_tab[(int) CONVERT_EXPR] =  "+=";
        !           696:   assignop_tab[(int) MINUS_EXPR] = "-=";
        !           697:   assignop_tab[(int) NEGATE_EXPR] = "-=";
        !           698:   assignop_tab[(int) MULT_EXPR] = "*=";
        !           699:   assignop_tab[(int) INDIRECT_REF] = "*=";
        !           700:   assignop_tab[(int) TRUNC_DIV_EXPR] = "/=";
        !           701:   assignop_tab[(int) EXACT_DIV_EXPR] = "(exact /=)";
        !           702:   assignop_tab[(int) CEIL_DIV_EXPR] = "(ceiling /=)";
        !           703:   assignop_tab[(int) FLOOR_DIV_EXPR] = "(floor /=)";
        !           704:   assignop_tab[(int) ROUND_DIV_EXPR] = "(round /=)";
        !           705:   assignop_tab[(int) TRUNC_MOD_EXPR] = "%=";
        !           706:   assignop_tab[(int) CEIL_MOD_EXPR] = "(ceiling %=)";
        !           707:   assignop_tab[(int) FLOOR_MOD_EXPR] = "(floor %=)";
        !           708:   assignop_tab[(int) ROUND_MOD_EXPR] = "(round %=)";
        !           709:   assignop_tab[(int) MIN_EXPR] = "<?=";
        !           710:   assignop_tab[(int) MAX_EXPR] = ">?=";
        !           711:   assignop_tab[(int) LSHIFT_EXPR] = "<<=";
        !           712:   assignop_tab[(int) RSHIFT_EXPR] = ">>=";
        !           713:   assignop_tab[(int) BIT_IOR_EXPR] = "|=";
        !           714:   assignop_tab[(int) BIT_XOR_EXPR] = "^=";
        !           715:   assignop_tab[(int) BIT_AND_EXPR] = "&=";
        !           716:   assignop_tab[(int) ADDR_EXPR] = "&=";
        !           717: 
        !           718:   init_filename_times ();
        !           719: 
        !           720: #define UNSET_RESERVED_WORD(STRING) \
        !           721:   do { is_reserved_word (STRING, sizeof (STRING) - 1)->name = ""; } while (0)
        !           722: 
        !           723:   if (flag_ansi_exceptions)
        !           724:       flag_handle_exceptions = 2;
        !           725: 
        !           726:   if (!flag_ansi_exceptions)
        !           727:     {
        !           728:       UNSET_RESERVED_WORD ("catch");
        !           729:     }
        !           730: 
        !           731:   if (! flag_handle_exceptions)
        !           732:     {
        !           733:       /* Easiest way to not recognize exception
        !           734:         handling extentions...  */
        !           735:       UNSET_RESERVED_WORD ("all");
        !           736:       UNSET_RESERVED_WORD ("except");
        !           737:       UNSET_RESERVED_WORD ("exception");
        !           738:       UNSET_RESERVED_WORD ("raise");
        !           739:       UNSET_RESERVED_WORD ("raises");
        !           740:       UNSET_RESERVED_WORD ("reraise");
        !           741:       UNSET_RESERVED_WORD ("try");
        !           742:       UNSET_RESERVED_WORD ("throw");
        !           743:     }
        !           744:   else if (flag_ansi_exceptions)
        !           745:     {
        !           746:       /* Easiest way to not recognize exception
        !           747:         handling extentions...  */
        !           748:       UNSET_RESERVED_WORD ("exception");
        !           749:       UNSET_RESERVED_WORD ("all");
        !           750:       UNSET_RESERVED_WORD ("except");
        !           751:       UNSET_RESERVED_WORD ("raise");
        !           752:       UNSET_RESERVED_WORD ("raises");
        !           753:       UNSET_RESERVED_WORD ("reraise");
        !           754:       is_reserved_word ("try", sizeof ("try") - 1)->token = ANSI_TRY;
        !           755:       is_reserved_word ("throw", sizeof ("throw") - 1)->token = ANSI_THROW;
        !           756:     }
        !           757:   if (! (flag_gc || flag_dossier))
        !           758:     {
        !           759:       UNSET_RESERVED_WORD ("classof");
        !           760:       UNSET_RESERVED_WORD ("headof");
        !           761:     }
        !           762:   if (flag_no_asm)
        !           763:     UNSET_RESERVED_WORD ("asm");
        !           764:   if (flag_no_asm || flag_traditional)
        !           765:     UNSET_RESERVED_WORD ("typeof");
        !           766: #ifndef SOS
        !           767:   UNSET_RESERVED_WORD ("dynamic");
        !           768: #endif
        !           769: 
        !           770:   token_count = init_parse ();
        !           771:   interface_unknown = 1;
        !           772: }
        !           773: 
        !           774: void
        !           775: reinit_parse_for_function ()
        !           776: {
        !           777:   current_base_init_list = NULL_TREE;
        !           778:   current_member_init_list = NULL_TREE;
        !           779: }
        !           780: 
        !           781: /* Functions and data structures for #pragma interface.
        !           782: 
        !           783:    `#pragma implementation' means that the main file being compiled
        !           784:    is considered to implement (provide) the classes that appear in
        !           785:    its main body.  I.e., if this is file "foo.cc", and class `bar'
        !           786:    is defined in "foo.cc", then we say that "foo.cc implements bar".
        !           787: 
        !           788:    All main input files "implement" themselves automagically.
        !           789: 
        !           790:    `#pragma interface' means that unless this file (of the form "foo.h"
        !           791:    is not presently being included by file "foo.cc", the
        !           792:    CLASSTYPE_INTERFACE_ONLY bit gets set.  The effect is that none
        !           793:    of the vtables nor any of the inline functions defined in foo.h
        !           794:    will ever be output.
        !           795: 
        !           796:    There are cases when we want to link files such as "defs.h" and
        !           797:    "main.cc".  In this case, we give "defs.h" a `#pragma interface',
        !           798:    and "main.cc" has `#pragma implementation "defs.h"'.  */
        !           799: 
        !           800: struct impl_files
        !           801: {
        !           802:   char *filename;
        !           803:   struct impl_files *next;
        !           804: };
        !           805: 
        !           806: static struct impl_files *impl_file_chain;
        !           807: 
        !           808: /* Helper function to load global variables with interface
        !           809:    information.  */
        !           810: void
        !           811: extract_interface_info ()
        !           812: {
        !           813:   tree fileinfo = get_time_identifier (input_filename);
        !           814:   fileinfo = IDENTIFIER_CLASS_VALUE (fileinfo);
        !           815:   interface_only = TREE_INT_CST_LOW (fileinfo);
        !           816:   interface_unknown = TREE_INT_CST_HIGH (fileinfo);
        !           817: }
        !           818: 
        !           819: /* Return nonzero if S and T are not considered part of an
        !           820:    INTERFACE/IMPLEMENTATION pair.  Otherwise, return 0.  */
        !           821: static int
        !           822: interface_strcmp (s)
        !           823:      char *s;
        !           824: {
        !           825:   /* Set the interface/implementation bits for this scope.  */
        !           826:   struct impl_files *ifiles;
        !           827:   char *s1;
        !           828: 
        !           829:   s = FILE_NAME_NONDIRECTORY (s);
        !           830: 
        !           831:   for (ifiles = impl_file_chain; ifiles; ifiles = ifiles->next)
        !           832:     {
        !           833:       char *t1 = ifiles->filename;
        !           834:       s1 = s;
        !           835: 
        !           836:       if (*s1 != *t1 || *s1 == 0)
        !           837:        continue;
        !           838: 
        !           839:       while (*s1 == *t1 && *s1 != 0)
        !           840:        s1++, t1++;
        !           841: 
        !           842:       /* A match.  */
        !           843:       if (*s1 == *t1)
        !           844:        return 0;
        !           845: 
        !           846:       /* Don't get faked out by xxx.yyy.cc vs xxx.zzz.cc.  */
        !           847:       if (strchr (s1, '.') || strchr (t1, '.'))
        !           848:        continue;
        !           849: 
        !           850:       if (*s1 == '\0' || s1[-1] != '.' || t1[-1] != '.')
        !           851:        continue;
        !           852: 
        !           853:       /* A match.  */
        !           854:       return 0;
        !           855:     }
        !           856: 
        !           857:   /* No matches.  */
        !           858:   return 1;
        !           859: }
        !           860: 
        !           861: void
        !           862: set_typedecl_interface_info (prev, vars)
        !           863:      tree prev, vars;
        !           864: {
        !           865:   tree id = get_time_identifier (DECL_SOURCE_FILE (vars));
        !           866:   tree fileinfo = IDENTIFIER_CLASS_VALUE (id);
        !           867:   tree type = TREE_TYPE (vars);
        !           868: 
        !           869:   CLASSTYPE_INTERFACE_ONLY (type) = TREE_INT_CST_LOW (fileinfo)
        !           870:     = interface_strcmp (DECL_SOURCE_FILE (vars));
        !           871: }
        !           872: 
        !           873: void
        !           874: set_vardecl_interface_info (prev, vars)
        !           875:      tree prev, vars;
        !           876: {
        !           877:   tree type = DECL_CONTEXT (vars);
        !           878: 
        !           879:   if (CLASSTYPE_INTERFACE_UNKNOWN (type) == 0)
        !           880:     {
        !           881:       if (CLASSTYPE_INTERFACE_ONLY (type))
        !           882:        set_typedecl_interface_info (prev, TYPE_NAME (type));
        !           883:       TREE_EXTERNAL (vars) = CLASSTYPE_INTERFACE_ONLY (type);
        !           884:       TREE_PUBLIC (vars) = ! CLASSTYPE_INTERFACE_ONLY (type);
        !           885:       CLASSTYPE_VTABLE_NEEDS_WRITING (type) |= TREE_PUBLIC (vars);
        !           886:     }
        !           887: }
        !           888: 
        !           889: /* Called from the top level: if there are any pending inlines to
        !           890:    do, set up to process them now.  */
        !           891: void
        !           892: do_pending_inlines ()
        !           893: {
        !           894:   struct pending_inline *prev = 0, *tail;
        !           895:   struct pending_inline *t;
        !           896: 
        !           897:   /* Reverse the pending inline functions, since
        !           898:      they were cons'd instead of appended.  */
        !           899:   
        !           900:   for (t = pending_inlines; t; t = tail)
        !           901:     {
        !           902:       t->deja_vu = 1;
        !           903:       tail = t->next;
        !           904:       t->next = prev;
        !           905:       prev = t;
        !           906:     }
        !           907:   /* Reset to zero so that if the inline functions we are currently
        !           908:      processing define inline functions of their own, that is handled
        !           909:      correctly.  ??? This hasn't been checked in a while.  */
        !           910:   pending_inlines = 0;
        !           911:   
        !           912:   /* Now start processing the first inline function.  */
        !           913:   t = prev;
        !           914:   assert ((t->parm_vec == NULL_TREE) == (t->bindings == NULL_TREE));
        !           915:   if (t->parm_vec)
        !           916:     push_template_decls (t->parm_vec, t->bindings, 0);
        !           917:   if (t->len > 0)
        !           918:     {
        !           919:       feed_input (t->buf, t->len, t->can_free ? &inline_text_obstack : 0);
        !           920:       lineno = t->lineno;
        !           921:       if (input_filename != t->filename)
        !           922:        {
        !           923:          input_filename = t->filename;
        !           924:          /* Get interface/implementation back in sync.  */
        !           925:          extract_interface_info ();
        !           926:        }
        !           927:       yychar = PRE_PARSED_FUNCTION_DECL;
        !           928:     }
        !           929:   /* Pass back a handle on the rest of the inline functions, so that they
        !           930:      can be processed later.  */
        !           931:   yylval.ttype = build_tree_list ((tree) t, t->fndecl);
        !           932:   if (flag_default_inline && t->fndecl
        !           933:       /* If we're working from a template, don't change
        !           934:         the `inline' state.  */
        !           935:       && t->parm_vec == NULL_TREE)
        !           936:     TREE_INLINE (t->fndecl) = 1;
        !           937:   DECL_PENDING_INLINE_INFO (t->fndecl) = 0;
        !           938: }
        !           939: 
        !           940: extern struct pending_input *to_be_restored;
        !           941: 
        !           942: void
        !           943: process_next_inline (t)
        !           944:      tree t;
        !           945: {
        !           946:   struct pending_inline *i = (struct pending_inline *) TREE_PURPOSE (t);
        !           947:   assert ((i->parm_vec == NULL_TREE) == (i->bindings == NULL_TREE));
        !           948:   if (i->parm_vec)
        !           949:     pop_template_decls (i->parm_vec, i->bindings, 0);
        !           950:   i = i->next;
        !           951:   if (yychar == YYEMPTY)
        !           952:     yychar = yylex ();
        !           953:   if (yychar != END_OF_SAVED_INPUT)
        !           954:     {
        !           955:       error ("parse error at end of saved function text");
        !           956:       /* restore_pending_input will abort unless yychar is either
        !           957:        * END_OF_SAVED_INPUT or YYEMPTY; since we already know we're
        !           958:        * hosed, feed back YYEMPTY.
        !           959:        */
        !           960:       yychar = YYEMPTY;
        !           961:     }
        !           962:   else
        !           963:     yychar = YYEMPTY;
        !           964:   restore_pending_input (to_be_restored);
        !           965:   to_be_restored = 0;
        !           966:   if (i && i->fndecl != NULL_TREE)
        !           967:     {
        !           968:       assert ((i->parm_vec == NULL_TREE) == (i->bindings == NULL_TREE));
        !           969:       if (i->parm_vec)
        !           970:        push_template_decls (i->parm_vec, i->bindings, 0);
        !           971:       feed_input (i->buf, i->len, i->can_free ? &inline_text_obstack : 0);
        !           972:       lineno = i->lineno;
        !           973:       input_filename = i->filename;
        !           974:       yychar = PRE_PARSED_FUNCTION_DECL;
        !           975:       yylval.ttype = build_tree_list ((tree) i, i->fndecl);
        !           976:       if (flag_default_inline
        !           977:          /* If we're working from a template, don't change
        !           978:             the `inline' state.  */
        !           979:          && i->parm_vec == NULL_TREE)
        !           980:        TREE_INLINE (i->fndecl) = 1;
        !           981:       DECL_PENDING_INLINE_INFO (i->fndecl) = 0;
        !           982:     }
        !           983:   extract_interface_info ();
        !           984: }
        !           985: 
        !           986: /* Since inline methods can refer to text which has not yet been seen,
        !           987:    we store the text of the method in a structure which is placed in the
        !           988:    DECL_PENDING_INLINE_INFO field of the FUNCTION_DECL.
        !           989:    After parsing the body of the class definition, the FUNCTION_DECL's are
        !           990:    scanned to see which ones have this field set.  Those are then digested
        !           991:    one at a time.
        !           992: 
        !           993:    This function's FUNCTION_DECL will have a bit set in its common so
        !           994:    that we know to watch out for it.  */
        !           995: 
        !           996: void
        !           997: consume_string (this_obstack)
        !           998:      register struct obstack *this_obstack;
        !           999: {
        !          1000:   register char c;
        !          1001:   do
        !          1002:     {
        !          1003:       c = getch ();
        !          1004:       if (c == '\\')
        !          1005:        {
        !          1006:          obstack_1grow (this_obstack, c);
        !          1007:          c = getch ();
        !          1008:          obstack_1grow (this_obstack, c);
        !          1009:          continue;
        !          1010:        }
        !          1011:       if (c == '\n')
        !          1012:        {
        !          1013:          if (pedantic)
        !          1014:            warning ("ANSI C forbids newline in string constant");
        !          1015:          lineno++;
        !          1016:        }
        !          1017:       obstack_1grow (this_obstack, c);
        !          1018:     }
        !          1019:   while (c != '\"');
        !          1020: }
        !          1021: 
        !          1022: static int nextchar = -1;
        !          1023: static int nextyychar = YYEMPTY;
        !          1024: static YYSTYPE nextyylval;
        !          1025: static tree nextlastiddecl;
        !          1026: 
        !          1027: struct pending_input {
        !          1028:   int nextchar, yychar, nextyychar, eof;
        !          1029:   YYSTYPE yylval, nextyylval;
        !          1030:   struct obstack token_obstack;
        !          1031:   int first_token;
        !          1032: };
        !          1033: 
        !          1034: struct pending_input *
        !          1035: save_pending_input ()
        !          1036: {
        !          1037:   struct pending_input *p;
        !          1038:   p = (struct pending_input *) xmalloc (sizeof (struct pending_input));
        !          1039:   p->nextchar = nextchar;
        !          1040:   p->yychar = yychar;
        !          1041:   p->nextyychar = nextyychar;
        !          1042:   p->yylval = yylval;
        !          1043:   p->nextyylval = nextyylval;
        !          1044:   p->eof = end_of_file;
        !          1045:   yychar = nextyychar = YYEMPTY;
        !          1046:   nextchar = -1;
        !          1047:   p->first_token = first_token;
        !          1048:   p->token_obstack = token_obstack;
        !          1049: 
        !          1050:   first_token = 0;
        !          1051:   gcc_obstack_init (&token_obstack);
        !          1052:   end_of_file = 0;
        !          1053:   return p;
        !          1054: }
        !          1055: 
        !          1056: void
        !          1057: restore_pending_input (p)
        !          1058:      struct pending_input *p;
        !          1059: {
        !          1060:   assert (nextchar == -1);
        !          1061:   nextchar = p->nextchar;
        !          1062:   assert (yychar == YYEMPTY || yychar == END_OF_SAVED_INPUT);
        !          1063:   yychar = p->yychar;
        !          1064:   assert (nextyychar == YYEMPTY);
        !          1065:   nextyychar = p->nextyychar;
        !          1066:   yylval = p->yylval;
        !          1067:   nextyylval = p->nextyylval;
        !          1068:   first_token = p->first_token;
        !          1069:   obstack_free (&token_obstack, (char *) 0);
        !          1070:   token_obstack = p->token_obstack;
        !          1071:   end_of_file = p->eof;
        !          1072:   free (p);
        !          1073: }
        !          1074: 
        !          1075: /* Return next non-whitespace input character, which may come
        !          1076:    from `finput', or from `nextchar'.  */
        !          1077: static int
        !          1078: yynextch ()
        !          1079: {
        !          1080:   int c;
        !          1081: 
        !          1082:   if (nextchar >= 0)
        !          1083:     {
        !          1084:       c = nextchar;
        !          1085:       nextchar = -1;
        !          1086:     }
        !          1087:   else c = getch ();
        !          1088:   return skip_white_space (c);
        !          1089: }
        !          1090: 
        !          1091: /* Unget character CH from the input stream.
        !          1092:    If RESCAN is non-zero, then we want to `see' this
        !          1093:    character as the next input token.  */
        !          1094: void
        !          1095: yyungetc (ch, rescan)
        !          1096:      int ch;
        !          1097:      int rescan;
        !          1098: {
        !          1099:   /* Unget a character from the input stream.  */
        !          1100:   if (yychar == YYEMPTY || rescan == 0)
        !          1101:     {
        !          1102:       if (nextchar >= 0)
        !          1103:        put_back (nextchar);
        !          1104:       nextchar = ch;
        !          1105:     }
        !          1106:   else
        !          1107:     {
        !          1108:       assert (nextyychar == YYEMPTY);
        !          1109:       nextyychar = yychar;
        !          1110:       nextyylval = yylval;
        !          1111:       yychar = ch;
        !          1112:     }
        !          1113: }
        !          1114: 
        !          1115: /* This function stores away the text for an inline function that should
        !          1116:    be processed later.  It decides how much later, and may need to move
        !          1117:    the info between obstacks; therefore, the caller should not refer to
        !          1118:    the T parameter after calling this function.
        !          1119: 
        !          1120:    This function also stores the list of template-parameter bindings that
        !          1121:    will be needed for expanding the template, if any.  */
        !          1122: 
        !          1123: static void
        !          1124: store_pending_inline (decl, t)
        !          1125:      tree decl;
        !          1126:      struct pending_inline *t;
        !          1127: {
        !          1128:   extern int processing_template_defn;
        !          1129:   int delay_to_eof = 0;
        !          1130:   struct pending_inline **inlines;
        !          1131: 
        !          1132:   t->fndecl = decl;
        !          1133:   /* Default: compile right away, and no extra bindings are needed.  */
        !          1134:   t->parm_vec = t->bindings = 0;
        !          1135:   if (processing_template_defn)
        !          1136:     {
        !          1137:       tree type = current_class_type;
        !          1138:       /* Assumption: In this (possibly) nested class sequence, only
        !          1139:         one name will have template parms.  */
        !          1140:       while (type)
        !          1141:        {
        !          1142:          tree decl = TYPE_NAME (type);
        !          1143:          tree tmpl = IDENTIFIER_TEMPLATE (DECL_NAME (decl));
        !          1144:          if (tmpl)
        !          1145:            {
        !          1146:              t->parm_vec = DECL_TEMPLATE_INFO (TREE_PURPOSE (tmpl))->parm_vec;
        !          1147:              t->bindings = TREE_VALUE (tmpl);
        !          1148:            }
        !          1149:          type = DECL_CONTEXT (decl);
        !          1150:        }
        !          1151:       if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
        !          1152:          || TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE)
        !          1153:        {
        !          1154:          if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
        !          1155:            assert (TYPE_MAX_VALUE (TREE_TYPE (decl)) == current_class_type);
        !          1156: 
        !          1157:          /* Inline functions can be compiled immediately.  Other functions
        !          1158:             will be output separately, so if we're in interface-only mode,
        !          1159:             punt them now, or output them now if we're doing implementations
        !          1160:             and we know no overrides will exist.  Otherwise, we delay until
        !          1161:             end-of-file, to see if the definition is really required.  */
        !          1162:          if (TREE_INLINE (decl))
        !          1163:            /* delay_to_eof == 0 */;
        !          1164:          else if (current_class_type && !interface_unknown)
        !          1165:            {
        !          1166:              if (interface_only)
        !          1167:                {
        !          1168: #if 0
        !          1169:                  print_node_brief (stderr, "\ndiscarding text for ", decl, 0);
        !          1170: #endif
        !          1171:                  if (t->can_free)
        !          1172:                    obstack_free (&inline_text_obstack, t->buf);
        !          1173:                  DECL_PENDING_INLINE_INFO (decl) = 0;
        !          1174:                  return;
        !          1175:                }
        !          1176:            }
        !          1177:          /* Don't delay the processing of virtual functions.  */
        !          1178:          else if (DECL_VINDEX (decl) == NULL_TREE)
        !          1179:            delay_to_eof = 1;
        !          1180:        }
        !          1181:       else
        !          1182:        abort ();
        !          1183:     }
        !          1184: 
        !          1185:   if (delay_to_eof)
        !          1186:     {
        !          1187:       extern struct pending_inline *pending_template_expansions;
        !          1188: 
        !          1189:       if (t->can_free)
        !          1190:        {
        !          1191:          char *free_to = t->buf;
        !          1192:          t->buf = (char *) obstack_copy (&permanent_obstack, t->buf,
        !          1193:                                          t->len + 1);
        !          1194:          t = (struct pending_inline *) obstack_copy (&permanent_obstack, t,
        !          1195:                                                      sizeof (*t));
        !          1196:          obstack_free (&inline_text_obstack, free_to);
        !          1197:        }
        !          1198:       inlines = &pending_template_expansions;
        !          1199:       t->can_free = 0;
        !          1200:     }
        !          1201:   else
        !          1202:     {
        !          1203:       inlines = &pending_inlines;
        !          1204:       DECL_PENDING_INLINE_INFO (decl) = t;
        !          1205:     }
        !          1206: 
        !          1207:   /* Because we use obstacks, we must process these in precise order.  */
        !          1208:   t->next = *inlines;
        !          1209:   *inlines = t;
        !          1210: }
        !          1211: 
        !          1212: void reinit_parse_for_block ();
        !          1213: 
        !          1214: void
        !          1215: reinit_parse_for_method (yychar, decl)
        !          1216:      int yychar;
        !          1217:      tree decl;
        !          1218: {
        !          1219:   int len;
        !          1220:   int starting_lineno = lineno;
        !          1221:   char *starting_filename = input_filename;
        !          1222: 
        !          1223:   reinit_parse_for_block (yychar, &inline_text_obstack, 0);
        !          1224: 
        !          1225:   len = obstack_object_size (&inline_text_obstack);
        !          1226:   current_base_init_list = NULL_TREE;
        !          1227:   current_member_init_list = NULL_TREE;
        !          1228:   if (decl == void_type_node
        !          1229:       || (current_class_type && TYPE_REDEFINED (current_class_type)))
        !          1230:     {
        !          1231:       /* Happens when we get two declarations of the same
        !          1232:         function in the same scope.  */
        !          1233:       char *buf = obstack_finish (&inline_text_obstack);
        !          1234:       obstack_free (&inline_text_obstack, buf);
        !          1235:       return;
        !          1236:     }
        !          1237:   else
        !          1238:     {
        !          1239:       struct pending_inline *t;
        !          1240:       char *buf = obstack_finish (&inline_text_obstack);
        !          1241: 
        !          1242:       t = (struct pending_inline *) obstack_alloc (&inline_text_obstack,
        !          1243:                                                   sizeof (struct pending_inline));
        !          1244:       t->buf = buf;
        !          1245:       t->len = len;
        !          1246:       t->lineno = starting_lineno;
        !          1247:       t->filename = starting_filename;
        !          1248:       t->token = YYEMPTY;
        !          1249:       t->can_free = 1;
        !          1250:       t->deja_vu = 0;
        !          1251:       store_pending_inline (decl, t);
        !          1252:     }
        !          1253: }
        !          1254: 
        !          1255: /* Consume a block -- actually, a method or template definition beginning
        !          1256:    with `:' or `{' -- and save it away on the specified obstack.
        !          1257: 
        !          1258:    Argument IS_TEMPLATE indicates which set of error messages should be
        !          1259:    output if something goes wrong.  This should really be cleaned up somehow,
        !          1260:    without loss of clarity.  */
        !          1261: void
        !          1262: reinit_parse_for_block (yychar, obstackp, is_template)
        !          1263:      int yychar;
        !          1264:      struct obstack *obstackp;
        !          1265:      int is_template;
        !          1266: {
        !          1267:   register int c = 0;
        !          1268:   int blev = 1;
        !          1269:   int starting_lineno = lineno;
        !          1270:   char *starting_filename = input_filename;
        !          1271:   int len;
        !          1272:   int look_for_semicolon = 0;
        !          1273: 
        !          1274:   if (yychar == '{')
        !          1275:     obstack_1grow (obstackp, '{');
        !          1276:   else if (yychar == '=')
        !          1277:     {
        !          1278:       look_for_semicolon = 1;
        !          1279:     }
        !          1280:   else
        !          1281:     {
        !          1282:       if (yychar != ':' && (yychar != RETURN || is_template))
        !          1283:        {
        !          1284:          yyerror (is_template
        !          1285:                   ? "parse error in template specification"
        !          1286:                   : "parse error in method specification");
        !          1287:          yychar = '{';
        !          1288:        }
        !          1289:       obstack_1grow (obstackp, yychar);
        !          1290:       while (c >= 0)
        !          1291:        {
        !          1292:          int this_lineno = lineno;
        !          1293: 
        !          1294:          c = yynextch ();
        !          1295: 
        !          1296:          /* Don't lose our cool if there are lots of comments.  */
        !          1297:          if (lineno == this_lineno)
        !          1298:            ;
        !          1299:          else if (lineno - this_lineno < 10 /* + strlen (input_filename) */)
        !          1300:            {
        !          1301:              int i;
        !          1302:              for (i = lineno - this_lineno; i > 0; i--)
        !          1303:                obstack_1grow (obstackp, '\n');
        !          1304:            }
        !          1305:          else
        !          1306:            {
        !          1307:              char buf[12];
        !          1308:              sprintf (buf, "\n# %d \"", lineno);
        !          1309:              len = strlen (buf);
        !          1310:              obstack_grow (obstackp, buf, len);
        !          1311: 
        !          1312:              len = strlen (input_filename);
        !          1313:              obstack_grow (obstackp, input_filename, len);
        !          1314:              obstack_1grow (obstackp, '\"');
        !          1315:              obstack_1grow (obstackp, '\n');
        !          1316:            }
        !          1317: 
        !          1318:          /* strings must be read differently than text.  */
        !          1319:          if (c == '\"')
        !          1320:            {
        !          1321:              obstack_1grow (obstackp, c);
        !          1322:              consume_string (obstackp);
        !          1323:              c = yynextch ();
        !          1324:            }
        !          1325:          while (c > ' ')       /* ASCII dependent! */
        !          1326:            {
        !          1327:              obstack_1grow (obstackp, c);
        !          1328:              if (c == '{') goto main_loop;
        !          1329:              if (c == '\"')
        !          1330:                consume_string (obstackp);
        !          1331:              if (c == ';')
        !          1332:                {
        !          1333:                  error (is_template
        !          1334:                         ? "template body missing"
        !          1335:                         : "function body for constructor missing");
        !          1336:                  obstack_1grow (obstackp, '{');
        !          1337:                  obstack_1grow (obstackp, '}');
        !          1338:                  len += 2;
        !          1339:                  goto done;
        !          1340:                }
        !          1341:              c = getch ();
        !          1342:            }
        !          1343:          if (c == '\n')
        !          1344:            lineno++;
        !          1345:          obstack_1grow (obstackp, c);
        !          1346:        }
        !          1347:       if (c == EOF)
        !          1348:        {
        !          1349:          error_with_file_and_line (starting_filename,
        !          1350:                                    starting_lineno,
        !          1351:                                    "end of file read inside definition");
        !          1352:        }         
        !          1353:     }
        !          1354: 
        !          1355:  main_loop:
        !          1356:   while (c >= 0)
        !          1357:     {
        !          1358:       int this_lineno = lineno;
        !          1359: 
        !          1360:       c = skip_white_space (getch ());
        !          1361: 
        !          1362:       /* Don't lose our cool if there are lots of comments.  */
        !          1363:       if (lineno - this_lineno)
        !          1364:        if (lineno - this_lineno == 1)
        !          1365:          obstack_1grow (obstackp, '\n');
        !          1366:        else
        !          1367:          {
        !          1368:            char buf[12];
        !          1369:            sprintf (buf, "\n# %d \"", lineno);
        !          1370:            len = strlen (buf);
        !          1371:            obstack_grow (obstackp, buf, len);
        !          1372: 
        !          1373:            len = strlen (input_filename);
        !          1374:            obstack_grow (obstackp, input_filename, len);
        !          1375:            obstack_1grow (obstackp, '\"');
        !          1376:            obstack_1grow (obstackp, '\n');
        !          1377:          }
        !          1378: 
        !          1379:       while (c > ' ')
        !          1380:        {
        !          1381:          obstack_1grow (obstackp, c);
        !          1382:          if (c == '{') blev++;
        !          1383:          else if (c == '}')
        !          1384:            {
        !          1385:              blev--;
        !          1386:              if (blev == 0 && !look_for_semicolon)
        !          1387:                goto done;
        !          1388:            }
        !          1389:          else if (c == '\"')
        !          1390:            consume_string (obstackp);
        !          1391:          else if (c == ';' && look_for_semicolon && blev == 0)
        !          1392:            goto done;
        !          1393:          c = getch ();
        !          1394:        }
        !          1395:       if (c == '\n')
        !          1396:        lineno++;
        !          1397:       obstack_1grow (obstackp, c);
        !          1398:     }
        !          1399:  done:
        !          1400:   obstack_1grow (obstackp, '\0');
        !          1401: }
        !          1402: 
        !          1403: /* Build a default function named NAME for type TYPE.
        !          1404:    KIND says what to build.
        !          1405: 
        !          1406:    When KIND == 0, build default destructor.
        !          1407:    When KIND == 1, build virtual destructor.
        !          1408:    When KIND == 2, build default constructor.
        !          1409:    When KIND == 3, build default X(const X&) constructor.
        !          1410:    When KIND == 4, build default X(X&) constructor.  */
        !          1411: 
        !          1412: tree
        !          1413: cons_up_default_function (type, name, kind)
        !          1414:      tree type, name;
        !          1415:      int kind;
        !          1416: {
        !          1417:   extern tree void_list_node, constructor_name ();
        !          1418:   int len;
        !          1419:   tree declspecs = NULL_TREE;
        !          1420:   tree fn, args;
        !          1421:   tree argtype;
        !          1422: 
        !          1423:   name = constructor_name (name);
        !          1424:   switch (kind)
        !          1425:     {
        !          1426:       /* Destructors.  */
        !          1427:     case 1:
        !          1428:       declspecs = build_decl_list (NULL_TREE, ridpointers [(int) RID_VIRTUAL]);
        !          1429:       /* Fall through...  */
        !          1430:     case 0:
        !          1431:       name = build_parse_node (BIT_NOT_EXPR, name);
        !          1432:       /* Fall through...  */
        !          1433:     case 2:
        !          1434:       /* Default constructor.  */
        !          1435:       args = void_list_node;
        !          1436:       break;
        !          1437: 
        !          1438:     case 3:
        !          1439:       type = build_type_variant (type, 1, 0);
        !          1440:       /* Fall through...  */
        !          1441:     case 4:
        !          1442:       argtype = build_reference_type (type);
        !          1443:       args = tree_cons (NULL_TREE,
        !          1444:                        build_tree_list (hash_tree_chain (argtype, NULL_TREE),
        !          1445:                                         get_identifier ("arg")),
        !          1446:                        void_list_node);
        !          1447:       break;
        !          1448: 
        !          1449:     default:
        !          1450:       abort ();
        !          1451:     }
        !          1452: 
        !          1453:   fn = start_method (declspecs,
        !          1454:                     build_parse_node (CALL_EXPR, name, args, NULL_TREE),
        !          1455:                     NULL_TREE);
        !          1456:   if (fn == void_type_node)
        !          1457:     return fn;
        !          1458: 
        !          1459:   current_base_init_list = NULL_TREE;
        !          1460:   current_member_init_list = NULL_TREE;
        !          1461: 
        !          1462:   len = 3;
        !          1463: 
        !          1464:   {
        !          1465:     struct pending_inline *t;
        !          1466: 
        !          1467:     t = (struct pending_inline *) obstack_alloc (&inline_text_obstack,
        !          1468:                                                 sizeof (struct pending_inline));
        !          1469:     t->buf = default_def;
        !          1470:     t->len = len;
        !          1471:     t->lineno = lineno;
        !          1472:     t->filename = input_filename;
        !          1473:     t->token = YYEMPTY;
        !          1474:     t->can_free = 0;
        !          1475:     t->deja_vu = 0;
        !          1476:     store_pending_inline (fn, t);
        !          1477:     /* We make this declaration private (static in the C sense).  */
        !          1478:     TREE_PUBLIC (fn) = 0;
        !          1479:   }
        !          1480:   finish_method (fn);
        !          1481:   DECL_CLASS_CONTEXT (fn) = type;
        !          1482:   /* Show that this function was generated by the compiler.  */
        !          1483:   DECL_IGNORED_P (fn) = 1;
        !          1484:   return fn;
        !          1485: }
        !          1486: 
        !          1487: /* Heuristic to tell whether the user is missing a semicolon
        !          1488:    after a struct or enum declaration.  Emit an error message
        !          1489:    if we know the user has blown it.  */
        !          1490: void
        !          1491: check_for_missing_semicolon (type)
        !          1492:      tree type;
        !          1493: {
        !          1494:   if (yychar < 0)
        !          1495:     yychar = yylex ();
        !          1496: 
        !          1497:   if (yychar > 255
        !          1498:       && yychar != IDENTIFIER
        !          1499:       && yychar != TYPENAME)
        !          1500:     {
        !          1501:       if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (type)))
        !          1502:        error ("semicolon missing after %s declaration",
        !          1503:               TREE_CODE (type) == ENUMERAL_TYPE ? "enum" : "struct");
        !          1504:       else
        !          1505:        error ("semicolon missing after declaration of `%s'",
        !          1506:               TYPE_NAME_STRING (type));
        !          1507:       shadow_tag (build_tree_list (0, type));
        !          1508:     }
        !          1509:   /* Could probably also hack cases where class { ... } f (); appears.  */
        !          1510:   clear_anon_tags ();
        !          1511: }
        !          1512: 
        !          1513: void
        !          1514: note_got_semicolon (type)
        !          1515:      tree type;
        !          1516: {
        !          1517:   if (TREE_CODE_CLASS (TREE_CODE (type)) != 't')
        !          1518:     abort ();
        !          1519:   if (IS_AGGR_TYPE (type))
        !          1520:     CLASSTYPE_GOT_SEMICOLON (type) = 1;
        !          1521: }
        !          1522: 
        !          1523: void
        !          1524: note_list_got_semicolon (declspecs)
        !          1525:      tree declspecs;
        !          1526: {
        !          1527:   tree link;
        !          1528: 
        !          1529:   for (link = declspecs; link; link = TREE_CHAIN (link))
        !          1530:     {
        !          1531:       tree type = TREE_VALUE (link);
        !          1532:       if (TREE_CODE_CLASS (TREE_CODE (type)) == 't')
        !          1533:        note_got_semicolon (type);
        !          1534:     }
        !          1535:   clear_anon_tags ();
        !          1536: }
        !          1537: 
        !          1538: /* If C is not whitespace, return C.
        !          1539:    Otherwise skip whitespace and return first nonwhite char read.  */
        !          1540: 
        !          1541: static int
        !          1542: skip_white_space (c)
        !          1543:      register int c;
        !          1544: {
        !          1545:   for (;;)
        !          1546:     {
        !          1547:       switch (c)
        !          1548:        {
        !          1549:        case '\n':
        !          1550:          c = check_newline ();
        !          1551:          break;
        !          1552: 
        !          1553:        case ' ':
        !          1554:        case '\t':
        !          1555:        case '\f':
        !          1556:        case '\r':
        !          1557:        case '\v':
        !          1558:        case '\b':
        !          1559:          do
        !          1560:            c = getch ();
        !          1561:          while (c == ' ' || c == '\t');
        !          1562:          break;
        !          1563: 
        !          1564:        case '\\':
        !          1565:          c = getch ();
        !          1566:          if (c == '\n')
        !          1567:            lineno++;
        !          1568:          else
        !          1569:            error ("stray '\\' in program");
        !          1570:          c = getch ();
        !          1571:          break;
        !          1572: 
        !          1573:        default:
        !          1574:          return (c);
        !          1575:        }
        !          1576:     }
        !          1577: }
        !          1578: 
        !          1579: 
        !          1580: 
        !          1581: /* Make the token buffer longer, preserving the data in it.
        !          1582:    P should point to just beyond the last valid character in the old buffer.
        !          1583:    The value we return is a pointer to the new buffer
        !          1584:    at a place corresponding to P.  */
        !          1585: 
        !          1586: static char *
        !          1587: extend_token_buffer (p)
        !          1588:      char *p;
        !          1589: {
        !          1590:   int offset = p - token_buffer;
        !          1591: 
        !          1592:   maxtoken = maxtoken * 2 + 10;
        !          1593:   token_buffer = (char *) xrealloc (token_buffer, maxtoken + 2);
        !          1594: 
        !          1595:   return token_buffer + offset;
        !          1596: }
        !          1597: 
        !          1598: static int
        !          1599: get_last_nonwhite_on_line ()
        !          1600: {
        !          1601:   register int c;
        !          1602: 
        !          1603:   /* Is this the last nonwhite stuff on the line?  */
        !          1604:   if (nextchar >= 0)
        !          1605:     c = nextchar, nextchar = -1;
        !          1606:   else
        !          1607:     c = getch ();
        !          1608: 
        !          1609:   while (c == ' ' || c == '\t')
        !          1610:     c = getch ();
        !          1611:   return c;
        !          1612: }
        !          1613: 
        !          1614: /* At the beginning of a line, increment the line number
        !          1615:    and process any #-directive on this line.
        !          1616:    If the line is a #-directive, read the entire line and return a newline.
        !          1617:    Otherwise, return the line's first non-whitespace character.  */
        !          1618: 
        !          1619: int
        !          1620: check_newline ()
        !          1621: {
        !          1622:   register int c;
        !          1623:   register int token;
        !          1624: 
        !          1625:   lineno++;
        !          1626: 
        !          1627:   /* Read first nonwhite char on the line.  */
        !          1628: 
        !          1629:   do
        !          1630:     c = getch ();
        !          1631:   while (c == ' ' || c == '\t');
        !          1632: 
        !          1633:   if (c != '#')
        !          1634:     {
        !          1635:       /* If not #, return it so caller will use it.  */
        !          1636:       return c;
        !          1637:     }
        !          1638: 
        !          1639:   /* Read first nonwhite char after the `#'.  */
        !          1640: 
        !          1641:   do
        !          1642:     c = getch ();
        !          1643:   while (c == ' ' || c == '\t');
        !          1644: 
        !          1645:   /* If a letter follows, then if the word here is `line', skip
        !          1646:      it and ignore it; otherwise, ignore the line, with an error
        !          1647:      if the word isn't `pragma'.  */
        !          1648: 
        !          1649:   if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
        !          1650:     {
        !          1651:       if (c == 'p')
        !          1652:        {
        !          1653:          if (getch () == 'r'
        !          1654:              && getch () == 'a'
        !          1655:              && getch () == 'g'
        !          1656:              && getch () == 'm'
        !          1657:              && getch () == 'a')
        !          1658:            {
        !          1659:              /* Read first nonwhite char after the `#pragma'.  */
        !          1660: 
        !          1661:              do
        !          1662:                c = getch ();
        !          1663:              while (c == ' ' || c == '\t');
        !          1664: 
        !          1665:              if (c == 'v'
        !          1666:                  && getch () == 't'
        !          1667:                  && getch () == 'a'
        !          1668:                  && getch () == 'b'
        !          1669:                  && getch () == 'l'
        !          1670:                  && getch () == 'e'
        !          1671:                  && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
        !          1672:                {
        !          1673:                  extern tree pending_vtables;
        !          1674: 
        !          1675:                  /* More follows: it must be a string constant (class name).  */
        !          1676:                  token = real_yylex ();
        !          1677:                  if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
        !          1678:                    {
        !          1679:                      error ("invalid #pragma vtable");
        !          1680:                      goto skipline;
        !          1681:                    }
        !          1682:                  if (write_virtuals != 2)
        !          1683:                    {
        !          1684:                      warning ("use `+e2' option to enable #pragma vtable");
        !          1685:                      goto skipline;
        !          1686:                    }
        !          1687:                  pending_vtables = perm_tree_cons (NULL_TREE, get_identifier (TREE_STRING_POINTER (yylval.ttype)), pending_vtables);
        !          1688:                  if (nextchar < 0)
        !          1689:                    nextchar = getch ();
        !          1690:                  c = nextchar;
        !          1691:                  if (c != '\n')
        !          1692:                    warning ("trailing characters ignored");
        !          1693:                }
        !          1694:              else if (c == 'u'
        !          1695:                       && getch () == 'n'
        !          1696:                       && getch () == 'i'
        !          1697:                       && getch () == 't'
        !          1698:                       && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
        !          1699:                {
        !          1700:                  /* More follows: it must be a string constant (unit name).  */
        !          1701:                  token = real_yylex ();
        !          1702:                  if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
        !          1703:                    {
        !          1704:                      error ("invalid #pragma unit");
        !          1705:                      goto skipline;
        !          1706:                    }
        !          1707:                  current_unit_name = get_identifier (TREE_STRING_POINTER (yylval.ttype));
        !          1708:                  current_unit_language = current_lang_name;
        !          1709:                  if (nextchar < 0)
        !          1710:                    nextchar = getch ();
        !          1711:                  c = nextchar;
        !          1712:                  if (c != '\n')
        !          1713:                    warning ("trailing characters ignored");
        !          1714:                }
        !          1715:              else if (c == 'i')
        !          1716:                {
        !          1717:                  tree fileinfo = IDENTIFIER_CLASS_VALUE (get_time_identifier (input_filename));
        !          1718:                  c = getch ();
        !          1719: 
        !          1720:                  if (c == 'n'
        !          1721:                      && getch () == 't'
        !          1722:                      && getch () == 'e'
        !          1723:                      && getch () == 'r'
        !          1724:                      && getch () == 'f'
        !          1725:                      && getch () == 'a'
        !          1726:                      && getch () == 'c'
        !          1727:                      && getch () == 'e'
        !          1728:                      && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
        !          1729:                    {
        !          1730:                      /* read to newline.  */
        !          1731:                      while (c != '\n')
        !          1732:                        c = getch ();
        !          1733: 
        !          1734:                      write_virtuals = 3;
        !          1735: 
        !          1736:                      if (impl_file_chain == 0)
        !          1737:                        {
        !          1738:                          char *filename;
        !          1739:                          tree fi;
        !          1740: 
        !          1741:                          /* If this is zero at this point, then we are
        !          1742:                             auto-implementing.  */
        !          1743:                          if (main_input_filename == 0)
        !          1744:                            main_input_filename = input_filename;
        !          1745: 
        !          1746:                          filename = FILE_NAME_NONDIRECTORY (main_input_filename);
        !          1747:                          fi = get_time_identifier (filename);
        !          1748:                          fi = IDENTIFIER_CLASS_VALUE (fi);
        !          1749:                          TREE_INT_CST_LOW (fi) = 0;
        !          1750:                          TREE_INT_CST_HIGH (fi) = 1;
        !          1751:                          /* Get default.  */
        !          1752:                          impl_file_chain = (struct impl_files *)permalloc (sizeof (struct impl_files));
        !          1753:                          impl_file_chain->filename = filename;
        !          1754:                          impl_file_chain->next = 0;
        !          1755:                        }
        !          1756: 
        !          1757:                      interface_only = interface_strcmp (input_filename);
        !          1758:                      interface_unknown = 0;
        !          1759:                      TREE_INT_CST_LOW (fileinfo) = interface_only;
        !          1760:                      TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
        !          1761:                    }
        !          1762:                  else if (c == 'm'
        !          1763:                           && getch () == 'p'
        !          1764:                           && getch () == 'l'
        !          1765:                           && getch () == 'e'
        !          1766:                           && getch () == 'm'
        !          1767:                           && getch () == 'e'
        !          1768:                           && getch () == 'n'
        !          1769:                           && getch () == 't'
        !          1770:                           && getch () == 'a'
        !          1771:                           && getch () == 't'
        !          1772:                           && getch () == 'i'
        !          1773:                           && getch () == 'o'
        !          1774:                           && getch () == 'n'
        !          1775:                           && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
        !          1776:                    {
        !          1777:                      char *main_filename = main_input_filename ? main_input_filename : input_filename;
        !          1778:                      char *tmp;
        !          1779: 
        !          1780:                      while (c == ' ' || c == '\t')
        !          1781:                        c = getch ();
        !          1782:                      if (c != '\n')
        !          1783:                        {
        !          1784:                          put_back (c);
        !          1785:                          token = real_yylex ();
        !          1786:                          if (token != STRING
        !          1787:                              || TREE_CODE (yylval.ttype) != STRING_CST)
        !          1788:                            {
        !          1789:                              error ("invalid `#pragma implementation'");
        !          1790:                              goto skipline;
        !          1791:                            }
        !          1792:                          main_filename = TREE_STRING_POINTER (yylval.ttype);
        !          1793:                        }
        !          1794:                      main_filename = FILE_NAME_NONDIRECTORY (main_filename);
        !          1795: 
        !          1796:                      /* read to newline.  */
        !          1797:                      while (c != '\n')
        !          1798:                        c = getch ();
        !          1799: 
        !          1800:                      if (write_virtuals == 3)
        !          1801:                        {
        !          1802:                          struct impl_files *ifiles = impl_file_chain;
        !          1803:                          while (ifiles)
        !          1804:                            {
        !          1805:                              if (! strcmp (ifiles->filename, main_filename))
        !          1806:                                break;
        !          1807:                              ifiles = ifiles->next;
        !          1808:                            }
        !          1809:                          if (ifiles == 0)
        !          1810:                            {
        !          1811:                              ifiles = (struct impl_files*) permalloc (sizeof (struct impl_files));
        !          1812:                              ifiles->filename = main_filename;
        !          1813:                              ifiles->next = impl_file_chain;
        !          1814:                              impl_file_chain = ifiles;
        !          1815:                            }
        !          1816:                        }
        !          1817:                      else if (main_input_filename == input_filename
        !          1818:                               || ! strcmp (input_filename, main_filename))
        !          1819:                        {
        !          1820:                          write_virtuals = 3;
        !          1821:                          if (impl_file_chain == 0)
        !          1822:                            {
        !          1823:                              impl_file_chain = (struct impl_files*) permalloc (sizeof (struct impl_files));
        !          1824:                              impl_file_chain->filename = main_filename;
        !          1825:                              impl_file_chain->next = 0;
        !          1826:                            }
        !          1827:                        }
        !          1828:                      else
        !          1829:                        error ("`#pragma implementation' can only appear at top-level");
        !          1830:                      interface_only = 0;
        !          1831:                      /* We make this non-zero so that we infer decl linkage
        !          1832:                         in the impl file only for variables first declared
        !          1833:                         in the interface file.  */
        !          1834:                      interface_unknown = 1;
        !          1835:                      TREE_INT_CST_LOW (fileinfo) = interface_only;
        !          1836:                      TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
        !          1837:                    }
        !          1838:                }
        !          1839:            }
        !          1840:          goto skipline;
        !          1841:        }
        !          1842:       else if (c == 'd')
        !          1843:        {
        !          1844:          if (getch () == 'e'
        !          1845:              && getch () == 'f'
        !          1846:              && getch () == 'i'
        !          1847:              && getch () == 'n'
        !          1848:              && getch () == 'e'
        !          1849:              && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
        !          1850:            {
        !          1851: #ifdef DWARF_DEBUGGING_INFO
        !          1852:              if ((debug_info_level == DINFO_LEVEL_VERBOSE)
        !          1853:                  && (write_symbols == DWARF_DEBUG))
        !          1854:                dwarfout_define (lineno, get_directive_line (finput));
        !          1855: #endif /* DWARF_DEBUGGING_INFO */
        !          1856:              goto skipline;
        !          1857:            }
        !          1858:        }
        !          1859:       else if (c == 'u')
        !          1860:        {
        !          1861:          if (getch () == 'n'
        !          1862:              && getch () == 'd'
        !          1863:              && getch () == 'e'
        !          1864:              && getch () == 'f'
        !          1865:              && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
        !          1866:            {
        !          1867: #ifdef DWARF_DEBUGGING_INFO
        !          1868:              if ((debug_info_level == DINFO_LEVEL_VERBOSE)
        !          1869:                  && (write_symbols == DWARF_DEBUG))
        !          1870:                dwarfout_undef (lineno, get_directive_line (finput));
        !          1871: #endif /* DWARF_DEBUGGING_INFO */
        !          1872:              goto skipline;
        !          1873:            }
        !          1874:        }
        !          1875:       else if (c == 'l')
        !          1876:        {
        !          1877:          if (getch () == 'i'
        !          1878:              && getch () == 'n'
        !          1879:              && getch () == 'e'
        !          1880:              && ((c = getch ()) == ' ' || c == '\t'))
        !          1881:            goto linenum;
        !          1882:        }
        !          1883:       else if (c == 'i')
        !          1884:        {
        !          1885:          if (getch () == 'd'
        !          1886:              && getch () == 'e'
        !          1887:              && getch () == 'n'
        !          1888:              && getch () == 't'
        !          1889:              && ((c = getch ()) == ' ' || c == '\t'))
        !          1890:            {
        !          1891:              /* Conditionally used.  */
        !          1892:               extern FILE *asm_out_file;
        !          1893: 
        !          1894:              if (pedantic)
        !          1895:                error ("ANSI C does not allow #ident");
        !          1896: 
        !          1897:              /* Here we have just seen `#ident '.
        !          1898:                 A string constant should follow.  */
        !          1899: 
        !          1900:              while (c == ' ' || c == '\t')
        !          1901:                c = getch ();
        !          1902: 
        !          1903:              /* If no argument, ignore the line.  */
        !          1904:              if (c == '\n')
        !          1905:                return c;
        !          1906: 
        !          1907:              put_back (c);
        !          1908:              token = real_yylex ();
        !          1909:              if (token != STRING
        !          1910:                  || TREE_CODE (yylval.ttype) != STRING_CST)
        !          1911:                {
        !          1912:                  error ("invalid #ident");
        !          1913:                  goto skipline;
        !          1914:                }
        !          1915: 
        !          1916: #ifdef ASM_OUTPUT_IDENT
        !          1917:              ASM_OUTPUT_IDENT (asm_out_file, TREE_STRING_POINTER (yylval.ttype));
        !          1918: #endif
        !          1919: 
        !          1920:              /* Skip the rest of this line.  */
        !          1921:              goto skipline;
        !          1922:            }
        !          1923:        }
        !          1924:       else if (c == 'n')
        !          1925:        {
        !          1926:          if (getch () == 'e'
        !          1927:              && getch () == 'w'
        !          1928:              && getch () == 'w'
        !          1929:              && getch () == 'o'
        !          1930:              && getch () == 'r'
        !          1931:              && getch () == 'l'
        !          1932:              && getch () == 'd'
        !          1933:              && ((c = getch ()) == ' ' || c == '\t'))
        !          1934:            {
        !          1935:              /* Used to test incremental compilation.  */
        !          1936:              sorry ("#pragma newworld");
        !          1937:              goto skipline;
        !          1938:            }
        !          1939:        }
        !          1940:       error ("undefined or invalid # directive");
        !          1941:       goto skipline;
        !          1942:     }
        !          1943: 
        !          1944: linenum:
        !          1945:   /* Here we have either `#line' or `# <nonletter>'.
        !          1946:      In either case, it should be a line number; a digit should follow.  */
        !          1947: 
        !          1948:   while (c == ' ' || c == '\t')
        !          1949:     c = getch ();
        !          1950: 
        !          1951:   /* If the # is the only nonwhite char on the line,
        !          1952:      just ignore it.  Check the new newline.  */
        !          1953:   if (c == '\n')
        !          1954:     return c;
        !          1955: 
        !          1956:   /* Something follows the #; read a token.  */
        !          1957: 
        !          1958:   put_back (c);
        !          1959:   token = real_yylex ();
        !          1960: 
        !          1961:   if (token == CONSTANT
        !          1962:       && TREE_CODE (yylval.ttype) == INTEGER_CST)
        !          1963:     {
        !          1964:       int old_lineno = lineno;
        !          1965:       int used_up = 0;
        !          1966:       /* subtract one, because it is the following line that
        !          1967:         gets the specified number */
        !          1968: 
        !          1969:       int l = TREE_INT_CST_LOW (yylval.ttype) - 1;
        !          1970:       c = get_last_nonwhite_on_line ();
        !          1971:       if (c == '\n')
        !          1972:        {
        !          1973:          /* No more: store the line number and check following line.  */
        !          1974:          lineno = l;
        !          1975:          return c;
        !          1976:        }
        !          1977:       put_back (c);
        !          1978: 
        !          1979:       /* More follows: it must be a string constant (filename).  */
        !          1980: 
        !          1981:       token = real_yylex ();
        !          1982:       if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
        !          1983:        {
        !          1984:          error ("invalid #line");
        !          1985:          goto skipline;
        !          1986:        }
        !          1987: 
        !          1988:       /* Changing files again.  This means currently collected time
        !          1989:         is charged against header time, and body time starts back
        !          1990:         at 0.  */
        !          1991:       if (flag_detailed_statistics)
        !          1992:        {
        !          1993:          int this_time = my_get_run_time ();
        !          1994:          tree time_identifier = get_time_identifier (TREE_STRING_POINTER (yylval.ttype));
        !          1995:          header_time += this_time - body_time;
        !          1996:          TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time))
        !          1997:            += this_time - body_time;
        !          1998:          this_filename_time = time_identifier;
        !          1999:          body_time = this_time;
        !          2000:        }
        !          2001: 
        !          2002:       if (flag_cadillac)
        !          2003:        cadillac_note_source ();
        !          2004: 
        !          2005:       input_filename
        !          2006:        = (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1);
        !          2007:       strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype));
        !          2008:       lineno = l;
        !          2009:       GNU_xref_file (input_filename);
        !          2010: 
        !          2011:       /* Each change of file name
        !          2012:         reinitializes whether we are now in a system header.  */
        !          2013:       in_system_header = 0;
        !          2014: 
        !          2015:       if (main_input_filename == 0)
        !          2016:        {
        !          2017:          struct impl_files *ifiles = impl_file_chain;
        !          2018: 
        !          2019:          if (ifiles)
        !          2020:            {
        !          2021:              while (ifiles->next)
        !          2022:                ifiles = ifiles->next;
        !          2023:              ifiles->filename = FILE_NAME_NONDIRECTORY (input_filename);
        !          2024:            }
        !          2025: 
        !          2026:          main_input_filename = input_filename;
        !          2027:          if (write_virtuals == 3)
        !          2028:            walk_vtables (set_typedecl_interface_info, set_vardecl_interface_info);
        !          2029:        }
        !          2030: 
        !          2031:       extract_interface_info ();
        !          2032: 
        !          2033:       c = get_last_nonwhite_on_line ();
        !          2034:       if (c == '\n')
        !          2035:        {
        !          2036:          if (flag_cadillac)
        !          2037:            cadillac_switch_source (-1);
        !          2038:          return c;
        !          2039:        }
        !          2040:       put_back (c);
        !          2041: 
        !          2042:       token = real_yylex ();
        !          2043:       used_up = 0;
        !          2044: 
        !          2045:       /* `1' after file name means entering new file.
        !          2046:         `2' after file name means just left a file.  */
        !          2047: 
        !          2048:       if (token == CONSTANT
        !          2049:          && TREE_CODE (yylval.ttype) == INTEGER_CST)
        !          2050:        {
        !          2051:          if (TREE_INT_CST_LOW (yylval.ttype) == 1)
        !          2052:            {
        !          2053:              /* Pushing to a new file.  */
        !          2054:              struct file_stack *p
        !          2055:                = (struct file_stack *) xmalloc (sizeof (struct file_stack));
        !          2056:              input_file_stack->line = old_lineno;
        !          2057:              p->next = input_file_stack;
        !          2058:              p->name = input_filename;
        !          2059:              input_file_stack = p;
        !          2060:              input_file_stack_tick++;
        !          2061: #ifdef DWARF_DEBUGGING_INFO
        !          2062:              if (debug_info_level == DINFO_LEVEL_VERBOSE
        !          2063:                  && write_symbols == DWARF_DEBUG)
        !          2064:                dwarfout_start_new_source_file (input_filename);
        !          2065: #endif /* DWARF_DEBUGGING_INFO */
        !          2066: 
        !          2067:              used_up = 1;
        !          2068:              if (flag_cadillac)
        !          2069:                cadillac_push_source ();
        !          2070:            }
        !          2071:          else if (TREE_INT_CST_LOW (yylval.ttype) == 2)
        !          2072:            {
        !          2073:              /* Popping out of a file.  */
        !          2074:              if (input_file_stack->next)
        !          2075:                {
        !          2076:                  struct file_stack *p = input_file_stack;
        !          2077: 
        !          2078:                  if (flag_cadillac)
        !          2079:                    cadillac_pop_source ();
        !          2080: 
        !          2081:                  input_file_stack = p->next;
        !          2082:                  free (p);
        !          2083:                  input_file_stack_tick++;
        !          2084: #ifdef DWARF_DEBUGGING_INFO
        !          2085:                  if (debug_info_level == DINFO_LEVEL_VERBOSE
        !          2086:                      && write_symbols == DWARF_DEBUG)
        !          2087:                    dwarfout_resume_previous_source_file (input_file_stack->line);
        !          2088: #endif /* DWARF_DEBUGGING_INFO */
        !          2089:                }
        !          2090:              else
        !          2091:                error ("#-lines for entering and leaving files don't match");
        !          2092: 
        !          2093:              used_up = 1;
        !          2094:            }
        !          2095:        }
        !          2096:       else if (flag_cadillac)
        !          2097:        cadillac_switch_source (-1);
        !          2098: 
        !          2099:       /* If we have handled a `1' or a `2',
        !          2100:         see if there is another number to read.  */
        !          2101:       if (used_up)
        !          2102:        {
        !          2103:          c = get_last_nonwhite_on_line ();
        !          2104:          if (c == '\n')
        !          2105:            {
        !          2106:              if (flag_cadillac)
        !          2107:                cadillac_switch_source (-1);
        !          2108:              return c;
        !          2109:            }
        !          2110:          put_back (c);
        !          2111: 
        !          2112:          token = real_yylex ();
        !          2113:          used_up = 0;
        !          2114:        }
        !          2115: 
        !          2116:       /* `3' after file name means this is a system header file.  */
        !          2117: 
        !          2118:       if (token == CONSTANT
        !          2119:          && TREE_CODE (yylval.ttype) == INTEGER_CST
        !          2120:          && TREE_INT_CST_LOW (yylval.ttype) == 3)
        !          2121:        in_system_header = 1;
        !          2122: 
        !          2123:       /* If NEXTCHAR is not end of line, we don't care what it is.  */
        !          2124:       if (nextchar == '\n')
        !          2125:        return '\n';
        !          2126:     }
        !          2127:   else
        !          2128:     error ("invalid #-line");
        !          2129: 
        !          2130:   /* skip the rest of this line.  */
        !          2131:  skipline:
        !          2132:   if (c == '\n')
        !          2133:     return c;
        !          2134:   while ((c = getch ()) != EOF && c != '\n');
        !          2135:   return c;
        !          2136: }
        !          2137: 
        !          2138: #if 0
        !          2139: #define isalnum(char) (char >= 'a' ? char <= 'z' : char >= '0' ? char <= '9' || (char >= 'A' && char <= 'Z') : 0)
        !          2140: #define isdigit(char) (char >= '0' && char <= '9')
        !          2141: #else
        !          2142: #include <ctype.h>
        !          2143: #endif
        !          2144: 
        !          2145: #define ENDFILE -1  /* token that represents end-of-file */
        !          2146: 
        !          2147: static int
        !          2148: readescape ()
        !          2149: {
        !          2150:   register int c = getch ();
        !          2151:   register unsigned count;
        !          2152:   register int code;
        !          2153:   unsigned firstdig;
        !          2154: 
        !          2155:   switch (c)
        !          2156:     {
        !          2157:     case 'x':
        !          2158:       code = 0;
        !          2159:       count = 0;
        !          2160:       while (1)
        !          2161:        {
        !          2162:          c = getch ();
        !          2163:          if (! isxdigit (c))
        !          2164:            {
        !          2165:              put_back (c);
        !          2166:              break;
        !          2167:            }
        !          2168:          code *= 16;
        !          2169:          if (c >= 'a' && c <= 'f')
        !          2170:            code += c - 'a' + 10;
        !          2171:          if (c >= 'A' && c <= 'F')
        !          2172:            code += c - 'A' + 10;
        !          2173:          if (c >= '0' && c <= '9')
        !          2174:            code += c - '0';
        !          2175:          if (count == 0)
        !          2176:            firstdig = code;
        !          2177:          count++;
        !          2178:        }
        !          2179:       if (count == 0)
        !          2180:        error ("\\x used with no following hex digits");
        !          2181:       else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node)
        !          2182:               || ((1 << (TYPE_PRECISION (integer_type_node) - (count - 1) * 4))
        !          2183:                   <= firstdig))
        !          2184:        warning ("hex escape out of range");
        !          2185:       return code;
        !          2186: 
        !          2187:     case '0':  case '1':  case '2':  case '3':  case '4':
        !          2188:     case '5':  case '6':  case '7':
        !          2189:       code = 0;
        !          2190:       count = 0;
        !          2191:       while ((c <= '7') && (c >= '0') && (count++ < 3))
        !          2192:        {
        !          2193:          code = (code * 8) + (c - '0');
        !          2194:          c = getch ();
        !          2195:        }
        !          2196:       put_back (c);
        !          2197:       return code;
        !          2198: 
        !          2199:     case '\\': case '\'': case '"':
        !          2200:       return c;
        !          2201: 
        !          2202:     case '\n':
        !          2203:       lineno++;
        !          2204:       return -1;
        !          2205: 
        !          2206:     case 'n':
        !          2207:       return TARGET_NEWLINE;
        !          2208: 
        !          2209:     case 't':
        !          2210:       return TARGET_TAB;
        !          2211: 
        !          2212:     case 'r':
        !          2213:       return TARGET_CR;
        !          2214: 
        !          2215:     case 'f':
        !          2216:       return TARGET_FF;
        !          2217: 
        !          2218:     case 'b':
        !          2219:       return TARGET_BS;
        !          2220: 
        !          2221:     case 'a':
        !          2222:       return TARGET_BELL;
        !          2223: 
        !          2224:     case 'v':
        !          2225:       return TARGET_VT;
        !          2226: 
        !          2227:     case 'E':
        !          2228:       return 033;
        !          2229: 
        !          2230:     case '?':
        !          2231:       /* `\(', etc, are used at beginning of line to avoid confusing Emacs.  */
        !          2232:     case '(':
        !          2233:     case '{':
        !          2234:     case '[':
        !          2235:       return c;
        !          2236:     }
        !          2237:   if (c >= 040 && c <= 0177)
        !          2238:     warning ("unknown escape sequence `\\%c'", c);
        !          2239:   else
        !          2240:     warning ("unknown escape sequence: `\\' followed by char code 0x%x", c);
        !          2241:   return c;
        !          2242: }
        !          2243: 
        !          2244: /* Value is 1 if we should try to make the next identifier look like a
        !          2245:    typename (when it may be a local variable or a class variable).
        !          2246:    Value is 0 if we treat this name in a default fashion.
        !          2247:    Value is -1 if we must not see a type name.  */
        !          2248: int looking_for_typename = 0;
        !          2249: 
        !          2250: void
        !          2251: dont_see_typename ()
        !          2252: {
        !          2253:   looking_for_typename = -1;
        !          2254:   if (yychar == TYPENAME || yychar == PTYPENAME)
        !          2255:     {
        !          2256:       yychar = IDENTIFIER;
        !          2257:       lastiddecl = 0;
        !          2258:     }
        !          2259: }
        !          2260: 
        !          2261: #ifdef __GNUC__
        !          2262: extern __inline int identifier_type ();
        !          2263: __inline
        !          2264: #endif
        !          2265: int
        !          2266: identifier_type (decl)
        !          2267:      tree decl;
        !          2268: {
        !          2269:   if (TREE_CODE (decl) == TEMPLATE_DECL
        !          2270:       && DECL_TEMPLATE_IS_CLASS (decl))
        !          2271:     return PTYPENAME;
        !          2272:   if (TREE_CODE (decl) != TYPE_DECL)
        !          2273:     return IDENTIFIER;
        !          2274:   return TYPENAME;
        !          2275: }
        !          2276: 
        !          2277: void
        !          2278: see_typename ()
        !          2279: {
        !          2280:   looking_for_typename = 0;
        !          2281:   if (yychar == IDENTIFIER)
        !          2282:     {
        !          2283:       lastiddecl = lookup_name (yylval.ttype, -1);
        !          2284:       if (lastiddecl == 0)
        !          2285:        {
        !          2286:          if (flag_labels_ok)
        !          2287:            lastiddecl = IDENTIFIER_LABEL_VALUE (yylval.ttype);
        !          2288:        }
        !          2289:       else
        !          2290:        yychar = identifier_type (lastiddecl);
        !          2291:     }
        !          2292: }
        !          2293: 
        !          2294: tree do_identifier (token)
        !          2295:      register tree token;
        !          2296: {
        !          2297:   register tree id = lastiddecl;
        !          2298: 
        !          2299:   if (yychar == YYEMPTY)
        !          2300:     yychar = yylex ();
        !          2301:   /* Scope class declarations before global
        !          2302:      declarations.  */
        !          2303:   if (id == IDENTIFIER_GLOBAL_VALUE (token)
        !          2304:       && current_class_type != 0
        !          2305:       && TYPE_SIZE (current_class_type) == 0
        !          2306:       && TREE_CODE (current_class_type) != UNINSTANTIATED_P_TYPE)
        !          2307:     {
        !          2308:       /* Could be from one of the base classes.  */
        !          2309:       tree field = lookup_field (current_class_type, token, 1);
        !          2310:       if (field == 0)
        !          2311:        ;
        !          2312:       else if (field == error_mark_node)
        !          2313:        /* We have already generated the error message.
        !          2314:           But we still want to return this value.  */
        !          2315:        id = lookup_field (current_class_type, token, 0);
        !          2316:       else if (TREE_CODE (field) == VAR_DECL
        !          2317:               || TREE_CODE (field) == CONST_DECL)
        !          2318:        id = field;
        !          2319:       else if (TREE_CODE (field) != FIELD_DECL)
        !          2320:        abort ();
        !          2321:       else
        !          2322:        {
        !          2323:          error_with_decl (field, "invalid use of member `%s' from base class `%s'",
        !          2324:                           TYPE_NAME_STRING (DECL_FIELD_CONTEXT (field)));
        !          2325:          id = error_mark_node;
        !          2326:          return id;
        !          2327:        }
        !          2328:     }
        !          2329: 
        !          2330:   if (!id || id == error_mark_node)
        !          2331:     {
        !          2332:       if (yychar == '(' || yychar == LEFT_RIGHT)
        !          2333:        {
        !          2334:          id = implicitly_declare (token);
        !          2335:        }
        !          2336:       else if (current_function_decl == 0)
        !          2337:        {
        !          2338:          error ("`%s' undeclared, outside of functions",
        !          2339:                 IDENTIFIER_POINTER (token));
        !          2340:          id = error_mark_node;
        !          2341:        }
        !          2342:       else
        !          2343:        {
        !          2344:          if (IDENTIFIER_GLOBAL_VALUE (token) != error_mark_node
        !          2345:              || IDENTIFIER_ERROR_LOCUS (token) != current_function_decl)
        !          2346:            {
        !          2347:              extern int undeclared_variable_notice;
        !          2348: 
        !          2349:              error ("`%s' undeclared (first use this function)",
        !          2350:                     IDENTIFIER_POINTER (token));
        !          2351: 
        !          2352:              if (! undeclared_variable_notice)
        !          2353:                {
        !          2354:                  error ("(Each undeclared identifier is reported only once");
        !          2355:                  error ("for each function it appears in.)");
        !          2356:                  undeclared_variable_notice = 1;
        !          2357:                }
        !          2358:            }
        !          2359:          id = error_mark_node;
        !          2360:          /* Prevent repeated error messages.  */
        !          2361:          IDENTIFIER_GLOBAL_VALUE (token) = error_mark_node;
        !          2362:          SET_IDENTIFIER_ERROR_LOCUS (token, current_function_decl);
        !          2363:        }
        !          2364:     }
        !          2365:   /* TREE_USED is set in `hack_identifier'.  */
        !          2366:   if (TREE_CODE (id) == CONST_DECL)
        !          2367:     {
        !          2368:       if (IDENTIFIER_CLASS_VALUE (token) == id)
        !          2369:        {
        !          2370:          /* Check visibility.  */
        !          2371:          enum visibility_type visibility
        !          2372:            = compute_visibility (TYPE_BINFO (current_class_type), id);
        !          2373:          if (visibility == visibility_private)
        !          2374:            error_with_decl (id, "enum `%s' is private");
        !          2375:          /* protected is OK, since it's an enum of `this'.  */
        !          2376:        }
        !          2377:       id = DECL_INITIAL (id);
        !          2378:     }
        !          2379:   else id = hack_identifier (id, token, yychar);
        !          2380:   return id;
        !          2381: }
        !          2382: 
        !          2383: tree
        !          2384: identifier_typedecl_value (node)
        !          2385:      tree node;
        !          2386: {
        !          2387:   tree t, type;
        !          2388:   type = IDENTIFIER_TYPE_VALUE (node);
        !          2389:   if (type == NULL_TREE)
        !          2390:     return NULL_TREE;
        !          2391: #define do(X) \
        !          2392:   { \
        !          2393:     t = (X); \
        !          2394:     if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type) \
        !          2395:       return t; \
        !          2396:   }
        !          2397:   do (IDENTIFIER_LOCAL_VALUE (node));
        !          2398:   do (IDENTIFIER_CLASS_VALUE (node));
        !          2399:   do (IDENTIFIER_GLOBAL_VALUE (node));
        !          2400: #undef do
        !          2401:   /* Will this one ever happen?  */
        !          2402:   if (TYPE_NAME (type))
        !          2403:     return TYPE_NAME (type);
        !          2404:   abort ();
        !          2405: }
        !          2406: 
        !          2407: struct try_type
        !          2408: {
        !          2409:   tree *node_var;
        !          2410:   char unsigned_flag;
        !          2411:   char long_flag;
        !          2412:   char long_long_flag;
        !          2413: };
        !          2414: 
        !          2415: struct try_type type_sequence[] = 
        !          2416: {
        !          2417:   { &integer_type_node, 0, 0, 0},
        !          2418:   { &unsigned_type_node, 1, 0, 0},
        !          2419:   { &long_integer_type_node, 0, 1, 0},
        !          2420:   { &long_unsigned_type_node, 1, 1, 0},
        !          2421:   { &long_long_integer_type_node, 0, 1, 1},
        !          2422:   { &long_long_unsigned_type_node, 1, 1, 1}
        !          2423: };
        !          2424: 
        !          2425: int
        !          2426: real_yylex ()
        !          2427: {
        !          2428:   tree tmp;
        !          2429:   register int c;
        !          2430:   register int value;
        !          2431:   int wide_flag = 0;
        !          2432:   int dollar_seen = 0;
        !          2433:   static tree typename_scope_in_progress;
        !          2434: 
        !          2435:  relex:
        !          2436:   if (nextchar >= 0)
        !          2437:     c = nextchar, nextchar = -1;
        !          2438:   else
        !          2439:     c = getch ();
        !          2440: 
        !          2441:   /* Effectively do c = skip_white_space (c)
        !          2442:      but do it faster in the usual cases.  */
        !          2443:   while (1)
        !          2444:     switch (c)
        !          2445:       {
        !          2446:       case ' ':
        !          2447:       case '\t':
        !          2448:       case '\f':
        !          2449:       case '\r':
        !          2450:       case '\v':
        !          2451:       case '\b':
        !          2452:        c = getch ();
        !          2453:        break;
        !          2454: 
        !          2455:       case '\n':
        !          2456:       case '/':
        !          2457:       case '\\':
        !          2458:        c = skip_white_space (c);
        !          2459:       default:
        !          2460:        goto found_nonwhite;
        !          2461:       }
        !          2462:  found_nonwhite:
        !          2463: 
        !          2464:   token_buffer[0] = c;
        !          2465:   token_buffer[1] = 0;
        !          2466: 
        !          2467: /*  yylloc.first_line = lineno; */
        !          2468: 
        !          2469:  reswitch:
        !          2470:   switch (c)
        !          2471:     {
        !          2472:     case EOF:
        !          2473:       token_buffer[0] = '\0';
        !          2474:       end_of_file = 1;
        !          2475:       if (input_redirected ())
        !          2476:        value = END_OF_SAVED_INPUT;
        !          2477:       else if (do_pending_expansions ())
        !          2478:        /* this will set yychar for us */
        !          2479:        return yychar;
        !          2480:       else
        !          2481:        value = ENDFILE;
        !          2482:       break;
        !          2483: 
        !          2484:     case '$':
        !          2485:       if (dollars_in_ident)
        !          2486:        {
        !          2487:          dollar_seen = 1;
        !          2488:          goto letter;
        !          2489:        }
        !          2490:       value = '$';
        !          2491:       goto done;
        !          2492: 
        !          2493:     case 'L':
        !          2494:       /* Capital L may start a wide-string or wide-character constant.  */
        !          2495:       {
        !          2496:        register int c = getch ();
        !          2497:        if (c == '\'')
        !          2498:          {
        !          2499:            wide_flag = 1;
        !          2500:            goto char_constant;
        !          2501:          }
        !          2502:        if (c == '"')
        !          2503:          {
        !          2504:            wide_flag = 1;
        !          2505:            goto string_constant;
        !          2506:          }
        !          2507:        put_back (c);
        !          2508:       }
        !          2509: 
        !          2510:     case 'A':  case 'B':  case 'C':  case 'D':  case 'E':
        !          2511:     case 'F':  case 'G':  case 'H':  case 'I':  case 'J':
        !          2512:     case 'K':            case 'M':  case 'N':  case 'O':
        !          2513:     case 'P':  case 'Q':  case 'R':  case 'S':  case 'T':
        !          2514:     case 'U':  case 'V':  case 'W':  case 'X':  case 'Y':
        !          2515:     case 'Z':
        !          2516:     case 'a':  case 'b':  case 'c':  case 'd':  case 'e':
        !          2517:     case 'f':  case 'g':  case 'h':  case 'i':  case 'j':
        !          2518:     case 'k':  case 'l':  case 'm':  case 'n':  case 'o':
        !          2519:     case 'p':  case 'q':  case 'r':  case 's':  case 't':
        !          2520:     case 'u':  case 'v':  case 'w':  case 'x':  case 'y':
        !          2521:     case 'z':
        !          2522:     case '_':
        !          2523:     letter:
        !          2524:       {
        !          2525:        register char *p;
        !          2526: 
        !          2527:        p = token_buffer;
        !          2528:        if (input == 0)
        !          2529:          {
        !          2530:            /* We know that `token_buffer' can hold at least on char,
        !          2531:               so we install C immediately.
        !          2532:               We may have to read the value in `putback_char', so call
        !          2533:               `getch' once.  */
        !          2534:            *p++ = c;
        !          2535:            c = getch ();
        !          2536: 
        !          2537:            /* Make this run fast.  We know that we are reading straight
        !          2538:               from FINPUT in this case (since identifiers cannot straddle
        !          2539:               input sources.  */
        !          2540:            while (isalnum (c) || (c == '_') || c == '$')
        !          2541:              {
        !          2542:                if (p >= token_buffer + maxtoken)
        !          2543:                  p = extend_token_buffer (p);
        !          2544:                if (c == '$' && ! dollars_in_ident)
        !          2545:                  break;
        !          2546: 
        !          2547:                *p++ = c;
        !          2548:                c = getc (finput);
        !          2549:              }
        !          2550:          }
        !          2551:        else
        !          2552:          {
        !          2553:            /* We know that `token_buffer' can hold at least on char,
        !          2554:               so we install C immediately.  */
        !          2555:            *p++ = c;
        !          2556:            c = getch ();
        !          2557: 
        !          2558:            while (isalnum (c) || (c == '_') || c == '$')
        !          2559:              {
        !          2560:                if (p >= token_buffer + maxtoken)
        !          2561:                  p = extend_token_buffer (p);
        !          2562:                if (c == '$' && ! dollars_in_ident)
        !          2563:                  break;
        !          2564: 
        !          2565:                *p++ = c;
        !          2566:                c = getch ();
        !          2567:              }
        !          2568:          }
        !          2569: 
        !          2570:        *p = 0;
        !          2571:        nextchar = c;
        !          2572: 
        !          2573:        value = IDENTIFIER;
        !          2574:        yylval.itype = 0;
        !          2575: 
        !          2576:       /* Try to recognize a keyword.  Uses minimum-perfect hash function */
        !          2577: 
        !          2578:        {
        !          2579:          register struct resword *ptr;
        !          2580: 
        !          2581:          if (ptr = is_reserved_word (token_buffer, p - token_buffer))
        !          2582:            {
        !          2583:              if (ptr->rid)
        !          2584:                {
        !          2585:                  tree old_ttype = ridpointers[(int) ptr->rid];
        !          2586: 
        !          2587:                  /* If this provides a type for us, then revert lexical
        !          2588:                     state to standard state.  */
        !          2589:                  if (TREE_CODE (old_ttype) == IDENTIFIER_NODE
        !          2590:                      && IDENTIFIER_GLOBAL_VALUE (old_ttype) != 0
        !          2591:                      && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (old_ttype)) == TYPE_DECL)
        !          2592:                    looking_for_typename = 0;
        !          2593:                  else if (ptr->token == AGGR || ptr->token == ENUM)
        !          2594:                    looking_for_typename = 1;
        !          2595: 
        !          2596:                  /* Check if this is a language-type declaration.
        !          2597:                     Just glimpse the next non-white character.  */
        !          2598:                  nextchar = skip_white_space (nextchar);
        !          2599:                  if (nextchar == '"')
        !          2600:                    {
        !          2601:                      /* We are looking at a string.  Complain
        !          2602:                         if the token before the string is no `extern'.
        !          2603:                         
        !          2604:                         Could cheat some memory by placing this string
        !          2605:                         on the temporary_, instead of the saveable_
        !          2606:                         obstack.  */
        !          2607: 
        !          2608:                      if (ptr->rid != RID_EXTERN)
        !          2609:                        error ("invalid modifier `%s' for language string",
        !          2610:                               ptr->name);
        !          2611:                      real_yylex ();
        !          2612:                      value = EXTERN_LANG_STRING;
        !          2613:                      yylval.ttype = get_identifier (TREE_STRING_POINTER (yylval.ttype));
        !          2614:                      break;
        !          2615:                    }
        !          2616:                  if (ptr->token == VISSPEC)
        !          2617:                    {
        !          2618:                      switch (ptr->rid)
        !          2619:                        {
        !          2620:                        case RID_PUBLIC:
        !          2621:                          yylval.itype = visibility_public;
        !          2622:                          break;
        !          2623:                        case RID_PRIVATE:
        !          2624:                          yylval.itype = visibility_private;
        !          2625:                          break;
        !          2626:                        case RID_PROTECTED:
        !          2627:                          yylval.itype = visibility_protected;
        !          2628:                          break;
        !          2629:                        default:
        !          2630:                          abort ();
        !          2631:                        }
        !          2632:                    }
        !          2633:                  else
        !          2634:                    yylval.ttype = old_ttype;
        !          2635:                }
        !          2636:              value = (int) ptr->token;
        !          2637:            }
        !          2638:        }
        !          2639: 
        !          2640:        /* If we did not find a keyword, look for an identifier
        !          2641:           (or a typename).  */
        !          2642: 
        !          2643:        if (value == IDENTIFIER || value == TYPESPEC)
        !          2644:          GNU_xref_ref (current_function_decl, token_buffer);
        !          2645: 
        !          2646:        if (value == IDENTIFIER)
        !          2647:          {
        !          2648:            tmp = get_identifier (token_buffer);
        !          2649: 
        !          2650: #ifndef VMS
        !          2651:            /* Make sure that user does not collide with our internal
        !          2652:               naming scheme.  */
        !          2653:            if (JOINER == '$'
        !          2654:                && dollar_seen
        !          2655:                && (THIS_NAME_P (tmp)
        !          2656:                    || VPTR_NAME_P (tmp)
        !          2657:                    || DESTRUCTOR_NAME_P (tmp)
        !          2658:                    || WRAPPER_OR_ANTI_WRAPPER_NAME_P (tmp)
        !          2659:                    || VTABLE_NAME_P (tmp)
        !          2660:                    || TEMP_NAME_P (tmp)
        !          2661:                    || ANON_AGGRNAME_P (tmp)
        !          2662:                    || ANON_PARMNAME_P (tmp)))
        !          2663:              warning ("identifier name `%s' conflicts with GNU C++ internal naming strategy",
        !          2664:                       token_buffer);
        !          2665: #endif
        !          2666: 
        !          2667:            yylval.ttype = tmp;
        !          2668:          }
        !          2669:        if (value == NEW && ! global_bindings_p ())
        !          2670:          {
        !          2671:            looking_for_typename = 1;
        !          2672:            value = NEW;
        !          2673:            goto done;
        !          2674:          }
        !          2675:       }
        !          2676:       break;
        !          2677: 
        !          2678:     case '.':
        !          2679:       {
        !          2680:        register int c1 = getch ();
        !          2681:        token_buffer[0] = c;
        !          2682:        token_buffer[1] = c1;
        !          2683:        if (c1 == '*')
        !          2684:          {
        !          2685:            value = DOT_STAR;
        !          2686:            token_buffer[2] = 0;
        !          2687:            goto done;
        !          2688:          }
        !          2689:        if (c1 == '.')
        !          2690:          {
        !          2691:            c1 = getch ();
        !          2692:            if (c1 == '.')
        !          2693:              {
        !          2694:                token_buffer[2] = c1;
        !          2695:                token_buffer[3] = 0;
        !          2696:                value = ELLIPSIS;
        !          2697:                goto done;
        !          2698:              }
        !          2699:            nextchar = c1;
        !          2700:            token_buffer[2] = '\0';
        !          2701:            value = RANGE;
        !          2702:            goto done;
        !          2703:          }
        !          2704:        if (isdigit (c1))
        !          2705:          {
        !          2706:            put_back (c1);
        !          2707:            goto resume_numerical_scan;
        !          2708:          }
        !          2709:        nextchar = c1;
        !          2710:        value = '.';
        !          2711:        token_buffer[1] = 0;
        !          2712:        goto done;
        !          2713:       }
        !          2714:     case '0':  case '1':
        !          2715:        /* Optimize for most frequent case.  */
        !          2716:       {
        !          2717:        register int c1 = getch ();
        !          2718:        if (! isalnum (c1) && c1 != '.')
        !          2719:          {
        !          2720:            /* Terminate string.  */
        !          2721:            token_buffer[0] = c;
        !          2722:            token_buffer[1] = 0;
        !          2723:            if (c == '0')
        !          2724:              yylval.ttype = integer_zero_node;
        !          2725:            else
        !          2726:              yylval.ttype = integer_one_node;
        !          2727:            nextchar = c1;
        !          2728:            value = CONSTANT;
        !          2729:            goto done;
        !          2730:          }
        !          2731:        put_back (c1);
        !          2732:       }
        !          2733:       /* fall through... */
        !          2734:                          case '2':  case '3':  case '4':
        !          2735:     case '5':  case '6':  case '7':  case '8':  case '9':
        !          2736:     resume_numerical_scan:
        !          2737:       {
        !          2738:        register char *p;
        !          2739:        int base = 10;
        !          2740:        int count = 0;
        !          2741:        int largest_digit = 0;
        !          2742:        int numdigits = 0;
        !          2743:        /* for multi-precision arithmetic,
        !          2744:           we store only 8 live bits in each short,
        !          2745:           giving us 64 bits of reliable precision */
        !          2746:        short shorts[8];
        !          2747:        int overflow = 0;
        !          2748: 
        !          2749:        enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag
        !          2750:          = NOT_FLOAT;
        !          2751: 
        !          2752:        p = token_buffer;
        !          2753:        *p++ = c;
        !          2754: 
        !          2755:        for (count = 0; count < 8; count++)
        !          2756:          shorts[count] = 0;
        !          2757: 
        !          2758:        if (c == '0')
        !          2759:          {
        !          2760:            *p++ = (c = getch ());
        !          2761:            if ((c == 'x') || (c == 'X'))
        !          2762:              {
        !          2763:                base = 16;
        !          2764:                *p++ = (c = getch ());
        !          2765:              }
        !          2766:            /* Leading 0 forces octal unless the 0 is the only digit.  */
        !          2767:            else if (c >= '0' && c <= '9')
        !          2768:              {
        !          2769:                base = 8;
        !          2770:                numdigits++;
        !          2771:              }
        !          2772:            else
        !          2773:              numdigits++;
        !          2774:          }
        !          2775: 
        !          2776:        /* Read all the digits-and-decimal-points.  */
        !          2777: 
        !          2778:        while (c == '.'
        !          2779:               || (isalnum (c) && (c != 'l') && (c != 'L')
        !          2780:                   && (c != 'u') && (c != 'U')
        !          2781:                   && (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F')))))
        !          2782:          {
        !          2783:            if (c == '.')
        !          2784:              {
        !          2785:                if (base == 16)
        !          2786:                  error ("floating constant may not be in radix 16");
        !          2787:                if (floatflag == AFTER_POINT)
        !          2788:                  {
        !          2789:                    error ("malformed floating constant");
        !          2790:                    floatflag = TOO_MANY_POINTS;
        !          2791:                  }
        !          2792:                else
        !          2793:                  floatflag = AFTER_POINT;
        !          2794: 
        !          2795:                base = 10;
        !          2796:                *p++ = c = getch ();
        !          2797:                /* Accept '.' as the start of a floating-point number
        !          2798:                   only when it is followed by a digit.
        !          2799:                   Otherwise, unread the following non-digit
        !          2800:                   and use the '.' as a structural token.  */
        !          2801:                if (p == token_buffer + 2 && !isdigit (c))
        !          2802:                  {
        !          2803:                    if (c == '.')
        !          2804:                      {
        !          2805:                        c = getch ();
        !          2806:                        if (c == '.')
        !          2807:                          {
        !          2808:                            *p++ = '.';
        !          2809:                            *p = '\0';
        !          2810:                            value = ELLIPSIS;
        !          2811:                            goto done;
        !          2812:                          }
        !          2813:                        nextchar = c;
        !          2814:                        token_buffer[2] = '\0';
        !          2815:                        value = RANGE;
        !          2816:                        goto done;
        !          2817:                      }
        !          2818:                    nextchar = c;
        !          2819:                    token_buffer[1] = '\0';
        !          2820:                    value = '.';
        !          2821:                    goto done;
        !          2822:                  }
        !          2823:              }
        !          2824:            else
        !          2825:              {
        !          2826:                /* It is not a decimal point.
        !          2827:                   It should be a digit (perhaps a hex digit).  */
        !          2828: 
        !          2829:                if (isdigit (c))
        !          2830:                  {
        !          2831:                    c = c - '0';
        !          2832:                  }
        !          2833:                else if (base <= 10)
        !          2834:                  {
        !          2835:                    if ((c&~040) == 'E')
        !          2836:                      {
        !          2837:                        base = 10;
        !          2838:                        floatflag = AFTER_POINT;
        !          2839:                        break;   /* start of exponent */
        !          2840:                      }
        !          2841:                    error ("nondigits in number and not hexadecimal");
        !          2842:                    c = 0;
        !          2843:                  }
        !          2844:                else if (c >= 'a')
        !          2845:                  {
        !          2846:                    c = c - 'a' + 10;
        !          2847:                  }
        !          2848:                else
        !          2849:                  {
        !          2850:                    c = c - 'A' + 10;
        !          2851:                  }
        !          2852:                if (c >= largest_digit)
        !          2853:                  largest_digit = c;
        !          2854:                numdigits++;
        !          2855: 
        !          2856:                for (count = 0; count < 8; count++)
        !          2857:                  {
        !          2858:                    shorts[count] *= base;
        !          2859:                    if (count)
        !          2860:                      {
        !          2861:                        shorts[count] += (shorts[count-1] >> 8);
        !          2862:                        shorts[count-1] &= (1<<8)-1;
        !          2863:                      }
        !          2864:                    else shorts[0] += c;
        !          2865:                  }
        !          2866: 
        !          2867:                if (shorts[7] >= 1<<8
        !          2868:                    || shorts[7] < - (1 << 8))
        !          2869:                  overflow = TRUE;
        !          2870: 
        !          2871:                if (p >= token_buffer + maxtoken - 3)
        !          2872:                  p = extend_token_buffer (p);
        !          2873:                *p++ = (c = getch ());
        !          2874:              }
        !          2875:          }
        !          2876: 
        !          2877:        if (numdigits == 0)
        !          2878:          error ("numeric constant with no digits");
        !          2879: 
        !          2880:        if (largest_digit >= base)
        !          2881:          error ("numeric constant contains digits beyond the radix");
        !          2882: 
        !          2883:        /* Remove terminating char from the token buffer and delimit the string */
        !          2884:        *--p = 0;
        !          2885: 
        !          2886:        if (floatflag != NOT_FLOAT)
        !          2887:          {
        !          2888:            tree type = double_type_node;
        !          2889:            char f_seen = 0;
        !          2890:            char l_seen = 0;
        !          2891:            REAL_VALUE_TYPE value;
        !          2892:            jmp_buf handler;
        !          2893: 
        !          2894:            /* Read explicit exponent if any, and put it in tokenbuf.  */
        !          2895: 
        !          2896:            if ((c == 'e') || (c == 'E'))
        !          2897:              {
        !          2898:                if (p >= token_buffer + maxtoken - 3)
        !          2899:                  p = extend_token_buffer (p);
        !          2900:                *p++ = c;
        !          2901:                c = getch ();
        !          2902:                if ((c == '+') || (c == '-'))
        !          2903:                  {
        !          2904:                    *p++ = c;
        !          2905:                    c = getch ();
        !          2906:                  }
        !          2907:                if (! isdigit (c))
        !          2908:                  error ("floating constant exponent has no digits");
        !          2909:                while (isdigit (c))
        !          2910:                  {
        !          2911:                    if (p >= token_buffer + maxtoken - 3)
        !          2912:                      p = extend_token_buffer (p);
        !          2913:                    *p++ = c;
        !          2914:                    c = getch ();
        !          2915:                  }
        !          2916:              }
        !          2917: 
        !          2918:            *p = 0;
        !          2919:            errno = 0;
        !          2920: 
        !          2921:            /* Convert string to a double, checking for overflow.  */
        !          2922:            if (setjmp (handler))
        !          2923:              {
        !          2924:                error ("floating constant out of range");
        !          2925:                value = dconst0;
        !          2926:              }
        !          2927:            else
        !          2928:              {
        !          2929:                set_float_handler (handler);
        !          2930:                value = REAL_VALUE_ATOF (token_buffer);
        !          2931:                set_float_handler (0);
        !          2932:              }
        !          2933: #ifdef ERANGE
        !          2934:            if (errno == ERANGE && !flag_traditional)
        !          2935:              {
        !          2936:                char *p1 = token_buffer;
        !          2937:                /* Check for "0.0" and variants;
        !          2938:                   Sunos 4 spuriously returns ERANGE for them.  */
        !          2939:                while (*p1 == '0') p1++;
        !          2940:                if (*p1 == '.')
        !          2941:                  {
        !          2942:                    p1++;
        !          2943:                    while (*p1 == '0') p1++;
        !          2944:                  }
        !          2945:                if (*p1 == 'e' || *p1 == 'E')
        !          2946:                  {
        !          2947:                    /* with significand==0, ignore the exponent */
        !          2948:                    p1++;
        !          2949:                    while (*p1 != 0) p1++;
        !          2950:                  }
        !          2951:                /* ERANGE is also reported for underflow,
        !          2952:                   so test the value to distinguish overflow from that.  */
        !          2953:                if (*p1 != 0 && (value > 1.0 || value < -1.0))
        !          2954:                  warning ("floating point number exceeds range of `double'");
        !          2955:              }
        !          2956: #endif
        !          2957: 
        !          2958:            /* Read the suffixes to choose a data type.  */
        !          2959:            while (1)
        !          2960:              {
        !          2961:                if (c == 'f' || c == 'F')
        !          2962:                  {
        !          2963:                    if (f_seen)
        !          2964:                      error ("two `f's in floating constant");
        !          2965:                    f_seen = 1;
        !          2966:                    type = float_type_node;
        !          2967:                    value = REAL_VALUE_TRUNCATE (TYPE_MODE (type), value);
        !          2968:                  }
        !          2969:                else if (c == 'l' || c == 'L')
        !          2970:                  {
        !          2971:                    if (l_seen)
        !          2972:                      error ("two `l's in floating constant");
        !          2973:                    l_seen = 1;
        !          2974:                    type = long_double_type_node;
        !          2975:                  }
        !          2976:                else
        !          2977:                  {
        !          2978:                    if (isalnum (c))
        !          2979:                      {
        !          2980:                        error ("garbage at end of number");
        !          2981:                        while (isalnum (c))
        !          2982:                          {
        !          2983:                            if (p >= token_buffer + maxtoken - 3)
        !          2984:                              p = extend_token_buffer (p);
        !          2985:                            *p++ = c;
        !          2986:                            c = getch ();
        !          2987:                          }
        !          2988:                      }
        !          2989:                    break;
        !          2990:                  }
        !          2991:                if (p >= token_buffer + maxtoken - 3)
        !          2992:                  p = extend_token_buffer (p);
        !          2993:                *p++ = c;
        !          2994:                c = getch ();
        !          2995:              }
        !          2996: 
        !          2997:            /* Create a node with determined type and value.  */
        !          2998:            yylval.ttype = build_real (type, value);
        !          2999: 
        !          3000:            put_back (c);
        !          3001:            *p = 0;
        !          3002:          }
        !          3003:        else
        !          3004:          {
        !          3005:            tree type;
        !          3006:            int spec_unsigned = 0;
        !          3007:            int spec_long = 0;
        !          3008:            int spec_long_long = 0;
        !          3009: 
        !          3010:            while (1)
        !          3011:              {
        !          3012:                if (c == 'u' || c == 'U')
        !          3013:                  {
        !          3014:                    if (spec_unsigned)
        !          3015:                      error ("two `u's in integer constant");
        !          3016:                    spec_unsigned = 1;
        !          3017:                  }
        !          3018:                else if (c == 'l' || c == 'L')
        !          3019:                  {
        !          3020:                    if (spec_long)
        !          3021:                      {
        !          3022:                        if (spec_long_long)
        !          3023:                          error ("three `l's in integer constant");
        !          3024:                        else if (pedantic)
        !          3025:                          pedwarn ("ANSI C forbids long long integer constants");
        !          3026:                        spec_long_long = 1;
        !          3027:                      }
        !          3028:                    spec_long = 1;
        !          3029:                  }
        !          3030:                else
        !          3031:                  {
        !          3032:                    if (isalnum (c))
        !          3033:                      {
        !          3034:                        error ("garbage at end of number");
        !          3035:                        while (isalnum (c))
        !          3036:                          {
        !          3037:                            if (p >= token_buffer + maxtoken - 3)
        !          3038:                              p = extend_token_buffer (p);
        !          3039:                            *p++ = c;
        !          3040:                            c = getch ();
        !          3041:                          }
        !          3042:                      }
        !          3043:                    break;
        !          3044:                  }
        !          3045:                if (p >= token_buffer + maxtoken - 3)
        !          3046:                  p = extend_token_buffer (p);
        !          3047:                *p++ = c;
        !          3048:                c = getch ();
        !          3049:              }
        !          3050: 
        !          3051:            put_back (c);
        !          3052: 
        !          3053:            if ((overflow || shorts[7] || shorts[6] || shorts[5] || shorts[4])
        !          3054:                && !spec_long_long)
        !          3055:              warning ("integer constant out of range");
        !          3056: 
        !          3057:            /* If it won't fit in a signed long long, make it unsigned.
        !          3058:               We can't distinguish based on the tree node because
        !          3059:               any integer constant fits any long long type.  */
        !          3060:            if (shorts[7] >= (1<<8))
        !          3061:              spec_unsigned = 1;
        !          3062: 
        !          3063:            /* This is simplified by the fact that our constant
        !          3064:               is always positive.  */
        !          3065:            yylval.ttype
        !          3066:              = (build_int_2
        !          3067:                 ((((long)shorts[3]<<24) + ((long)shorts[2]<<16)
        !          3068:                   + ((long)shorts[1]<<8) + (long)shorts[0]),
        !          3069:                  (spec_long_long
        !          3070:                   ? (((long)shorts[7]<<24) + ((long)shorts[6]<<16)
        !          3071:                      + ((long)shorts[5]<<8) + (long)shorts[4])
        !          3072:                   : 0)));
        !          3073: 
        !          3074: #if 0
        !          3075:            /* Find the first allowable type that the value fits in.  */
        !          3076:            type = 0;
        !          3077:            for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]);
        !          3078:                 i++)
        !          3079:              if (!(spec_long && !type_sequence[i].long_flag)
        !          3080:                  && !(spec_long_long && !type_sequence[i].long_long_flag)
        !          3081:                  && !(spec_unsigned && !type_sequence[i].unsigned_flag)
        !          3082:                  /* A hex or octal constant traditionally is unsigned.  */
        !          3083:                  && !(base != 10 && flag_traditional
        !          3084:                       && !type_sequence[i].unsigned_flag)
        !          3085:                  /* A decimal constant can't be unsigned int
        !          3086:                     unless explicitly specified.  */
        !          3087:                  && !(base == 10 && !spec_unsigned
        !          3088:                       && *type_sequence[i].node_var == unsigned_type_node))
        !          3089:                if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var))
        !          3090:                  {
        !          3091:                    type = *type_sequence[i].node_var;
        !          3092:                    break;
        !          3093:                  }
        !          3094:            if (flag_traditional && type == long_unsigned_type_node
        !          3095:                && !spec_unsigned)
        !          3096:              type = long_integer_type_node;
        !          3097:              
        !          3098:            if (type == 0)
        !          3099:              {
        !          3100:                type = long_long_integer_type_node;
        !          3101:                warning ("integer constant out of range");
        !          3102:              }
        !          3103: 
        !          3104:            /* Warn about some cases where the type of a given constant
        !          3105:               changes from traditional C to ANSI C.  */
        !          3106:            if (warn_traditional)
        !          3107:              {
        !          3108:                tree other_type = 0;
        !          3109: 
        !          3110:                /* This computation is the same as the previous one
        !          3111:                   except that flag_traditional is used backwards.  */
        !          3112:                for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]);
        !          3113:                     i++)
        !          3114:                  if (!(spec_long && !type_sequence[i].long_flag)
        !          3115:                      && !(spec_long_long && !type_sequence[i].long_long_flag)
        !          3116:                      && !(spec_unsigned && !type_sequence[i].unsigned_flag)
        !          3117:                      /* A hex or octal constant traditionally is unsigned.  */
        !          3118:                      && !(base != 10 && !flag_traditional
        !          3119:                           && !type_sequence[i].unsigned_flag)
        !          3120:                      /* A decimal constant can't be unsigned int
        !          3121:                         unless explicitly specified.  */
        !          3122:                      && !(base == 10 && !spec_unsigned
        !          3123:                           && *type_sequence[i].node_var == unsigned_type_node))
        !          3124:                    if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var))
        !          3125:                      {
        !          3126:                        other_type = *type_sequence[i].node_var;
        !          3127:                        break;
        !          3128:                      }
        !          3129:                if (!flag_traditional && type == long_unsigned_type_node
        !          3130:                    && !spec_unsigned)
        !          3131:                  type = long_integer_type_node;
        !          3132:              
        !          3133:                if (other_type != 0 && other_type != type)
        !          3134:                  {
        !          3135:                    if (flag_traditional)
        !          3136:                      warning ("type of integer constant would be different without -traditional");
        !          3137:                    else
        !          3138:                      warning ("type of integer constant would be different with -traditional");
        !          3139:                  }
        !          3140:              }
        !          3141: 
        !          3142: #else /* 1 */
        !          3143:            if (!spec_long && !spec_unsigned
        !          3144:                && !(flag_traditional && base != 10)
        !          3145:                && int_fits_type_p (yylval.ttype, integer_type_node))
        !          3146:              {
        !          3147: #if 0
        !          3148:                if (warn_traditional && base != 10)
        !          3149:                  warning ("small nondecimal constant becomes signed in ANSI C");
        !          3150: #endif
        !          3151:                type = integer_type_node;
        !          3152:              }
        !          3153:            else if (!spec_long && (base != 10 || spec_unsigned)
        !          3154:                     && int_fits_type_p (yylval.ttype, unsigned_type_node))
        !          3155:              {
        !          3156:                /* Nondecimal constants try unsigned even in traditional C.  */
        !          3157:                type = unsigned_type_node;
        !          3158:              }
        !          3159: 
        !          3160:            else if (!spec_unsigned && !spec_long_long
        !          3161:                     && int_fits_type_p (yylval.ttype, long_integer_type_node))
        !          3162:              type = long_integer_type_node;
        !          3163: 
        !          3164:            else if (! spec_long_long
        !          3165:                     && int_fits_type_p (yylval.ttype,
        !          3166:                                         long_unsigned_type_node))
        !          3167:              {
        !          3168: #if 0
        !          3169:                if (warn_traditional && !spec_unsigned)
        !          3170:                  warning ("large integer constant becomes unsigned in ANSI C");
        !          3171: #endif
        !          3172:                if (flag_traditional && !spec_unsigned)
        !          3173:                  type = long_integer_type_node;
        !          3174:                else
        !          3175:                  type = long_unsigned_type_node;
        !          3176:              }
        !          3177: 
        !          3178:            else if (! spec_unsigned
        !          3179:                     && int_fits_type_p (yylval.ttype,
        !          3180:                                         long_long_integer_type_node))
        !          3181:              type = long_long_integer_type_node;
        !          3182: 
        !          3183:            else if (int_fits_type_p (yylval.ttype,
        !          3184:                                      long_long_unsigned_type_node))
        !          3185:              {
        !          3186: #if 0
        !          3187:                if (warn_traditional && !spec_unsigned)
        !          3188:                  warning ("large nondecimal constant is unsigned in ANSI C");
        !          3189: #endif
        !          3190: 
        !          3191:                if (flag_traditional && !spec_unsigned)
        !          3192:                  type = long_long_integer_type_node;
        !          3193:                else
        !          3194:                  type = long_long_unsigned_type_node;
        !          3195:              }
        !          3196: 
        !          3197:            else
        !          3198:              {
        !          3199:                type = long_long_integer_type_node;
        !          3200:                warning ("integer constant out of range");
        !          3201:              }
        !          3202: #endif
        !          3203: 
        !          3204:            TREE_TYPE (yylval.ttype) = type;
        !          3205:            *p = 0;
        !          3206:          }
        !          3207: 
        !          3208:        value = CONSTANT; break;
        !          3209:       }
        !          3210: 
        !          3211:     case '\'':
        !          3212:     char_constant:
        !          3213:       {
        !          3214:        register int result = 0;
        !          3215:        register num_chars = 0;
        !          3216:        unsigned width = TYPE_PRECISION (char_type_node);
        !          3217:        int max_chars;
        !          3218: 
        !          3219:        if (wide_flag) width = TYPE_PRECISION (integer_type_node);
        !          3220: 
        !          3221:        max_chars = TYPE_PRECISION (integer_type_node) / width;
        !          3222: 
        !          3223:        while (1)
        !          3224:          {
        !          3225:          tryagain:
        !          3226: 
        !          3227:            c = getch ();
        !          3228: 
        !          3229:            if (c == '\'' || c == EOF)
        !          3230:              break;
        !          3231: 
        !          3232:            if (c == '\\')
        !          3233:              {
        !          3234:                c = readescape ();
        !          3235:                if (c < 0)
        !          3236:                  goto tryagain;
        !          3237:                if (width < HOST_BITS_PER_INT
        !          3238:                    && (unsigned) c >= (1 << width))
        !          3239:                  warning ("escape sequence out of range for character");
        !          3240:              }
        !          3241:            else if (c == '\n')
        !          3242:              {
        !          3243:                if (pedantic)
        !          3244:                  warning ("ANSI C forbids newline in character constant");
        !          3245:                lineno++;
        !          3246:              }
        !          3247: 
        !          3248:            num_chars++;
        !          3249:            if (num_chars > maxtoken - 4)
        !          3250:              extend_token_buffer (token_buffer);
        !          3251: 
        !          3252:            token_buffer[num_chars] = c;
        !          3253: 
        !          3254:            /* Merge character into result; ignore excess chars.  */
        !          3255:            if (num_chars < max_chars + 1)
        !          3256:              {
        !          3257:                if (width < HOST_BITS_PER_INT)
        !          3258:                  result = (result << width) | (c & ((1 << width) - 1));
        !          3259:                else
        !          3260:                  result = c;
        !          3261:              }
        !          3262:          }
        !          3263: 
        !          3264:        token_buffer[num_chars + 1] = '\'';
        !          3265:        token_buffer[num_chars + 2] = 0;
        !          3266: 
        !          3267:        if (c != '\'')
        !          3268:          error ("malformatted character constant");
        !          3269:        else if (num_chars == 0)
        !          3270:          error ("empty character constant");
        !          3271:        else if (num_chars > max_chars)
        !          3272:          {
        !          3273:            num_chars = max_chars;
        !          3274:            error ("character constant too long");
        !          3275:          }
        !          3276:        else if (num_chars != 1 && ! flag_traditional)
        !          3277:          warning ("multi-character character constant");
        !          3278: 
        !          3279:        /* If char type is signed, sign-extend the constant.  */
        !          3280:        if (! wide_flag)
        !          3281:          {
        !          3282:            int num_bits = num_chars * width;
        !          3283:            if (TREE_UNSIGNED (char_type_node)
        !          3284:                || ((result >> (num_bits - 1)) & 1) == 0)
        !          3285:              yylval.ttype
        !          3286:                = build_int_2 (result & ((unsigned) ~0
        !          3287:                                         >> (HOST_BITS_PER_INT - num_bits)),
        !          3288:                               0);
        !          3289:            else
        !          3290:              yylval.ttype
        !          3291:                = build_int_2 (result | ~((unsigned) ~0
        !          3292:                                          >> (HOST_BITS_PER_INT - num_bits)),
        !          3293:                               -1);
        !          3294:            TREE_TYPE (yylval.ttype) = char_type_node;
        !          3295:          }
        !          3296:        else
        !          3297:          {
        !          3298:            yylval.ttype = build_int_2 (result, 0);
        !          3299:            TREE_TYPE (yylval.ttype) = integer_type_node;
        !          3300:          }
        !          3301:        value = CONSTANT; break;
        !          3302:       }
        !          3303: 
        !          3304:     case '"':
        !          3305:     string_constant:
        !          3306:       {
        !          3307:        int *widep;
        !          3308:        register char *p;
        !          3309: 
        !          3310:        c = getch ();
        !          3311:        p = token_buffer + 1;
        !          3312: 
        !          3313:        if (wide_flag)
        !          3314:          widep = wide_buffer;
        !          3315: 
        !          3316:        while (c != '"' && c >= 0)
        !          3317:          {
        !          3318:            if (c == '\\')
        !          3319:              {
        !          3320:                c = readescape ();
        !          3321:                if (c < 0)
        !          3322:                  goto skipnewline;
        !          3323:                if (!wide_flag && c >= (1 << BITS_PER_UNIT))
        !          3324:                  warning ("escape sequence out of range for character");
        !          3325:              }
        !          3326:            else if (c == '\n')
        !          3327:              {
        !          3328:                if (pedantic)
        !          3329:                  warning ("ANSI C forbids newline in string constant");
        !          3330:                lineno++;
        !          3331:              }
        !          3332: 
        !          3333:            /* Store the char in C into the appropriate buffer.  */
        !          3334: 
        !          3335:            if (wide_flag)
        !          3336:              {
        !          3337:                if (widep == wide_buffer + max_wide)
        !          3338:                  {
        !          3339:                    int n = widep - wide_buffer;
        !          3340:                    max_wide *= 2;
        !          3341:                    wide_buffer = (int *) xrealloc (wide_buffer, max_wide + 1);
        !          3342:                    widep = wide_buffer + n;
        !          3343:                  }
        !          3344:                *widep++ = c;
        !          3345:              }
        !          3346:            else
        !          3347:              {
        !          3348:                if (p == token_buffer + maxtoken)
        !          3349:                  p = extend_token_buffer (p);
        !          3350:                *p++ = c;
        !          3351:              }
        !          3352: 
        !          3353:          skipnewline:
        !          3354:            c = getch ();
        !          3355:            if (c == EOF) {
        !          3356:                error("Unterminated string");
        !          3357:                break;
        !          3358:            }
        !          3359:          }
        !          3360: 
        !          3361:        /* We have read the entire constant.
        !          3362:           Construct a STRING_CST for the result.  */
        !          3363: 
        !          3364:        if (wide_flag)
        !          3365:          {
        !          3366:            /* If this is a L"..." wide-string, make a vector
        !          3367:               of the ints in wide_buffer.  */
        !          3368:            *widep = 0;
        !          3369:            /* We have not implemented the case where `int'
        !          3370:               on the target and on the execution machine differ in size.  */
        !          3371:            assert (TYPE_PRECISION (integer_type_node) == sizeof (int) * BITS_PER_UNIT);
        !          3372:            yylval.ttype = build_string ((widep - wide_buffer + 1) * sizeof (int),
        !          3373:                                         (char *)wide_buffer);
        !          3374:            TREE_TYPE (yylval.ttype) = int_array_type_node;
        !          3375:          }
        !          3376:        else
        !          3377:          {
        !          3378:            *p = 0;
        !          3379:            yylval.ttype = build_string (p - token_buffer, token_buffer + 1);
        !          3380:            TREE_TYPE (yylval.ttype) = char_array_type_node;
        !          3381:          }
        !          3382: 
        !          3383:        *p++ = '"';
        !          3384:        *p = 0;
        !          3385: 
        !          3386:        value = STRING; break;
        !          3387:       }
        !          3388: 
        !          3389:     case '+':
        !          3390:     case '-':
        !          3391:     case '&':
        !          3392:     case '|':
        !          3393:     case '<':
        !          3394:     case '>':
        !          3395:     case '*':
        !          3396:     case '/':
        !          3397:     case '%':
        !          3398:     case '^':
        !          3399:     case '!':
        !          3400:     case '=':
        !          3401:       {
        !          3402:        register int c1;
        !          3403: 
        !          3404:       combine:
        !          3405: 
        !          3406:        switch (c)
        !          3407:          {
        !          3408:          case '+':
        !          3409:            yylval.code = PLUS_EXPR; break;
        !          3410:          case '-':
        !          3411:            yylval.code = MINUS_EXPR; break;
        !          3412:          case '&':
        !          3413:            yylval.code = BIT_AND_EXPR; break;
        !          3414:          case '|':
        !          3415:            yylval.code = BIT_IOR_EXPR; break;
        !          3416:          case '*':
        !          3417:            yylval.code = MULT_EXPR; break;
        !          3418:          case '/':
        !          3419:            yylval.code = TRUNC_DIV_EXPR; break;
        !          3420:          case '%':
        !          3421:            yylval.code = TRUNC_MOD_EXPR; break;
        !          3422:          case '^':
        !          3423:            yylval.code = BIT_XOR_EXPR; break;
        !          3424:          case LSHIFT:
        !          3425:            yylval.code = LSHIFT_EXPR; break;
        !          3426:          case RSHIFT:
        !          3427:            yylval.code = RSHIFT_EXPR; break;
        !          3428:          case '<':
        !          3429:            yylval.code = LT_EXPR; break;
        !          3430:          case '>':
        !          3431:            yylval.code = GT_EXPR; break;
        !          3432:          }
        !          3433: 
        !          3434:        token_buffer[1] = c1 = getch ();
        !          3435:        token_buffer[2] = 0;
        !          3436: 
        !          3437:        if (c1 == '=')
        !          3438:          {
        !          3439:            switch (c)
        !          3440:              {
        !          3441:              case '<':
        !          3442:                value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done;
        !          3443:              case '>':
        !          3444:                value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done;
        !          3445:              case '!':
        !          3446:                value = EQCOMPARE; yylval.code = NE_EXPR; goto done;
        !          3447:              case '=':
        !          3448:                value = EQCOMPARE; yylval.code = EQ_EXPR; goto done;
        !          3449:              }
        !          3450:            value = ASSIGN; goto done;
        !          3451:          }
        !          3452:        else if (c == c1)
        !          3453:          switch (c)
        !          3454:            {
        !          3455:            case '+':
        !          3456:              value = PLUSPLUS; goto done;
        !          3457:            case '-':
        !          3458:              value = MINUSMINUS; goto done;
        !          3459:            case '&':
        !          3460:              value = ANDAND; goto done;
        !          3461:            case '|':
        !          3462:              value = OROR; goto done;
        !          3463:            case '<':
        !          3464:              c = LSHIFT;
        !          3465:              goto combine;
        !          3466:            case '>':
        !          3467:              c = RSHIFT;
        !          3468:              goto combine;
        !          3469:            }
        !          3470:        else if ((c == '-') && (c1 == '>'))
        !          3471:          {
        !          3472:            nextchar = skip_white_space (getch ());
        !          3473:            if (nextchar == '(')
        !          3474:              {
        !          3475:                int next_c = skip_white_space (getch ());
        !          3476:                if (next_c == ')')
        !          3477:                  {
        !          3478:                    nextchar = -1;
        !          3479:                    value = POINTSAT_LEFT_RIGHT;
        !          3480:                    goto done;
        !          3481:                  }
        !          3482:                put_back (next_c);
        !          3483:              }
        !          3484:            if (nextchar == '*')
        !          3485:              {
        !          3486:                nextchar = -1;
        !          3487:                value = POINTSAT_STAR;
        !          3488:              }
        !          3489:            else
        !          3490:              value = POINTSAT;
        !          3491:            goto done;
        !          3492:          }
        !          3493:        else if (c1 == '?' && (c == '<' || c == '>'))
        !          3494:          {
        !          3495:            token_buffer[3] = 0;
        !          3496: 
        !          3497:            c1 = getch ();
        !          3498:            yylval.code = (c == '<' ? MIN_EXPR : MAX_EXPR);
        !          3499:            if (c1 == '=')
        !          3500:              {
        !          3501:                /* <?= or >?= expression.  */
        !          3502:                token_buffer[2] = c1;
        !          3503:                value = ASSIGN;
        !          3504:              }
        !          3505:            else
        !          3506:              {
        !          3507:                value = MIN_MAX;
        !          3508:                nextchar = c1;
        !          3509:              }
        !          3510:            if (pedantic)
        !          3511:              error ("use of `operator %s' is not standard C++",
        !          3512:                     token_buffer);
        !          3513:            goto done;
        !          3514:          }
        !          3515: 
        !          3516:        nextchar = c1;
        !          3517:        token_buffer[1] = 0;
        !          3518: 
        !          3519:        value = c;
        !          3520:        goto done;
        !          3521:       }
        !          3522: 
        !          3523:     case ':':
        !          3524:       c = getch ();
        !          3525:       if (c == ':')
        !          3526:        {
        !          3527:          token_buffer[1] = ':';
        !          3528:          token_buffer[2] = '\0';
        !          3529:          value = SCOPE;
        !          3530:          yylval.itype = 1;
        !          3531:        }
        !          3532:       else
        !          3533:        {
        !          3534:          nextchar = c;
        !          3535:          value = ':';
        !          3536:        }
        !          3537:       break;
        !          3538: 
        !          3539:     case 0:
        !          3540:       /* Don't make yyparse think this is eof.  */
        !          3541:       value = 1;
        !          3542:       break;
        !          3543: 
        !          3544:     case '(':
        !          3545:       /* try, weakly, to handle casts to pointers to functions.  */
        !          3546:       nextchar = skip_white_space (getch ());
        !          3547:       if (nextchar == '*')
        !          3548:        {
        !          3549:          int next_c = skip_white_space (getch ());
        !          3550:          if (next_c == ')')
        !          3551:            {
        !          3552:              nextchar = -1;
        !          3553:              yylval.ttype = build1 (INDIRECT_REF, 0, 0);
        !          3554:              value = PAREN_STAR_PAREN;
        !          3555:            }
        !          3556:          else
        !          3557:            {
        !          3558:              put_back (next_c);
        !          3559:              value = c;
        !          3560:            }
        !          3561:        }
        !          3562:       else if (nextchar == ')')
        !          3563:        {
        !          3564:          nextchar = -1;
        !          3565:          yylval.ttype = NULL_TREE;
        !          3566:          value = LEFT_RIGHT;
        !          3567:        }
        !          3568:       else value = c;
        !          3569:       break;
        !          3570: 
        !          3571:     default:
        !          3572:       value = c;
        !          3573:     }
        !          3574: 
        !          3575: done:
        !          3576: /*  yylloc.last_line = lineno; */
        !          3577: #ifdef GATHER_STATISTICS
        !          3578:   token_count[value] += 1;
        !          3579: #endif
        !          3580: 
        !          3581:   return value;
        !          3582: }
        !          3583: 
        !          3584: typedef enum
        !          3585: {
        !          3586:   d_kind, t_kind, s_kind, r_kind, e_kind, c_kind,
        !          3587:   id_kind, op_id_kind, perm_list_kind, temp_list_kind,
        !          3588:   vec_kind, x_kind, lang_decl, lang_type, all_kinds
        !          3589: } tree_node_kind;
        !          3590: extern int tree_node_counts[];
        !          3591: extern int tree_node_sizes[];
        !          3592: extern char *tree_node_kind_names[];
        !          3593: 
        !          3594: /* Place to save freed lang_decls which were allocated on the
        !          3595:    permanent_obstack.  @@ Not currently used.  */
        !          3596: tree free_lang_decl_chain;
        !          3597: 
        !          3598: tree
        !          3599: build_lang_decl (code, name, type)
        !          3600:      enum tree_code code;
        !          3601:      tree name;
        !          3602:      tree type;
        !          3603: {
        !          3604:   register tree t = build_decl (code, name, type);
        !          3605:   struct obstack *obstack = current_obstack;
        !          3606:   register int i = sizeof (struct lang_decl) / sizeof (int);
        !          3607:   register int *pi;
        !          3608: 
        !          3609:   if (! TREE_PERMANENT (t))
        !          3610:     obstack = saveable_obstack;
        !          3611:   else
        !          3612:     /* Could be that saveable is permanent and current is not.  */
        !          3613:     obstack = &permanent_obstack;
        !          3614: 
        !          3615:   if (free_lang_decl_chain && obstack == &permanent_obstack)
        !          3616:     {
        !          3617:       pi = (int *)free_lang_decl_chain;
        !          3618:       free_lang_decl_chain = TREE_CHAIN (free_lang_decl_chain);
        !          3619:     }
        !          3620:   else
        !          3621:     pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl));
        !          3622: 
        !          3623:   while (i > 0)
        !          3624:     pi[--i] = 0;
        !          3625: 
        !          3626:   DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi;
        !          3627:   LANG_DECL_PERMANENT ((struct lang_decl *) pi)
        !          3628:     = obstack == &permanent_obstack;
        !          3629:   assert (LANG_DECL_PERMANENT ((struct lang_decl *) pi)
        !          3630:          == TREE_PERMANENT  (t));
        !          3631:   DECL_MAIN_VARIANT (t) = t;
        !          3632:   if (current_lang_name == lang_name_cplusplus)
        !          3633:     {
        !          3634:       DECL_LANGUAGE (t) = lang_cplusplus;
        !          3635: 
        !          3636: #ifndef NO_AUTO_OVERLOAD
        !          3637:       if (code == FUNCTION_DECL && name != 0
        !          3638:          && ! (IDENTIFIER_LENGTH (name) == 4
        !          3639:                && IDENTIFIER_POINTER (name)[0] == 'm'
        !          3640:                && strcmp (IDENTIFIER_POINTER (name), "main") == 0)
        !          3641:          && ! (IDENTIFIER_LENGTH (name) > 10
        !          3642:                && IDENTIFIER_POINTER (name)[0] == '_'
        !          3643:                && IDENTIFIER_POINTER (name)[1] == '_'
        !          3644:                && strncmp (IDENTIFIER_POINTER (name)+2, "builtin_", 8) == 0))
        !          3645:        TREE_OVERLOADED (name) = 1;
        !          3646: #endif
        !          3647:     }
        !          3648:   else if (current_lang_name == lang_name_c)
        !          3649:     DECL_LANGUAGE (t) = lang_c;
        !          3650:   else abort ();
        !          3651: 
        !          3652: #ifdef GATHER_STATISTICS
        !          3653:   tree_node_counts[(int)lang_decl] += 1;
        !          3654:   tree_node_sizes[(int)lang_decl] += sizeof(struct lang_decl);
        !          3655: #endif
        !          3656: 
        !          3657:   return t;
        !          3658: }
        !          3659: 
        !          3660: tree
        !          3661: build_lang_field_decl (code, name, type)
        !          3662:      enum tree_code code;
        !          3663:      tree name;
        !          3664:      tree type;
        !          3665: {
        !          3666:   extern struct obstack *current_obstack, *saveable_obstack;
        !          3667:   register tree t = build_decl (code, name, type);
        !          3668:   struct obstack *obstack = current_obstack;
        !          3669:   register int i = sizeof (struct lang_decl_flags) / sizeof (int);
        !          3670:   register int *pi;
        !          3671: 
        !          3672:   if (! TREE_PERMANENT (t))
        !          3673:     obstack = saveable_obstack;
        !          3674:   else
        !          3675:     assert (obstack == &permanent_obstack);
        !          3676: 
        !          3677:   pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl_flags));
        !          3678:   while (i > 0)
        !          3679:     pi[--i] = 0;
        !          3680: 
        !          3681:   DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi;
        !          3682:   return t;
        !          3683: }
        !          3684: 
        !          3685: void
        !          3686: copy_lang_decl (node)
        !          3687:      tree node;
        !          3688: {
        !          3689:   int size;
        !          3690:   int *pi;
        !          3691: 
        !          3692:   if (TREE_CODE (node) == FIELD_DECL)
        !          3693:     size = sizeof (struct lang_decl_flags);
        !          3694:   else
        !          3695:     size = sizeof (struct lang_decl);
        !          3696:   pi = (int *)obstack_alloc (&permanent_obstack, size);
        !          3697:   bcopy (DECL_LANG_SPECIFIC (node), pi, size);
        !          3698:   DECL_LANG_SPECIFIC (node) = (struct lang_decl *)pi;
        !          3699: }
        !          3700: 
        !          3701: tree
        !          3702: make_lang_type (code)
        !          3703:      enum tree_code code;
        !          3704: {
        !          3705:   extern struct obstack *current_obstack, *saveable_obstack;
        !          3706:   register tree t = make_node (code);
        !          3707:   struct obstack *obstack = current_obstack;
        !          3708:   register int i = sizeof (struct lang_type) / sizeof (int);
        !          3709:   register int *pi;
        !          3710: 
        !          3711:   /* Set up some flags that give proper default behavior.  */
        !          3712:   IS_AGGR_TYPE (t) = 1;
        !          3713: 
        !          3714:   if (! TREE_PERMANENT (t))
        !          3715:     obstack = saveable_obstack;
        !          3716:   else
        !          3717:     assert (obstack == &permanent_obstack);
        !          3718: 
        !          3719:   pi = (int *) obstack_alloc (obstack, sizeof (struct lang_type));
        !          3720:   while (i > 0)
        !          3721:     pi[--i] = 0;
        !          3722: 
        !          3723:   TYPE_LANG_SPECIFIC (t) = (struct lang_type *) pi;
        !          3724:   CLASSTYPE_AS_LIST (t) = build_tree_list (NULL_TREE, t);
        !          3725:   CLASSTYPE_INTERFACE_UNKNOWN (t) = interface_unknown;
        !          3726:   CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
        !          3727:   CLASSTYPE_VBASE_SIZE (t) = integer_zero_node;
        !          3728:   TYPE_BINFO (t) = make_binfo (integer_zero_node, t, 0, 0, 0);
        !          3729:   CLASSTYPE_BINFO_AS_LIST (t) = build_tree_list (NULL_TREE, TYPE_BINFO (t));
        !          3730: 
        !          3731:   /* Make sure this is laid out, for ease of use later.
        !          3732:      In the presence of parse errors, the normal was of assuring
        !          3733:      this might not ever get executed, so we lay it out *immediately*.  */
        !          3734:   build_pointer_type (t);
        !          3735: 
        !          3736: #ifdef GATHER_STATISTICS
        !          3737:   tree_node_counts[(int)lang_type] += 1;
        !          3738:   tree_node_sizes[(int)lang_type] += sizeof(struct lang_type);
        !          3739: #endif
        !          3740: 
        !          3741:   return t;
        !          3742: }
        !          3743: 
        !          3744: void
        !          3745: copy_decl_lang_specific (decl)
        !          3746:      tree decl;
        !          3747: {
        !          3748:   extern struct obstack *current_obstack, *saveable_obstack;
        !          3749:   register int *old = (int *)DECL_LANG_SPECIFIC (decl);
        !          3750:   struct obstack *obstack = current_obstack;
        !          3751:   register int i = sizeof (struct lang_decl) / sizeof (int);
        !          3752:   register int *pi;
        !          3753: 
        !          3754:   if (! TREE_PERMANENT (decl))
        !          3755:     obstack = saveable_obstack;
        !          3756:   else
        !          3757:     assert (obstack == &permanent_obstack);
        !          3758: 
        !          3759:   pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl));
        !          3760:   while (i-- > 0)
        !          3761:     pi[i] = old[i];
        !          3762: 
        !          3763:   DECL_LANG_SPECIFIC (decl) = (struct lang_decl *) pi;
        !          3764: 
        !          3765: #ifdef GATHER_STATISTICS
        !          3766:   tree_node_counts[(int)lang_decl] += 1;
        !          3767:   tree_node_sizes[(int)lang_decl] += sizeof(struct lang_decl);
        !          3768: #endif
        !          3769: }
        !          3770: 
        !          3771: void
        !          3772: dump_time_statistics ()
        !          3773: {
        !          3774:   register tree prev = 0, decl, next;
        !          3775:   int this_time = my_get_run_time ();
        !          3776:   TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time))
        !          3777:     += this_time - body_time;
        !          3778: 
        !          3779:   fprintf (stderr, "\n******\n");
        !          3780:   print_time ("header files (total)", header_time);
        !          3781:   print_time ("main file (total)", this_time - body_time);
        !          3782:   fprintf (stderr, "ratio = %g : 1\n",
        !          3783:           (double)header_time / (double)(this_time - body_time));
        !          3784:   fprintf (stderr, "\n******\n");
        !          3785: 
        !          3786:   for (decl = filename_times; decl; decl = next)
        !          3787:     {
        !          3788:       next = IDENTIFIER_GLOBAL_VALUE (decl);
        !          3789:       IDENTIFIER_GLOBAL_VALUE (decl) = prev;
        !          3790:       prev = decl;
        !          3791:     }
        !          3792: 
        !          3793:   for (decl = prev; decl; decl = IDENTIFIER_GLOBAL_VALUE (decl))
        !          3794:     print_time (IDENTIFIER_POINTER (decl),
        !          3795:                TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (decl)));
        !          3796: }
        !          3797: 
        !          3798: void
        !          3799: compiler_error (s, v, v2)
        !          3800:      char *s;
        !          3801:      int v, v2;                        /* @@also used as pointer */
        !          3802: {
        !          3803:   char buf[1024];
        !          3804:   sprintf (buf, s, v, v2);
        !          3805:   error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf);
        !          3806: }
        !          3807: 
        !          3808: void
        !          3809: compiler_error_with_decl (decl, s)
        !          3810:      tree decl;
        !          3811:      char *s;
        !          3812: {
        !          3813:   char *name;
        !          3814:   count_error (0);
        !          3815: 
        !          3816:   report_error_function (0);
        !          3817: 
        !          3818:   if (TREE_CODE (decl) == PARM_DECL)
        !          3819:     fprintf (stderr, "%s:%d: ",
        !          3820:             DECL_SOURCE_FILE (DECL_CONTEXT (decl)),
        !          3821:             DECL_SOURCE_LINE (DECL_CONTEXT (decl)));
        !          3822:   else
        !          3823:     fprintf (stderr, "%s:%d: ",
        !          3824:             DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
        !          3825: 
        !          3826:   name = lang_printable_name (decl);
        !          3827:   if (name)
        !          3828:     fprintf (stderr, s, name);
        !          3829:   else
        !          3830:     fprintf (stderr, s, "((anonymous))");
        !          3831:   fprintf (stderr, " (compiler error)\n");
        !          3832: }

unix.superglobalmegacorp.com

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