Annotation of GNUtools/cc/cp-lex.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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