home *** CD-ROM | disk | FTP | other *** search
/ Education Sampler 1992 [NeXTSTEP] / Education_1992_Sampler.iso / NeXT / GnuSource / cc-61.0.1 / cc / cplus-lex.c < prev    next >
C/C++ Source or Header  |  1991-06-04  |  105KB  |  4,037 lines

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