Annotation of gcc/cp-lex.c, revision 1.1.1.4

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

unix.superglobalmegacorp.com

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