home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / gcc / cp / lex.c < prev    next >
C/C++ Source or Header  |  1996-12-21  |  137KB  |  5,046 lines

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