home *** CD-ROM | disk | FTP | other *** search
/ Education Sampler 1992 [NeXTSTEP] / Education_1992_Sampler.iso / NeXT / GnuSource / cc-61.0.1 / cc / cplus-parse.y < prev    next >
Text File  |  1991-06-03  |  99KB  |  3,487 lines

  1. /* YACC parser for C++ syntax.
  2.    Copyright (C) 1988, 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 grammar is based on the GNU CC grammar.  */
  23.  
  24. /* Note: Bison automatically applies a default action of "$$ = $1" for
  25.    all derivations; this is applied before the explicit action, if one
  26.    is given.  Keep this in mind when reading the actions.  */
  27.  
  28. /* Also note: this version contains experimental exception
  29.    handling features.  They could break, change, disappear,
  30.    or otherwise exhibit volatile behavior.  Don't depend on
  31.    me (Michael Tiemann) to protect you from any negative impact
  32.    this may have on your professional, personal, or spiritual life.  */
  33.  
  34. %{
  35. #include "config.h"
  36.  
  37. #include <stdio.h>
  38. #include <errno.h>
  39.  
  40. #include "tree.h"
  41. #include "input.h"
  42. #include "cplus-parse.h"
  43. #include "cplus-tree.h"
  44. #include "assert.h"
  45.  
  46. extern tree void_list_node;
  47.  
  48. #ifndef errno
  49. extern int errno;
  50. #endif
  51.  
  52. extern int end_of_file;
  53.  
  54. void yyerror ();
  55.  
  56. /* Like YYERROR but do call yyerror.  */
  57. #define YYERROR1 { yyerror ("syntax error"); YYERROR; }
  58.  
  59. static void position_after_white_space ();
  60.  
  61. /* The elements of `ridpointers' are identifier nodes
  62.    for the reserved type names and storage classes.
  63.    It is indexed by a RID_... value.  */
  64.  
  65. tree ridpointers[(int) RID_MAX];
  66. #define NORID RID_UNUSED
  67.  
  68. /* Contains error message to give if user tries to declare
  69.    a variable where one does not belong.  */
  70. static char *stmt_decl_msg = 0;
  71.  
  72. void yyhook ();
  73.  
  74. /* Cause the `yydebug' variable to be defined.  */
  75. #define YYDEBUG 0
  76.  
  77. /* Cons up an empty parameter list.  */
  78. #ifdef __GNU__
  79. __inline
  80. #endif
  81. static tree
  82. empty_parms ()
  83. {
  84.   tree parms;
  85.  
  86.   if (strict_prototype)
  87.     parms = void_list_node;
  88.   else
  89.     parms = NULL_TREE;
  90.   return parms;
  91. }
  92. %}
  93.  
  94. %start program
  95.  
  96. %union {long itype; tree ttype; enum tree_code code; }
  97.  
  98. /* All identifiers that are not reserved words
  99.    and are not declared typedefs in the current block */
  100. %token IDENTIFIER
  101.  
  102. /* All identifiers that are declared typedefs in the current block.
  103.    In some contexts, they are treated just like IDENTIFIER,
  104.    but they can also serve as typespecs in declarations.  */
  105. %token TYPENAME
  106.  
  107. /* Qualified identifiers that end in a TYPENAME.  */
  108. %token SCOPED_TYPENAME
  109.  
  110. /* Reserved words that specify storage class.
  111.    yylval contains an IDENTIFIER_NODE which indicates which one.  */
  112. %token SCSPEC
  113.  
  114. /* Reserved words that specify type.
  115.    yylval contains an IDENTIFIER_NODE which indicates which one.  */
  116. %token TYPESPEC
  117.  
  118. /* Reserved words that qualify type: "const" or "volatile".
  119.    yylval contains an IDENTIFIER_NODE which indicates which one.  */
  120. %token TYPE_QUAL
  121.  
  122. /* Character or numeric constants.
  123.    yylval is the node for the constant.  */
  124. %token CONSTANT
  125.  
  126. /* String constants in raw form.
  127.    yylval is a STRING_CST node.  */
  128. %token STRING
  129.  
  130. /* "...", used for functions with variable arglists.  */
  131. %token ELLIPSIS
  132.  
  133. /* the reserved words */
  134. %token SIZEOF ENUM /* STRUCT UNION */ IF ELSE WHILE DO FOR SWITCH CASE DEFAULT
  135. %token BREAK CONTINUE RETURN GOTO ASM TYPEOF ALIGNOF HEADOF CLASSOF
  136. %token ATTRIBUTE
  137.  
  138. /* the reserved words... C++ extensions */
  139. %token <ttype> AGGR
  140. %token <itype> VISSPEC
  141. %token DELETE NEW OVERLOAD THIS OPERATOR
  142. %token DYNAMIC POINTSAT_LEFT_RIGHT LEFT_RIGHT TEMPLATE
  143. %token <itype> SCOPE
  144.  
  145. /* Define the operator tokens and their precedences.
  146.    The value is an integer because, if used, it is the tree code
  147.    to use in the expression made from the operator.  */
  148.  
  149. %left EMPTY            /* used to resolve s/r with epsilon */
  150.  
  151. /* Add precedence rules to solve dangling else s/r conflict */
  152. %nonassoc IF
  153. %nonassoc ELSE
  154.  
  155. %left IDENTIFIER TYPENAME TYPENAME_COLON SCSPEC TYPESPEC TYPE_QUAL ENUM AGGR
  156.  
  157. %left '{' ','
  158.  
  159. %right <code> ASSIGN '='
  160. %right <code> '?' ':' RANGE
  161. %left <code> OROR
  162. %left <code> ANDAND
  163. %left <code> '|'
  164. %left <code> '^'
  165. %left <code> '&'
  166. %left <code> MIN_MAX
  167. %left <code> EQCOMPARE
  168. %left <code> ARITHCOMPARE '<' '>'
  169. %left <code> LSHIFT RSHIFT
  170. %left <code> '+' '-'
  171. %left <code> '*' '/' '%'
  172. %right <code> UNARY PLUSPLUS MINUSMINUS
  173. %left HYPERUNARY
  174. %left <ttype> PAREN_STAR_PAREN LEFT_RIGHT
  175. %left <code> POINTSAT '.' '(' '['
  176.  
  177. %right SCOPE            /* C++ extension */
  178. %nonassoc NEW DELETE RAISE RAISES RERAISE TRY EXCEPT CATCH
  179. %right DYNAMIC
  180.  
  181. %type <code> unop
  182.  
  183. %type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist /* exprlist */
  184. %type <ttype> expr_no_commas cast_expr unary_expr primary string STRING
  185. %type <ttype> typed_declspecs reserved_declspecs
  186. %type <ttype> typed_typespecs reserved_typespecquals
  187. %type <ttype> declmods typespec typespecqual_reserved
  188. %type <ttype> SCSPEC TYPESPEC TYPE_QUAL nonempty_type_quals maybe_type_qual
  189. %type <itype> initdecls notype_initdecls initdcl    /* C++ modification */
  190. %type <ttype> init initlist maybeasm
  191. %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
  192. %type <ttype> maybe_attribute attribute_list attrib
  193. %type <ttype> abs_member_declarator after_type_member_declarator
  194.  
  195. %type <ttype> compstmt except_stmts
  196.  
  197. %type <ttype> declarator notype_declarator after_type_declarator
  198.  
  199. %type <ttype> structsp opt.component_decl_list component_decl_list component_decl components component_declarator
  200. %type <ttype> enumlist enumerator
  201. %type <ttype> typename absdcl absdcl1 type_quals
  202. %type <ttype> xexpr see_typename parmlist parms parm bad_parm
  203.  
  204. /* C++ extensions */
  205. %token <ttype> TYPENAME_COLON TYPENAME_SCOPE TYPENAME_ELLIPSIS
  206. %token <ttype> PTYPENAME SCOPED_TYPENAME
  207. %token <ttype> PRE_PARSED_FUNCTION_DECL EXTERN_LANG_STRING ALL
  208. %token <ttype> PRE_PARSED_CLASS_DECL END_OF_SAVED_INPUT
  209. %type <ttype> fn.def1 /* Not really! */
  210. %type <ttype> fn.def2 return_id
  211. %type <ttype> named_class_head named_class_head_sans_basetype
  212. %type <ttype> unnamed_class_head
  213. %type <ttype> class_head base_class_list
  214. %type <itype> base_class_visibility_list
  215. %type <ttype> base_class maybe_base_class_list base_class.1
  216. %type <ttype> after_type_declarator_no_typename
  217. %type <ttype> maybe_raises raise_identifier raise_identifiers
  218. %type <ttype> component_declarator0 scoped_id scoped_typename
  219. %type <ttype> forhead.1 identifier_or_opname operator_name
  220. %type <ttype> new delete object primary_no_id aggr nonmomentary_expr
  221. %type <itype> LC forhead.2 initdcl0 notype_initdcl0 wrapper member_init_list
  222. %type <itype> .scope try
  223. %type <ttype> template_header template_parm_list template_parm
  224. %type <ttype> template_type template_arg_list template_arg
  225. %type <ttype> template_instantiation template_type_name
  226.  
  227. %{
  228. /* the declaration found for the last IDENTIFIER token read in.
  229.    yylex must look this up to detect typedefs, which get token type TYPENAME,
  230.    so it is left around in case the identifier is not a typedef but is
  231.    used in a context which makes it a reference to a variable.  */
  232. tree lastiddecl;
  233.  
  234. /* Back-door communication channel to the lexer.  */
  235. extern int looking_for_typename;
  236.  
  237. tree make_pointer_declarator (), make_reference_declarator ();
  238.  
  239. void reinit_parse_for_function ();
  240. void reinit_parse_for_method ();
  241.  
  242. /* List of types and structure classes of the current declaration.  */
  243. tree current_declspecs;
  244.  
  245. /* When defining an aggregate, this is the most recent one being defined.  */
  246. static tree current_aggr;
  247.  
  248. int undeclared_variable_notice;    /* 1 if we explained undeclared var errors.  */
  249.  
  250. int yylex ();
  251.  
  252. static
  253. #ifdef __GNUC__
  254. inline
  255. #endif
  256. yyprint (file, yychar, yylval)
  257.      FILE *file;
  258.      int yychar;
  259.      YYSTYPE yylval;
  260. {
  261.   tree t;
  262.   switch (yychar)
  263.     {
  264.     case IDENTIFIER:
  265.     case TYPENAME:
  266.     case PTYPENAME:
  267.     case TYPENAME_COLON:
  268.     case TYPENAME_SCOPE:
  269.     case TYPENAME_ELLIPSIS:
  270.     case SCOPED_TYPENAME:
  271.       t = yylval.ttype;
  272.       assert (TREE_CODE (t) == IDENTIFIER_NODE);
  273.       if (IDENTIFIER_POINTER (t))
  274.       fprintf (file, " `%s'", IDENTIFIER_POINTER (t));
  275.     }
  276. }
  277. #define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL)
  278.  
  279.  
  280. /* Sets the value of the 'yydebug' varable to VALUE.
  281.    This is a function so we don't have to have YYDEBUG defined
  282.    in order to build the compiler.  */
  283. void
  284. set_yydebug (value)
  285.      int value;
  286. {
  287. #if YYDEBUG != 0
  288.   extern int yydebug;
  289.   yydebug = value;
  290. #else
  291.   warning ("YYDEBUG not defined.");
  292. #endif
  293. }
  294. %}
  295.  
  296. %%
  297. program: /* empty */
  298.     | extdefs
  299.         { finish_file (); }
  300.     ;
  301.  
  302. /* the reason for the strange actions in this rule
  303.  is so that notype_initdecls when reached via datadef
  304.  can find a valid list of type and sc specs in $0. */
  305.  
  306. extdefs:
  307.       { $<ttype>$ = NULL_TREE; } extdef
  308.         {$<ttype>$ = NULL_TREE; }
  309.     | extdefs extdef
  310.         {$<ttype>$ = NULL_TREE; }
  311.     ;
  312.  
  313. extdef:
  314.       fndef
  315.         { if (pending_inlines) do_pending_inlines (); }
  316.     | datadef
  317.         { if (pending_inlines) do_pending_inlines (); }
  318.     | overloaddef
  319.     | ASM '(' string ')' ';'
  320.         { if (pedantic)
  321.             warning ("ANSI C forbids use of `asm' keyword");
  322.           if (TREE_CHAIN ($3)) $3 = combine_strings ($3);
  323.           assemble_asm ($3); }
  324.     | extern_lang_string '{' extdefs '}'
  325.         { pop_lang_context (); }
  326.     | extern_lang_string '{' '}'
  327.         { pop_lang_context (); }
  328.     | extern_lang_string fndef
  329.         { if (pending_inlines) do_pending_inlines ();
  330.           pop_lang_context (); }
  331.     | extern_lang_string datadef
  332.         { if (pending_inlines) do_pending_inlines ();
  333.           pop_lang_context (); }
  334.     ;
  335.  
  336. extern_lang_string:
  337.       EXTERN_LANG_STRING
  338.         { push_lang_context ($1); }
  339.     ;
  340.  
  341. template_header:
  342.       TEMPLATE '<'
  343.         { begin_template_parm_list (); }
  344.       template_parm_list '>'
  345.         { $$ = end_template_parm_list ($4); }
  346.     ;
  347.  
  348. template_parm_list:
  349.       template_parm
  350.         { $$ = process_template_parm (0, $1); }
  351.     | template_parm_list ',' template_parm
  352.         { $$ = process_template_parm ($1, $3); }
  353.     ;
  354.  
  355. template_parm:
  356.     /* The following rules introduce a new reduce/reduce
  357.        conflict: they are valid prefixes for a `structsp',
  358.        which means they could match a nameless parameter.
  359.        By putting them before the `parm' rule, we get
  360.        their match before considering them nameless parameter
  361.        declarations.  */
  362.       aggr identifier
  363.         {
  364.           if ((enum tag_types) TREE_INT_CST_LOW ($1) != class_type)
  365.             error ("template type parameter must use keyword `class'");
  366.           $$ = build_tree_list ($2, NULL_TREE);
  367.         }
  368.     | aggr identifier ':' base_class.1
  369.         {
  370.           if ((enum tag_types) TREE_INT_CST_LOW ($1) != class_type)
  371.             error ("template type parameter must use keyword `class'");
  372.           warning ("restricted template type parameters not yet implemented");
  373.           $$ = build_tree_list ($2, $4);
  374.         }
  375.     | aggr TYPENAME_COLON base_class.1
  376.         {
  377.           if ((enum tag_types) TREE_INT_CST_LOW ($1) != class_type)
  378.             error ("template type parameter must use keyword `class'");
  379.           warning ("restricted template type parameters not yet implemented");
  380.           $$ = build_tree_list ($2, $3);
  381.         }
  382.     | parm
  383.     ;
  384.  
  385. overloaddef:
  386.       OVERLOAD ov_identifiers ';'
  387.  
  388. ov_identifiers: IDENTIFIER
  389.         { declare_overloaded ($1); }
  390.     | ov_identifiers ',' IDENTIFIER
  391.         { declare_overloaded ($3); }
  392.     ;
  393.       
  394. datadef:
  395.       notype_initdecls ';'
  396.         { if (pedantic)
  397.             error ("ANSI C forbids data definition with no type or storage class");
  398.             else if (! flag_traditional)
  399.               warning ("data definition has no type or storage class"); }
  400.     | declmods notype_initdecls ';'
  401.         {}
  402.     /* Normal case to make fast: "int i;".  */
  403.     | declmods declarator ';'
  404.         { tree d;
  405.           d = start_decl ($2, $<ttype>$, 0, NULL_TREE);
  406.           finish_decl (d, NULL_TREE, NULL_TREE);
  407.         }
  408.     | typed_declspecs initdecls ';'
  409.         {
  410.           end_exception_decls ();
  411.           note_list_got_semicolon ($<ttype>$);
  412.         }
  413.     /* Normal case: make this fast.  */
  414.     | typed_declspecs declarator ';'
  415.         { tree d;
  416.           d = start_decl ($2, $<ttype>$, 0, NULL_TREE);
  417.           finish_decl (d, NULL_TREE, NULL_TREE);
  418.           end_exception_decls ();
  419.           note_list_got_semicolon ($<ttype>$);
  420.         }
  421.         | declmods ';'
  422.       { error ("empty declaration"); }
  423.     | typed_declspecs ';'
  424.       {
  425.         shadow_tag ($<ttype>$);
  426.         note_list_got_semicolon ($<ttype>$);
  427.       }
  428.     /* Class template declarations go here; they aren't normal class
  429.        declarations, because we can't process the bodies yet.
  430.        Should move these elsewhere sometime, so we can have nested
  431.        templates, but for now this will do.  */
  432.     | template_header named_class_head_sans_basetype '{'
  433.         { yychar = '{'; goto template1; }
  434.      ';'
  435.     | template_header named_class_head_sans_basetype ':'
  436.         {
  437.           yychar = ':';
  438.         template1:
  439.           if (current_aggr == exception_type_node)
  440.             error ("template type must define an aggregate or union");
  441.           /* Maybe pedantic warning for union?
  442.              How about an enum? :-)  */
  443.           end_template_decl ($1, $2);
  444.           reinit_parse_for_template (yychar, $1, $2);
  445.           yychar = YYEMPTY;
  446.         }
  447.       ';'
  448.     | template_header named_class_head_sans_basetype ';'
  449.         {
  450.           end_template_decl ($1, $2);
  451.           /* declare $2 as template name with $1 parm list */
  452.         }
  453.     | error ';'
  454.     | error '}'
  455.     | ';'
  456.     ;
  457.  
  458. fndef:
  459.       fn.def1 base_init compstmt_or_error
  460.         {
  461.           finish_function (lineno, 1);
  462.           /* finish_function performs these three statements:
  463.  
  464.              expand_end_bindings (getdecls (), 1, 0);
  465.              poplevel (1, 1, 0);
  466.  
  467.              expand_end_bindings (0, 0, 0);
  468.              poplevel (0, 0, 1);
  469.              */
  470.           if ($<ttype>$) process_next_inline ($<ttype>$);
  471.         }
  472.     | fn.def1 return_init base_init compstmt_or_error
  473.         {
  474.           finish_function (lineno, 1);
  475.           /* finish_function performs these three statements:
  476.  
  477.              expand_end_bindings (getdecls (), 1, 0);
  478.              poplevel (1, 1, 0);
  479.  
  480.              expand_end_bindings (0, 0, 0);
  481.              poplevel (0, 0, 1);
  482.              */
  483.           if ($<ttype>$) process_next_inline ($<ttype>$);
  484.         }
  485.     | fn.def1 nodecls compstmt_or_error
  486.         { finish_function (lineno, 0);
  487.           if ($<ttype>$) process_next_inline ($<ttype>$); }
  488.     | fn.def1 return_init ';' nodecls compstmt_or_error
  489.         { finish_function (lineno, 0);
  490.           if ($<ttype>$) process_next_inline ($<ttype>$); }
  491.     | fn.def1 return_init nodecls compstmt_or_error
  492.         { finish_function (lineno, 0);
  493.           if ($<ttype>$) process_next_inline ($<ttype>$); }
  494.     | typed_declspecs declarator error
  495.         {}
  496.     | declmods notype_declarator error
  497.         {}
  498.     | notype_declarator error
  499.         {}
  500.     ;
  501.  
  502. fn.def1:
  503.       typed_declspecs declarator maybe_raises
  504.         { if (! start_function ($$, $2, $3, 0))
  505.             YYERROR1;
  506.           reinit_parse_for_function ();
  507.           $$ = NULL_TREE; }
  508.     | declmods notype_declarator maybe_raises
  509.         { if (! start_function ($$, $2, $3, 0))
  510.             YYERROR1;
  511.           reinit_parse_for_function ();
  512.           $$ = NULL_TREE; }
  513.     | notype_declarator maybe_raises
  514.         { if (! start_function (NULL_TREE, $$, $2, 0))
  515.             YYERROR1;
  516.           reinit_parse_for_function ();
  517.           $$ = NULL_TREE; }
  518.     | TYPENAME '(' parmlist ')' type_quals maybe_raises
  519.         { if (! start_function (NULL_TREE, build_parse_node (CALL_EXPR, $$, $3, $5), $6, 0))
  520.             YYERROR1;
  521.           reinit_parse_for_function ();
  522.           $$ = NULL_TREE; }
  523.     | scoped_typename '(' parmlist ')' type_quals maybe_raises
  524.         { if (! start_function (NULL_TREE, build_parse_node (CALL_EXPR, $$, $3, $5), $6, 0))
  525.             YYERROR1;
  526.           reinit_parse_for_function ();
  527.           $$ = NULL_TREE; }
  528.     | TYPENAME LEFT_RIGHT type_quals maybe_raises
  529.         { if (! start_function (NULL_TREE, build_parse_node (CALL_EXPR, $$, empty_parms (), $3), $4, 0))
  530.             YYERROR1;
  531.           reinit_parse_for_function ();
  532.           $$ = NULL_TREE; }
  533.     | scoped_typename LEFT_RIGHT type_quals maybe_raises
  534.         { if (! start_function (NULL_TREE, build_parse_node (CALL_EXPR, $$, empty_parms (), $3), $4, 0))
  535.             YYERROR1;
  536.           reinit_parse_for_function ();
  537.           $$ = NULL_TREE; }
  538.     | PRE_PARSED_FUNCTION_DECL
  539.         { start_function (NULL_TREE, TREE_VALUE ($$), NULL_TREE, 1);
  540.           reinit_parse_for_function (); }
  541.     ;
  542.  
  543. /* more C++ complexity */
  544. fn.def2:
  545.       typed_declspecs '(' parmlist ')' type_quals maybe_raises
  546.         {
  547.           tree decl = build_parse_node (CALL_EXPR, TREE_VALUE ($$), $3, $5);
  548.           $$ = start_method (TREE_CHAIN ($$), decl, $6);
  549.           if (! $$)
  550.             YYERROR1;
  551.           if (yychar == YYEMPTY)
  552.             yychar = YYLEX;
  553.           reinit_parse_for_method (yychar, $$); }
  554.     | typed_declspecs LEFT_RIGHT type_quals maybe_raises
  555.         {
  556.           tree decl = build_parse_node (CALL_EXPR, TREE_VALUE ($$), empty_parms (), $3);
  557.           $$ = start_method (TREE_CHAIN ($$), decl, $4);
  558.           if (! $$)
  559.             YYERROR1;
  560.           if (yychar == YYEMPTY)
  561.             yychar = YYLEX;
  562.           reinit_parse_for_method (yychar, $$); }
  563.     | typed_declspecs declarator maybe_raises
  564.         { $$ = start_method ($$, $2, $3);
  565.           if (! $$)
  566.             YYERROR1;
  567.           if (yychar == YYEMPTY)
  568.             yychar = YYLEX;
  569.           reinit_parse_for_method (yychar, $$); }
  570.     | declmods '(' parmlist ')' type_quals maybe_raises
  571.         {
  572.           tree decl = build_parse_node (CALL_EXPR, TREE_VALUE ($$), $3, $5);
  573.           $$ = start_method (TREE_CHAIN ($$), decl, $6);
  574.           if (! $$)
  575.             YYERROR1;
  576.           if (yychar == YYEMPTY)
  577.             yychar = YYLEX;
  578.           reinit_parse_for_method (yychar, $$); }
  579.     | declmods LEFT_RIGHT type_quals maybe_raises
  580.         {
  581.           tree decl = build_parse_node (CALL_EXPR, TREE_VALUE ($$), empty_parms (), $3);
  582.           $$ = start_method (TREE_CHAIN ($$), decl, $4);
  583.           if (! $$)
  584.             YYERROR1;
  585.           if (yychar == YYEMPTY)
  586.             yychar = YYLEX;
  587.           reinit_parse_for_method (yychar, $$); }
  588.     | declmods declarator maybe_raises
  589.         { $$ = start_method ($$, $2, $3);
  590.           if (! $$)
  591.             YYERROR1;
  592.           if (yychar == YYEMPTY)
  593.             yychar = YYLEX;
  594.           reinit_parse_for_method (yychar, $$); }
  595.     | notype_declarator maybe_raises
  596.         { $$ = start_method (NULL_TREE, $$, $2);
  597.           if (! $$)
  598.             YYERROR1;
  599.           if (yychar == YYEMPTY)
  600.             yychar = YYLEX;
  601.           reinit_parse_for_method (yychar, $$); }
  602.     ;
  603.  
  604. return_id: RETURN IDENTIFIER
  605.         {
  606.           if (! current_function_parms_stored)
  607.             store_parm_decls ();
  608.           $$ = $2;
  609.         }
  610.     ;
  611.  
  612. return_init: return_id
  613.         { store_return_init ($<ttype>$, NULL_TREE); }
  614.     | return_id '=' init
  615.         { store_return_init ($<ttype>$, $2); }
  616.     | return_id '(' nonnull_exprlist ')'
  617.         { store_return_init ($<ttype>$, $3); }
  618.     | return_id LEFT_RIGHT
  619.         { store_return_init ($<ttype>$, NULL_TREE); }
  620.     ;
  621.  
  622. base_init:
  623.       ':' .set_base_init member_init_list
  624.         {
  625.           if ($3 == 0)
  626.             error ("no base initializers given following ':'");
  627.           setup_vtbl_ptr ();
  628.         }
  629.     ;
  630.  
  631. .set_base_init:
  632.     /* empty */
  633.         {
  634.           if (! current_function_parms_stored)
  635.             store_parm_decls ();
  636.  
  637.           /* Flag that we are processing base and member initializers.  */
  638.           current_vtable_decl = error_mark_node;
  639.  
  640.           if (DECL_CONSTRUCTOR_P (current_function_decl))
  641.             {
  642.               /* Make a contour for the initializer list.  */
  643.               pushlevel (0);
  644.               clear_last_expr ();
  645.               expand_start_bindings (0);
  646.             }
  647.           else if (current_class_type == NULL_TREE)
  648.             error ("base initializers not allowed for non-member functions");
  649.           else if (! DECL_CONSTRUCTOR_P (current_function_decl))
  650.             error ("only constructors take base initializers");
  651.         }
  652.     ;
  653.  
  654. member_init_list:
  655.       /* empty */
  656.         { $$ = 0; }
  657.     | member_init
  658.         { $$ = 1; }
  659.     | member_init_list ',' member_init
  660.     | member_init_list error
  661.     ;
  662.  
  663. member_init: '(' nonnull_exprlist ')'
  664.         {
  665.           if (current_class_name && pedantic)
  666.             warning ("old style base class initialization; use `%s (...)'",
  667.                  IDENTIFIER_POINTER (current_class_name));
  668.           expand_member_init (C_C_D, NULL_TREE, $2);
  669.         }
  670.     | LEFT_RIGHT
  671.         {
  672.           if (current_class_name && pedantic)
  673.             warning ("old style base class initialization; use `%s (...)'",
  674.                  IDENTIFIER_POINTER (current_class_name));
  675.           expand_member_init (C_C_D, NULL_TREE, void_type_node);
  676.         }
  677.     | identifier '(' nonnull_exprlist ')'
  678.         {
  679.           expand_member_init (C_C_D, $<ttype>$, $3);
  680.         }
  681.     | identifier LEFT_RIGHT
  682.         { expand_member_init (C_C_D, $<ttype>$, void_type_node); }
  683.     | scoped_id identifier '(' nonnull_exprlist ')'
  684.         {
  685.           do_member_init ($<ttype>$, $2, $4);
  686.         }
  687.     | scoped_id identifier LEFT_RIGHT
  688.         {
  689.           do_member_init ($<ttype>$, $2, void_type_node);
  690.         }
  691.     ;
  692.  
  693. identifier:
  694.       IDENTIFIER
  695.     | TYPENAME
  696.     | PTYPENAME
  697.     ;
  698.  
  699. identifier_or_opname:
  700.       IDENTIFIER
  701.     | TYPENAME
  702. /*    | '~' TYPENAME
  703.         { $$ = build_parse_node (BIT_NOT_EXPR, $2); }*/
  704.     /* get rid of the next line, replace it with the above */
  705.     | PTYPENAME | '~' identifier { $$ = build_parse_node (BIT_NOT_EXPR,$2);}
  706.     | operator_name
  707.         { $$ = hack_operator ($$);
  708.           if ($$ == error_mark_node)
  709.             $$ = get_identifier ("<missing operator>"); }
  710.     | wrapper IDENTIFIER
  711.         { $$ = hack_wrapper ($$, NULL_TREE, $2); }
  712.     | wrapper TYPENAME
  713.         { $$ = hack_wrapper ($$, NULL_TREE, $2); }
  714.     | wrapper operator_name
  715.         { $$ = hack_wrapper ($$, NULL_TREE, $2); }
  716.     | wrapper scoped_id IDENTIFIER
  717.         { $$ = hack_wrapper ($$, $2, $3); }
  718.     | wrapper scoped_id operator_name
  719.         { $$ = hack_wrapper ($$, $2, $3); }
  720.     ;
  721.  
  722. wrapper:  LEFT_RIGHT
  723.         { $$ = 0; }
  724.     | '~' LEFT_RIGHT
  725.         { $$ = 1; }
  726.     | LEFT_RIGHT '?'
  727.         { $$ = 2; }
  728.     ;
  729.  
  730. template_type:
  731.       template_type_name tmpl.1 template_instantiation
  732.         {
  733.           if ($3) $$ = $3;
  734.           else $$ = TREE_TYPE ($$);
  735.         }
  736.     ;
  737.  
  738. template_type_name:
  739.       PTYPENAME '<' template_arg_list '>'
  740.         { $$ = lookup_template_class ($$, $3); }
  741.     ;
  742.  
  743. tmpl.1:
  744.     /* Expansion of template may be required, unless we're followed by
  745.        a class definition.  */
  746.       '{'    { yyungetc ('{', 1); }
  747.     | ':'    { yyungetc (':', 1); }
  748.     | /* empty */ %prec EMPTY
  749.         { goto maybe_do_template_instantiation; }
  750.     ;
  751.  
  752. tmpl.2:
  753.     /* Always do expansion if it hasn't been done already. */
  754.         {
  755.         maybe_do_template_instantiation:
  756.           if (!TREE_TYPE ($<ttype>0))
  757.             instantiate_template ($<ttype>0);
  758.         }
  759.     ;
  760.  
  761. template_arg_list:
  762.       template_arg
  763.         { $$ = build_tree_list (NULL_TREE, $$); }
  764.     | template_arg_list ',' template_arg
  765.         { $$ = chainon ($$, build_tree_list (NULL_TREE, $3)); }
  766.     ;
  767.  
  768. template_arg:
  769.       typename
  770.         { $$ = groktypename ($$); }
  771.     | expr_no_commas  %prec UNARY
  772.     ;
  773.  
  774. template_instantiation:
  775.       /* empty */
  776.         { $$ = NULL_TREE; }
  777.     | PRE_PARSED_CLASS_DECL maybe_base_class_list
  778.         {
  779.           extern tree current_template_name;
  780.           tree t, decl, id;
  781.  
  782.           id = TREE_VALUE ($1);
  783.           t = xref_tag (class_type_node, id, $2);
  784.           set_current_level_tags_transparency (1);
  785.           assert (TREE_CODE (t) == RECORD_TYPE);
  786.           $<ttype>$ = t;
  787.  
  788.           /* Now, put a copy of the decl in global scope, to avoid
  789.              recursive expansion.  */
  790.           decl = IDENTIFIER_LOCAL_VALUE (id);
  791.           if (!decl)
  792.             decl = IDENTIFIER_CLASS_VALUE (id);
  793.           assert (decl != 0 && TREE_CODE (decl) == TYPE_DECL);
  794.           IDENTIFIER_GLOBAL_VALUE (id) = decl;
  795.         }
  796.       LC opt.component_decl_list '}'
  797.         {
  798.           extern void end_template_instantiation ();
  799.           tree template = IDENTIFIER_TEMPLATE (TREE_VALUE ($1));
  800.           $$ = finish_struct ($<ttype>3, $5, 0, 0);
  801.  
  802.           if ($4 & 1)
  803.             resume_temporary_allocation ();
  804.           if ($4 & 2)
  805.             resume_momentary (1);
  806.           end_template_instantiation ($1, $<ttype>3);
  807.         }
  808.     ;
  809.  
  810. unop:     '-'
  811.         { $$ = NEGATE_EXPR; }
  812.     | '+'
  813.         { $$ = CONVERT_EXPR; }
  814.     | PLUSPLUS
  815.         { $$ = PREINCREMENT_EXPR; }
  816.     | MINUSMINUS
  817.         { $$ = PREDECREMENT_EXPR; }
  818.     | '!'
  819.         { $$ = TRUTH_NOT_EXPR; }
  820.     ;
  821.  
  822. expr:      nonnull_exprlist
  823.         { $$ = build_x_compound_expr ($$); }
  824.     /* Ugly, but faster.  */
  825.     | expr_no_commas
  826.         {
  827.           if (TREE_CODE ($$) == CALL_EXPR
  828.               && TYPE_NEEDS_DESTRUCTOR (TREE_TYPE ($$)))
  829.             $$ = cleanup_after_call ($$);
  830.         }
  831.     ;
  832.  
  833. /* Now obsolete.
  834. exprlist:
  835.       / * empty * /
  836.         { $$ = NULL_TREE; }
  837.     | nonnull_exprlist
  838.     ;
  839. */
  840.  
  841. nonnull_exprlist:
  842.       expr_no_commas
  843.         { $$ = build_tree_list (NULL_TREE, $$); }
  844.     | nonnull_exprlist ',' expr_no_commas
  845.         { chainon ($$, build_tree_list (NULL_TREE, $3)); }
  846.     | nonnull_exprlist ',' error
  847.         { chainon ($$, build_tree_list (NULL_TREE, error_mark_node)); }
  848.     ;
  849.  
  850. unary_expr:
  851.       primary %prec UNARY
  852.         {
  853.           if (TREE_CODE ($$) == TYPE_EXPR)
  854.             $$ = build_component_type_expr (C_C_D, $$, NULL_TREE, 1);
  855.         }
  856.     | '*' cast_expr   %prec UNARY
  857.         { $$ = build_x_indirect_ref ($2, "unary *"); }
  858.     | '&' cast_expr   %prec UNARY
  859.         { $$ = build_x_unary_op (ADDR_EXPR, $2); }
  860.     | '~' cast_expr   %prec UNARY
  861.         { $$ = build_x_unary_op (BIT_NOT_EXPR, $2); }
  862.     | unop cast_expr  %prec UNARY
  863.         { $$ = build_x_unary_op ($$, $2);
  864.           if ($1 == NEGATE_EXPR && TREE_CODE ($2) == INTEGER_CST)
  865.             TREE_NEGATED_INT ($$) = 1;
  866.         }
  867.     | SIZEOF unary_expr  %prec UNARY
  868.         { if (TREE_CODE ($2) == COMPONENT_REF
  869.               && DECL_BIT_FIELD (TREE_OPERAND ($2, 1)))
  870.             error ("sizeof applied to a bit-field");
  871.           /* ANSI says arrays and functions are converted inside comma.
  872.              But we can't really convert them in build_compound_expr
  873.              because that would break commas in lvalues.
  874.              So do the conversion here if operand was a comma.  */
  875.           if (TREE_CODE ($2) == COMPOUND_EXPR
  876.               && (TREE_CODE (TREE_TYPE ($2)) == ARRAY_TYPE
  877.               || TREE_CODE (TREE_TYPE ($2)) == FUNCTION_TYPE))
  878.             $2 = default_conversion ($2);
  879.           $$ = c_sizeof (TREE_TYPE ($2)); }
  880.     | SIZEOF '(' typename ')'  %prec HYPERUNARY
  881.         { $$ = c_sizeof (groktypename ($3)); }
  882.     | ALIGNOF unary_expr  %prec UNARY
  883.         { if (TREE_CODE ($2) == COMPONENT_REF
  884.               && DECL_BIT_FIELD (TREE_OPERAND ($2, 1)))
  885.             error ("`__alignof' applied to a bit-field");
  886.           if (TREE_CODE ($2) == INDIRECT_REF)
  887.             {
  888.               tree t = TREE_OPERAND ($2, 0);
  889.               tree best = t;
  890.               int bestalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t)));
  891.               while (TREE_CODE (t) == NOP_EXPR
  892.                  && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == POINTER_TYPE)
  893.             {
  894.               int thisalign;
  895.               t = TREE_OPERAND (t, 0);
  896.               thisalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t)));
  897.               if (thisalign > bestalign)
  898.                 best = t, bestalign = thisalign;
  899.             }
  900.               $$ = c_alignof (TREE_TYPE (TREE_TYPE (best)));
  901.             }
  902.           else
  903.             {
  904.               /* ANSI says arrays and fns are converted inside comma.
  905.              But we can't convert them in build_compound_expr
  906.              because that would break commas in lvalues.
  907.              So do the conversion here if operand was a comma.  */
  908.               if (TREE_CODE ($2) == COMPOUND_EXPR
  909.               && (TREE_CODE (TREE_TYPE ($2)) == ARRAY_TYPE
  910.                   || TREE_CODE (TREE_TYPE ($2)) == FUNCTION_TYPE))
  911.             $2 = default_conversion ($2);
  912.               $$ = c_alignof (TREE_TYPE ($2));
  913.             }
  914.         }
  915.     | ALIGNOF '(' typename ')'  %prec HYPERUNARY
  916.         { $$ = c_alignof (groktypename ($3)); }
  917.  
  918.     | .scope new typename %prec '='
  919.         { $$ = build_new ($2, $3, NULL_TREE, $$); }
  920.     | .scope new typespec '(' nonnull_exprlist ')'
  921.         { $$ = build_new ($2, $3, $5, $$); }
  922.     | .scope new typespec LEFT_RIGHT
  923.         { $$ = build_new ($2, $3, NULL_TREE, $$); }
  924.     | .scope new typename '=' init %prec '='
  925.         { $$ = build_new ($2, $3, $5, $$); }
  926.     | .scope new '(' typename ')' '[' expr ']'
  927.         {
  928.           /* I'm not sure why this is disallowed.  But since
  929.              it is, and it doesn't seem difficult to catch it,
  930.              let's give an informative error message, so the
  931.              programmer can fix it.  --Ken Raeburn  */
  932.           error ("array dimensions with parenthesized type gratuitously disallowed");
  933.           $$ = error_mark_node;
  934.         }
  935.     | .scope new '(' typename ')'
  936.         { $$ = build_new ($2, $4, NULL_TREE, $$); }
  937.     /* Unswallow a ':' which is probably meant for ?: expression.  */
  938.     | .scope new TYPENAME_COLON
  939.         { yyungetc (':', 1);
  940.           $$ = build_new ($2, $3, NULL_TREE, $$); }
  941.  
  942.     | delete cast_expr  %prec UNARY
  943.         { tree expr = stabilize_reference (convert_from_reference ($2));
  944.           tree type = TREE_TYPE (expr);
  945.  
  946.           if (integer_zerop (expr))
  947.             $$ = build1 (NOP_EXPR, void_type_node, expr);
  948.           else if (TREE_CODE (type) != POINTER_TYPE)
  949.             {
  950.               error ("non-pointer type to `delete'");
  951.               $$ = error_mark_node;
  952.               break;
  953.             }
  954.           if (TYPE_HAS_DESTRUCTOR (TREE_TYPE (type)))
  955.             $$ = build_delete (type, expr, integer_three_node,
  956.                        LOOKUP_NORMAL|LOOKUP_HAS_IN_CHARGE, $$);
  957.           else if (! TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (type)))
  958.             $$ = build_x_delete (type, expr, $$);
  959.           else
  960.             $$ = build_delete (type, expr, integer_three_node,
  961.                        LOOKUP_NORMAL|LOOKUP_HAS_IN_CHARGE, 0);
  962.         }
  963.     | delete '[' expr ']' cast_expr  %prec UNARY
  964.         {
  965.           tree maxindex = build_binary_op (MINUS_EXPR, $3, integer_one_node);
  966.           tree exp = stabilize_reference (convert_from_reference ($5));
  967.           tree elt_size = c_sizeof (TREE_TYPE (exp));
  968.  
  969.           if (yychar == YYEMPTY)
  970.             yychar = YYLEX;
  971.  
  972.           $$ = build_vec_delete (exp, maxindex, elt_size, NULL_TREE,
  973.                      integer_one_node, integer_two_node);
  974.         }
  975.     | delete '[' ']' cast_expr %prec UNARY
  976.         {
  977.           tree maxindex;
  978.           tree exp = convert_from_reference ($4), dtype;
  979.  
  980.           dtype = TREE_TYPE (exp);
  981.  
  982.           if (TREE_CODE (dtype) != ARRAY_TYPE)
  983.             {
  984.               if (dtype != error_mark_node)
  985.             error ("delete [] applied to non-array type");
  986.               $$ = error_mark_node;
  987.             }
  988.           else
  989.             {
  990.               tree elt_size;
  991.  
  992.               maxindex = TYPE_MAX_VALUE (TYPE_DOMAIN (dtype));
  993.               exp = stabilize_reference (exp);
  994.               elt_size = c_sizeof (TREE_TYPE (exp));
  995.  
  996.               if (yychar == YYEMPTY)
  997.             yychar = YYLEX;
  998.  
  999.               $$ = build_vec_delete (exp, maxindex, elt_size, NULL_TREE,
  1000.                          integer_one_node, integer_two_node);
  1001.             }
  1002.         }
  1003.     ;
  1004.  
  1005. cast_expr:
  1006.       unary_expr
  1007.     | '(' typename ')' expr_no_commas  %prec UNARY
  1008.         { tree type = groktypename ($2);
  1009.           $$ = build_c_cast (type, $4); }
  1010.     | '(' typename ')' '{' initlist maybecomma '}'  %prec UNARY
  1011.         { tree type = groktypename ($2);
  1012.           tree init = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($5));
  1013.           if (pedantic)
  1014.             warning ("ANSI C forbids constructor-expressions");
  1015.           /* Indicate that this was a GNU C constructor expression.  */
  1016.           TREE_HAS_CONSTRUCTOR (init) = 1;
  1017.           $$ = digest_init (type, init, 0);
  1018.           if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (type) == 0)
  1019.             {
  1020.               int failure = complete_array_type (type, $$, 1);
  1021.               if (failure)
  1022.             abort ();
  1023.             }
  1024.         }
  1025.     | HEADOF '(' expr ')'
  1026.         { $$ = build_headof ($3); }
  1027.     | CLASSOF '(' expr ')'
  1028.         { $$ = build_classof ($3); }
  1029.     | CLASSOF '(' TYPENAME ')'
  1030.         { if (is_aggr_typedef ($3, 1))
  1031.             {
  1032.               tree type = IDENTIFIER_TYPE_VALUE ($3);
  1033.               $$ = CLASSTYPE_DOSSIER (type);
  1034.             }
  1035.           else
  1036.             $$ = error_mark_node;
  1037.         }
  1038.     ;
  1039.  
  1040. expr_no_commas:
  1041.       cast_expr
  1042.     | expr_no_commas '+' expr_no_commas
  1043.         { $$ = build_x_binary_op ($2, $$, $3); }
  1044.     | expr_no_commas '-' expr_no_commas
  1045.         { $$ = build_x_binary_op ($2, $$, $3); }
  1046.     | expr_no_commas '*' expr_no_commas
  1047.         { $$ = build_x_binary_op ($2, $$, $3); }
  1048.     | expr_no_commas '/' expr_no_commas
  1049.         { $$ = build_x_binary_op ($2, $$, $3); }
  1050.     | expr_no_commas '%' expr_no_commas
  1051.         { $$ = build_x_binary_op ($2, $$, $3); }
  1052.     | expr_no_commas LSHIFT expr_no_commas
  1053.         { $$ = build_x_binary_op ($2, $$, $3); }
  1054.     | expr_no_commas RSHIFT expr_no_commas
  1055.         { $$ = build_x_binary_op ($2, $$, $3); }
  1056.     | expr_no_commas ARITHCOMPARE expr_no_commas
  1057.         { $$ = build_x_binary_op ($2, $$, $3); }
  1058.     | expr_no_commas '<' expr_no_commas
  1059.         { $$ = build_x_binary_op (LT_EXPR, $$, $3); }
  1060.     | expr_no_commas '>' expr_no_commas
  1061.         { $$ = build_x_binary_op (GT_EXPR, $$, $3); }
  1062.     | expr_no_commas EQCOMPARE expr_no_commas
  1063.         { $$ = build_x_binary_op ($2, $$, $3); }
  1064.     | expr_no_commas MIN_MAX expr_no_commas
  1065.         { $$ = build_x_binary_op ($2, $$, $3); }
  1066.     | expr_no_commas '&' expr_no_commas
  1067.         { $$ = build_x_binary_op ($2, $$, $3); }
  1068.     | expr_no_commas '|' expr_no_commas
  1069.         { $$ = build_x_binary_op ($2, $$, $3); }
  1070.     | expr_no_commas '^' expr_no_commas
  1071.         { $$ = build_x_binary_op ($2, $$, $3); }
  1072.     | expr_no_commas ANDAND expr_no_commas
  1073.         { $$ = build_x_binary_op (TRUTH_ANDIF_EXPR, $$, $3); }
  1074.     | expr_no_commas OROR expr_no_commas
  1075.         { $$ = build_x_binary_op (TRUTH_ORIF_EXPR, $$, $3); }
  1076.     | expr_no_commas '?' xexpr ':' expr_no_commas
  1077.         { $$ = build_x_conditional_expr ($$, $3, $5); }
  1078.     | expr_no_commas '=' expr_no_commas
  1079.         { $$ = build_modify_expr ($$, NOP_EXPR, $3); }
  1080.     | expr_no_commas ASSIGN expr_no_commas
  1081.         { register tree rval;
  1082.           if (rval = build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL, $$, $3, $2))
  1083.             $$ = rval;
  1084.           else
  1085.             $$ = build_modify_expr ($$, $2, $3); }
  1086.  
  1087.     /* Handle general members.  */
  1088.     | object '*' expr_no_commas   %prec UNARY
  1089.         { $$ = build_m_component_ref ($$, build_x_indirect_ref ($3, "unary *")); }
  1090.     | object '&' expr_no_commas   %prec UNARY
  1091.         { $$ = build_m_component_ref ($$, build_x_unary_op (ADDR_EXPR, $3)); }
  1092.     | object unop expr_no_commas  %prec UNARY
  1093.         { $$ = build_m_component_ref ($$, build_x_unary_op ($2, $3)); }
  1094.     | object '(' typename ')' expr_no_commas  %prec UNARY
  1095.         { tree type = groktypename ($3);
  1096.           $$ = build_m_component_ref ($$, build_c_cast (type, $5)); }
  1097.     | object primary_no_id  %prec UNARY
  1098.         { $$ = build_m_component_ref ($$, $2); }
  1099.     ;
  1100.  
  1101. primary:
  1102.     IDENTIFIER
  1103.         { $$ = do_identifier ($$); }
  1104.     | operator_name
  1105.         {
  1106.           tree op = hack_operator ($$);
  1107.           if (TREE_CODE (op) != IDENTIFIER_NODE)
  1108.             $$ = op;
  1109.           else
  1110.             {
  1111.               $$ = lookup_name (op);
  1112.               if ($$ == NULL_TREE)
  1113.             {
  1114.               error ("operator %s not defined", operator_name_string (op));
  1115.               $$ = error_mark_node;
  1116.             }
  1117.             }
  1118.         }
  1119.     | CONSTANT
  1120.     | string
  1121.         { $$ = combine_strings ($$); }
  1122.     | '(' expr ')'
  1123.         { $$ = $2; }
  1124.     | '(' error ')'
  1125.         { $$ = error_mark_node; }
  1126.     | '('
  1127.         { if (current_function_decl == 0)
  1128.             {
  1129.               error ("braced-group within expression allowed only inside a function");
  1130.               YYERROR;
  1131.             }
  1132.           keep_next_level ();
  1133.           $<ttype>$ = expand_start_stmt_expr (); }
  1134.       compstmt ')'
  1135.         { tree rtl_exp;
  1136.           if (pedantic)
  1137.             warning ("ANSI C forbids braced-groups within expressions");
  1138.           rtl_exp = expand_end_stmt_expr ($<ttype>2);
  1139.           /* The statements have side effects, so the group does.  */
  1140.           TREE_SIDE_EFFECTS (rtl_exp) = 1;
  1141.  
  1142.           /* Make a BIND_EXPR for the BLOCK already made.  */
  1143.           $$ = build (BIND_EXPR, TREE_TYPE (rtl_exp),
  1144.                   NULL_TREE, rtl_exp, $3);
  1145.         }
  1146.     | primary '(' nonnull_exprlist ')'
  1147.         { $$ = build_x_function_call ($$, $3, current_class_decl); }
  1148.     | primary LEFT_RIGHT
  1149.         { $$ = build_x_function_call ($$, NULL_TREE, current_class_decl); }
  1150.     | primary '[' expr ']'
  1151.         {
  1152.         do_array:
  1153.           {
  1154.             tree type = TREE_TYPE ($$);
  1155.             if (type == error_mark_node || $3 == error_mark_node)
  1156.               $$ = error_mark_node;
  1157.             else if (type == NULL_TREE)
  1158.               {
  1159.             /* Something has gone very wrong.  Assume we
  1160.                are mistakenly reducing an expression
  1161.                instead of a declaration.  */
  1162.             error ("parser may be lost: is there a '{' missing somewhere?");
  1163.             $$ = NULL_TREE;
  1164.               }
  1165.             else
  1166.               {
  1167.             if (TREE_CODE (type) == OFFSET_TYPE)
  1168.               type = TREE_TYPE (type);
  1169.             if (TREE_CODE (type) == REFERENCE_TYPE)
  1170.               type = TREE_TYPE (type);
  1171.  
  1172.             if (TYPE_LANG_SPECIFIC (type) &&
  1173.                 TYPE_OVERLOADS_ARRAY_REF (type))
  1174.               $$ = build_opfncall (ARRAY_REF, LOOKUP_NORMAL, $1, $3);
  1175.             else if (TREE_CODE (type) == POINTER_TYPE
  1176.                  || TREE_CODE (type) == ARRAY_TYPE)
  1177.               $$ = build_array_ref ($1, $3);
  1178.             else
  1179.               error("[] applied to non-pointer type");
  1180.               }
  1181.           }
  1182.         }
  1183.     | object identifier_or_opname  %prec UNARY
  1184.         { $$ = build_component_ref ($$, $2, NULL_TREE, 1); }
  1185.     | object scoped_id identifier_or_opname %prec UNARY
  1186.         {
  1187.           tree basetype = $2;
  1188.           if (is_aggr_typedef (basetype, 1))
  1189.             {
  1190.               basetype = IDENTIFIER_TYPE_VALUE (basetype);
  1191.  
  1192.               if ($$ == error_mark_node)
  1193.             ;
  1194.               else if (basetype_or_else (basetype, TREE_TYPE ($$)))
  1195.             $$ = build_component_ref (build_scoped_ref ($$, $2), $3, NULL_TREE, 1);
  1196.               else
  1197.             $$ = error_mark_node;
  1198.             }
  1199.           else $$ = error_mark_node;
  1200.         }
  1201.     | primary PLUSPLUS
  1202.         { $$ = build_x_unary_op (POSTINCREMENT_EXPR, $$); }
  1203.     | primary MINUSMINUS
  1204.         { $$ = build_x_unary_op (POSTDECREMENT_EXPR, $$); }
  1205.  
  1206.     /* C++ extensions */
  1207.     | THIS
  1208.         { if (current_class_decl)
  1209.             {
  1210. #ifdef WARNING_ABOUT_CCD
  1211.               TREE_USED (current_class_decl) = 1;
  1212. #endif
  1213.               $$ = current_class_decl;
  1214.             }
  1215.           else if (current_function_decl
  1216.                && DECL_STATIC_FUNCTION_P (current_function_decl))
  1217.             {
  1218.               error ("`this' is unavailable for static member functions");
  1219.               $$ = error_mark_node;
  1220.             }
  1221.           else
  1222.             {
  1223.               if (current_function_decl)
  1224.             error ("invalid use of `this' in non-member function");
  1225.               else
  1226.             error ("invalid use of `this' at top level");
  1227.               $$ = error_mark_node;
  1228.             }
  1229.         }
  1230.     | TYPE_QUAL '(' nonnull_exprlist ')'
  1231.         {
  1232.           tree type;
  1233.           tree id = $$;
  1234.  
  1235.           /* This is a C cast in C++'s `functional' notation.  */
  1236.           if ($3 == error_mark_node)
  1237.             {
  1238.               $$ = error_mark_node;
  1239.               break;
  1240.             }
  1241. #if 0
  1242.           if ($3 == NULL_TREE)
  1243.             {
  1244.               error ("cannot cast null list to type `%s'",
  1245.                      IDENTIFIER_POINTER (TYPE_NAME (id)));
  1246.               $$ = error_mark_node;
  1247.               break;
  1248.             }
  1249. #endif
  1250.           if (type == error_mark_node)
  1251.             $$ = error_mark_node;
  1252.           else
  1253.             {
  1254.               if (id == ridpointers[(int) RID_CONST])
  1255.                 type = build_type_variant (integer_type_node, 1, 0);
  1256.               else if (id == ridpointers[(int) RID_VOLATILE])
  1257.                 type = build_type_variant (integer_type_node, 0, 1);
  1258.               else if (id == ridpointers[(int) RID_FRIEND])
  1259.                 {
  1260.                   error ("cannot cast expression to `friend' type");
  1261.                   $$ = error_mark_node;
  1262.                   break;
  1263.                 }
  1264.               else abort ();
  1265.               $$ = build_c_cast (type, build_compound_expr ($3));
  1266.             }
  1267.         }
  1268.     | typespec '(' nonnull_exprlist ')'
  1269.         { $$ = build_functional_cast ($$, $3); }
  1270.     | typespec LEFT_RIGHT
  1271.         { $$ = build_functional_cast ($$, NULL_TREE); }
  1272.     | SCOPE IDENTIFIER
  1273.         {
  1274.         do_scoped_id:
  1275.           $$ = IDENTIFIER_GLOBAL_VALUE ($2);
  1276.           if (yychar == YYEMPTY)
  1277.             yychar = YYLEX;
  1278.           if (! $$)
  1279.             {
  1280.               if (yychar == '(' || yychar == LEFT_RIGHT)
  1281.             $$ = implicitly_declare ($2);
  1282.               else
  1283.             {
  1284.               if (IDENTIFIER_GLOBAL_VALUE ($2) != error_mark_node)
  1285.                 error ("undeclared variable `%s' (first use here)",
  1286.                    IDENTIFIER_POINTER ($2));
  1287.               $$ = error_mark_node;
  1288.               /* Prevent repeated error messages.  */
  1289.               IDENTIFIER_GLOBAL_VALUE ($2) = error_mark_node;
  1290.             }
  1291.             }
  1292.           else if (TREE_CODE ($$) == CONST_DECL)
  1293.             $$ = DECL_INITIAL ($$);
  1294.           if (TREE_CODE_CLASS (TREE_CODE ($$)) == 'd'
  1295.               && ! TREE_USED ($$))
  1296.             {
  1297.               if (TREE_EXTERNAL ($$))
  1298.             assemble_external ($$);
  1299.               TREE_USED ($$) = 1;
  1300.             }
  1301.         }
  1302.     | SCOPE operator_name
  1303.         {
  1304.           $2 = hack_operator ($2);
  1305.           if (TREE_CODE ($2) == IDENTIFIER_NODE)
  1306.             goto do_scoped_id;
  1307.         do_scoped_operator:
  1308.           $$ = $2;
  1309.         }
  1310.     | scoped_id identifier_or_opname  %prec HYPERUNARY
  1311.         { $$ = build_offset_ref ($$, $2); }
  1312.     | scoped_id identifier_or_opname '(' nonnull_exprlist ')'
  1313.         { $$ = build_member_call ($$, $2, $4); }
  1314.     | scoped_id identifier_or_opname LEFT_RIGHT
  1315.         { $$ = build_member_call ($$, $2, NULL_TREE); }
  1316.     | object identifier_or_opname '(' nonnull_exprlist ')'
  1317.         { $$ = build_method_call ($$, $2, $4, NULL_TREE,
  1318.                       (LOOKUP_NORMAL|LOOKUP_AGGR)); }
  1319.     | object identifier_or_opname LEFT_RIGHT
  1320.         { $$ = build_method_call ($$, $2, NULL_TREE, NULL_TREE,
  1321.                       (LOOKUP_NORMAL|LOOKUP_AGGR)); }
  1322.     | object scoped_id identifier_or_opname '(' nonnull_exprlist ')'
  1323.         { $$ = build_scoped_method_call ($$, $2, $3, $5); }
  1324.     | object scoped_id identifier_or_opname LEFT_RIGHT
  1325.         { $$ = build_scoped_method_call ($$, $2, $3, NULL_TREE); }
  1326.     ;
  1327.  
  1328. primary_no_id:
  1329.       '(' expr ')'
  1330.         { $$ = $2; }
  1331.     | '(' error ')'
  1332.         { $$ = error_mark_node; }
  1333.     | '('
  1334.         { if (current_function_decl == 0)
  1335.             {
  1336.               error ("braced-group within expression allowed only inside a function");
  1337.               YYERROR;
  1338.             }
  1339.           $<ttype>$ = expand_start_stmt_expr (); }
  1340.       compstmt ')'
  1341.         { if (pedantic)
  1342.             warning ("ANSI C forbids braced-groups within expressions");
  1343.           $$ = expand_end_stmt_expr ($<ttype>2); }
  1344.     | primary_no_id '(' nonnull_exprlist ')'
  1345.         { $$ = build_x_function_call ($$, $3, current_class_decl); }
  1346.     | primary_no_id LEFT_RIGHT
  1347.         { $$ = build_x_function_call ($$, NULL_TREE, current_class_decl); }
  1348.     | primary_no_id '[' expr ']'
  1349.         { goto do_array; }
  1350.     | primary_no_id PLUSPLUS
  1351.         { $$ = build_x_unary_op (POSTINCREMENT_EXPR, $$); }
  1352.     | primary_no_id MINUSMINUS
  1353.         { $$ = build_x_unary_op (POSTDECREMENT_EXPR, $$); }
  1354.     | SCOPE IDENTIFIER
  1355.         { goto do_scoped_id; }
  1356.     | SCOPE operator_name
  1357.         { $2 = hack_operator ($2);
  1358.           if (TREE_CODE ($2) == IDENTIFIER_NODE)
  1359.             goto do_scoped_id;
  1360.           goto do_scoped_operator;
  1361.         }
  1362.     ;
  1363.  
  1364. new:      NEW
  1365.         { $$ = NULL_TREE; }
  1366.     | NEW '{' nonnull_exprlist '}'
  1367.         { $$ = $3; }
  1368.     | NEW DYNAMIC  %prec EMPTY
  1369.         { $$ = void_type_node; }
  1370.     | NEW DYNAMIC '(' string ')'
  1371.         { $$ = combine_strings ($4); }
  1372.     ;
  1373.  
  1374. .scope:
  1375.     /* empty  */
  1376.         { $$ = 0; }
  1377.     | SCOPE
  1378.         { $$ = 1; }
  1379.     ;
  1380.  
  1381. delete:      DELETE
  1382.         { $$ = NULL_TREE; }
  1383.     | SCOPE delete
  1384.         { if ($2)
  1385.             error ("extra `::' before `delete' ignored");
  1386.           $$ = error_mark_node;
  1387.         }
  1388.     ;
  1389.  
  1390. /* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it.  */
  1391. string:
  1392.       STRING
  1393.     | string STRING
  1394.         { $$ = chainon ($$, $2); }
  1395.     ;
  1396.  
  1397. nodecls:
  1398.       /* empty */
  1399.         {
  1400.           if (! current_function_parms_stored)
  1401.             store_parm_decls ();
  1402.           setup_vtbl_ptr ();
  1403.         }
  1404.     ;
  1405.  
  1406. object:      primary '.'
  1407.         {
  1408.           if ($$ == error_mark_node)
  1409.             ;
  1410.           else
  1411.             {
  1412.               tree type = TREE_TYPE ($$);
  1413.  
  1414.               if (! PROMOTES_TO_AGGR_TYPE (type, REFERENCE_TYPE))
  1415.             {
  1416.               error ("object in '.' expression is not of aggregate type");
  1417.               $$ = error_mark_node;
  1418.             }
  1419.             }
  1420.         }
  1421.     | primary POINTSAT
  1422.         {
  1423.           $$ = build_x_arrow ($$);
  1424.         }
  1425.     ;
  1426.  
  1427. decl:
  1428.       typed_declspecs initdecls ';'
  1429.         {
  1430.           resume_momentary ($2);
  1431.           note_list_got_semicolon ($<ttype>$);
  1432.         }
  1433.     /* Normal case: make this fast.  */
  1434.     | typed_declspecs declarator ';'
  1435.         { tree d;
  1436.           int yes = suspend_momentary ();
  1437.           d = start_decl ($2, $<ttype>$, 0, NULL_TREE);
  1438.           finish_decl (d, NULL_TREE, NULL_TREE);
  1439.           resume_momentary (yes);
  1440.           note_list_got_semicolon ($<ttype>$);
  1441.         }
  1442.     | declmods notype_initdecls ';'
  1443.         { resume_momentary ($2); }
  1444.     /* Normal case: make this fast.  */
  1445.     | declmods declarator ';'
  1446.         { tree d;
  1447.           int yes = suspend_momentary ();
  1448.           d = start_decl ($2, $<ttype>$, 0, NULL_TREE);
  1449.           finish_decl (d, NULL_TREE, NULL_TREE);
  1450.           resume_momentary (yes);
  1451.         }
  1452.     | typed_declspecs ';'
  1453.         {
  1454.           shadow_tag ($<ttype>$);
  1455.           note_list_got_semicolon ($<ttype>$);
  1456.         }
  1457.     | declmods ';'
  1458.         { warning ("empty declaration"); }
  1459.     ;
  1460.  
  1461. /* Any kind of declarator (thus, all declarators allowed
  1462.    after an explicit typespec).  */
  1463.  
  1464. declarator:
  1465.       after_type_declarator
  1466.     | notype_declarator
  1467.     ;
  1468.  
  1469. /* Declspecs which contain at least one type specifier or typedef name.
  1470.    (Just `const' or `volatile' is not enough.)
  1471.    A typedef'd name following these is taken as a name to be declared.  */
  1472.  
  1473. typed_declspecs:
  1474.       typespec    %prec HYPERUNARY
  1475.         { $$ = list_hash_lookup_or_cons ($$); }
  1476.     | declmods typespec
  1477.         { $$ = hash_tree_chain ($2, $$); }
  1478.     | typespec reserved_declspecs    %prec HYPERUNARY
  1479.         { $$ = hash_tree_chain ($$, $2); }
  1480.     | declmods typespec reserved_declspecs
  1481.         { $$ = hash_tree_chain ($2, hash_chainon ($3, $$)); }
  1482.     ;
  1483.  
  1484. reserved_declspecs:  /* empty
  1485.         { $$ = NULL_TREE; } */
  1486.       typespecqual_reserved
  1487.         { $$ = build_decl_list (NULL_TREE, $$); }
  1488.     | SCSPEC
  1489.         { $$ = build_decl_list (NULL_TREE, $$); }
  1490.     | reserved_declspecs typespecqual_reserved
  1491.         { $$ = decl_tree_cons (NULL_TREE, $2, $$); }
  1492.     | reserved_declspecs SCSPEC
  1493.         { $$ = decl_tree_cons (NULL_TREE, $2, $$); }
  1494.     ;
  1495.  
  1496. /* List of just storage classes and type modifiers.
  1497.    A declaration can start with just this, but then it cannot be used
  1498.    to redeclare a typedef-name.  */
  1499.  
  1500. declmods:
  1501.       TYPE_QUAL
  1502.         { $$ = IDENTIFIER_AS_LIST ($$); }
  1503.     | SCSPEC
  1504.         { $$ = IDENTIFIER_AS_LIST ($$); }
  1505.     | declmods TYPE_QUAL
  1506.         { $$ = hash_tree_chain ($2, $$); }
  1507.     | declmods SCSPEC
  1508.         { $$ = hash_tree_chain ($2, $$); }
  1509.     ;
  1510.  
  1511.  
  1512. /* Used instead of declspecs where storage classes are not allowed
  1513.    (that is, for typenames and structure components).
  1514.  
  1515.    C++ can takes storage classes for structure components.
  1516.    Don't accept a typedef-name if anything but a modifier precedes it.  */
  1517.  
  1518. typed_typespecs:
  1519.       typespec  %prec EMPTY
  1520.         { $$ = get_decl_list ($$); }
  1521.     | nonempty_type_quals typespec
  1522.         { $$ = decl_tree_cons (NULL_TREE, $2, $$); }
  1523.     | typespec reserved_typespecquals
  1524.         { $$ = decl_tree_cons (NULL_TREE, $$, $2); }
  1525.     | nonempty_type_quals typespec reserved_typespecquals
  1526.         { $$ = decl_tree_cons (NULL_TREE, $2, hash_chainon ($3, $$)); }
  1527.     ;
  1528.  
  1529. reserved_typespecquals:
  1530.       typespecqual_reserved
  1531.         { $$ = get_decl_list ($$); }
  1532.     | reserved_typespecquals typespecqual_reserved
  1533.         { $$ = decl_tree_cons (NULL_TREE, $2, $$); }
  1534.     ;
  1535.  
  1536. /* A typespec (but not a type qualifier).
  1537.    Once we have seen one of these in a declaration,
  1538.    if a typedef name appears then it is being redeclared.  */
  1539.  
  1540. typespec: structsp
  1541.     | TYPESPEC  %prec EMPTY
  1542.     | TYPENAME  %prec EMPTY
  1543.     | scoped_typename
  1544.     | template_type SCOPE try_for_typename TYPENAME
  1545.         { $$ = resolve_scope_to_name ($1, $4);
  1546.           popclass (1); }
  1547.     | TYPEOF '(' expr ')'
  1548.         { $$ = TREE_TYPE ($3);
  1549.           if (pedantic)
  1550.             warning ("ANSI C forbids `typeof'"); }
  1551.     | TYPEOF '(' typename ')'
  1552.         { $$ = groktypename ($3);
  1553.           if (pedantic)
  1554.             warning ("ANSI C forbids `typeof'"); }
  1555.     ;
  1556.  
  1557. /* A typespec that is a reserved word, or a type qualifier.  */
  1558.  
  1559. typespecqual_reserved: TYPESPEC
  1560.     | TYPE_QUAL
  1561.     | structsp
  1562.     ;
  1563.  
  1564. initdecls:
  1565.       initdcl0
  1566.     | initdecls ',' initdcl
  1567.     ;
  1568.  
  1569. notype_initdecls:
  1570.       notype_initdcl0
  1571.     | notype_initdecls ',' initdcl
  1572.     ;
  1573.  
  1574. maybeasm:
  1575.       /* empty */
  1576.         { $$ = NULL_TREE; }
  1577.     | ASM '(' string ')'
  1578.         { if (TREE_CHAIN ($3)) $3 = combine_strings ($3);
  1579.           $$ = $3;
  1580.           if (pedantic)
  1581.             warning ("ANSI C forbids use of `asm' keyword");
  1582.         }
  1583.     ;
  1584.  
  1585. initdcl0:
  1586.       declarator maybe_raises maybeasm maybe_attribute '='
  1587.         { current_declspecs = $<ttype>0;
  1588.           $<itype>5 = suspend_momentary ();
  1589.           $<ttype>$ = start_decl ($1, current_declspecs, 1, $2); }
  1590.       init
  1591. /* Note how the declaration of the variable is in effect while its init is parsed! */
  1592.         { finish_decl ($<ttype>6, $7, $3);
  1593.           $$ = $<itype>5; }
  1594.     | declarator maybe_raises maybeasm maybe_attribute
  1595.         { tree d;
  1596.           current_declspecs = $<ttype>0;
  1597.           $$ = suspend_momentary ();
  1598.           d = start_decl ($1, current_declspecs, 0, $2);
  1599.           finish_decl (d, NULL_TREE, $3); }
  1600.     ;
  1601.  
  1602. initdcl:
  1603.       declarator maybe_raises maybeasm maybe_attribute '='
  1604.         { $<ttype>$ = start_decl ($1, current_declspecs, 1, $2); }
  1605.       init
  1606. /* Note how the declaration of the variable is in effect while its init is parsed! */
  1607.         { finish_decl ($<ttype>6, $7, $3); }
  1608.     | declarator maybe_raises maybeasm maybe_attribute
  1609.         { tree d = start_decl ($$, current_declspecs, 0, $2);
  1610.           finish_decl (d, NULL_TREE, $3); }
  1611.     ;
  1612.  
  1613. notype_initdcl0:
  1614.       notype_declarator maybe_raises maybeasm maybe_attribute '='
  1615.         { current_declspecs = $<ttype>0;
  1616.           $<itype>5 = suspend_momentary ();
  1617.           $<ttype>$ = start_decl ($1, current_declspecs, 1, $2); }
  1618.       init
  1619. /* Note how the declaration of the variable is in effect while its init is parsed! */
  1620.         { finish_decl ($<ttype>6, $7, $3);
  1621.           $$ = $<itype>5; }
  1622.     | notype_declarator maybe_raises maybeasm maybe_attribute
  1623.         { tree d;
  1624.           current_declspecs = $<ttype>0;
  1625.           $$ = suspend_momentary ();
  1626.           d = start_decl ($1, current_declspecs, 0, $2);
  1627.           finish_decl (d, NULL_TREE, $3); }
  1628.     ;
  1629.  
  1630. /* the * rules are dummies to accept the Apollo extended syntax
  1631.    so that the header files compile. */
  1632. maybe_attribute:
  1633.     /* empty */
  1634.     { $$ = NULL_TREE; }
  1635.     | ATTRIBUTE '(' '(' attribute_list ')' ')'
  1636.         { $$ = $4; }
  1637.     ;
  1638.  
  1639. attribute_list
  1640.     : attrib
  1641.     | attribute_list ',' attrib
  1642.     ;
  1643.  
  1644. attrib
  1645.     : IDENTIFIER
  1646.     { warning ("`%s' attribute directive ignored",
  1647.            IDENTIFIER_POINTER ($$)); }
  1648.     | IDENTIFIER '(' CONSTANT ')'
  1649.     { /* if not "aligned(1)", then issue warning */
  1650.       if (strcmp (IDENTIFIER_POINTER ($$), "aligned") != 0
  1651.           || TREE_CODE ($3) != INTEGER_CST
  1652.           || TREE_INT_CST_LOW ($3) != 1)
  1653.         warning ("`%s' attribute directive ignored",
  1654.              IDENTIFIER_POINTER ($$)); }
  1655.     | IDENTIFIER '(' identifiers ')'
  1656.     { warning ("`%s' attribute directive ignored",
  1657.            IDENTIFIER_POINTER ($$)); }
  1658.     ;
  1659.  
  1660. identifiers:
  1661.       IDENTIFIER
  1662.         { }
  1663.     | identifiers ',' IDENTIFIER
  1664.         { }
  1665.     ;
  1666.  
  1667. init:
  1668.       expr_no_commas %prec '='
  1669.     | '{' '}'
  1670.         { $$ = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE);
  1671.           TREE_HAS_CONSTRUCTOR ($$) = 1;
  1672.           if (pedantic)
  1673.             warning ("ANSI C forbids empty initializer braces"); }
  1674.     | '{' initlist '}'
  1675.         { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2));
  1676.           TREE_HAS_CONSTRUCTOR ($$) = 1; }
  1677.     | '{' initlist ',' '}'
  1678.         { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2));
  1679.           TREE_HAS_CONSTRUCTOR ($$) = 1; }
  1680.     | error
  1681.         { $$ = NULL_TREE; }
  1682.     ;
  1683.  
  1684. /* This chain is built in reverse order,
  1685.    and put in forward order where initlist is used.  */
  1686. initlist:
  1687.       init
  1688.         { $$ = build_tree_list (NULL_TREE, $$); }
  1689.     | initlist ',' init
  1690.         { $$ = tree_cons (NULL_TREE, $3, $$); }
  1691.     /* These are for labeled elements.  */
  1692.     | '[' expr_no_commas ']' init
  1693.         { $$ = build_tree_list ($2, $4); }
  1694.     | initlist ',' CASE expr_no_commas ':' init
  1695.         { $$ = tree_cons ($4, $6, $$); }
  1696.     | identifier ':' init
  1697.         { $$ = build_tree_list ($$, $3); }
  1698.     | initlist ',' identifier ':' init
  1699.         { $$ = tree_cons ($3, $5, $$); }
  1700.     ;
  1701.  
  1702. structsp:
  1703.       ENUM identifier '{'
  1704.         { $<itype>3 = suspend_momentary ();
  1705.           $$ = start_enum ($2); }
  1706.       enumlist maybecomma_warn '}'
  1707.         { $$ = finish_enum ($<ttype>4, $5);
  1708.           resume_momentary ($<itype>3);
  1709.           check_for_missing_semicolon ($<ttype>4); }
  1710.     | ENUM identifier '{' '}'
  1711.         { $$ = finish_enum (start_enum ($2), NULL_TREE);
  1712.           check_for_missing_semicolon ($$); }
  1713.     | ENUM '{'
  1714.         { $<itype>2 = suspend_momentary ();
  1715.           $$ = start_enum (make_anon_name ()); }
  1716.       enumlist maybecomma_warn '}'
  1717.         { $$ = finish_enum ($<ttype>3, $4);
  1718.           resume_momentary ($<itype>1);
  1719.           check_for_missing_semicolon ($<ttype>3); }
  1720.     | ENUM '{' '}'
  1721.         { $$ = finish_enum (start_enum (make_anon_name()), NULL_TREE);
  1722.           check_for_missing_semicolon ($$); }
  1723.     | ENUM identifier
  1724.         { $$ = xref_tag (enum_type_node, $2, NULL_TREE); }
  1725.  
  1726.     /* C++ extensions, merged with C to avoid shift/reduce conflicts */
  1727.     | class_head LC opt.component_decl_list '}'
  1728.         {
  1729.           if (TREE_CODE ($$) == ENUMERAL_TYPE)
  1730.             /* $$ = $1; */ ;
  1731.           else if (CLASSTYPE_DECLARED_EXCEPTION ($$))
  1732.             $$ = finish_exception ($$, $3);
  1733.           else
  1734.             $$ = finish_struct ($$, $3, 0, 0);
  1735.  
  1736.           if ($2 & 1)
  1737.             resume_temporary_allocation ();
  1738.           if ($2 & 2)
  1739.             resume_momentary (1);
  1740.           check_for_missing_semicolon ($$);
  1741.           if (TYPE_NAME ($1) && DECL_NAME (TYPE_NAME ($1)))
  1742.             undo_template_name_overload (DECL_NAME (TYPE_NAME ($1)));
  1743.         }
  1744.     | class_head LC opt.component_decl_list '}' ';'
  1745.         {
  1746. #if 0
  1747.           /* Need to rework class nesting in the
  1748.              presence of nested classes, etc.  */
  1749.           shadow_tag (CLASSTYPE_AS_LIST ($$)); */
  1750. #endif
  1751.           note_got_semicolon ($$);
  1752.           if (TREE_CODE ($$) == ENUMERAL_TYPE)
  1753.             /* $$ = $1 from default rule.  */;
  1754.           else if (CLASSTYPE_DECLARED_EXCEPTION ($$))
  1755.             warning ("empty exception declaration\n");
  1756.           else
  1757.             $$ = finish_struct ($$, $3, 1, 1);
  1758.           if ($2 & 1)
  1759.             resume_temporary_allocation ();
  1760.           if ($2 & 2)
  1761.             resume_momentary (1);
  1762.           if (TYPE_NAME ($1) && DECL_NAME (TYPE_NAME ($1)))
  1763.             undo_template_name_overload (DECL_NAME (TYPE_NAME ($1)));
  1764.           yyungetc (';', 0); }
  1765.     | class_head  %prec EMPTY
  1766.         {
  1767.           if (TYPE_BASETYPES ($$) && !TYPE_SIZE ($$))
  1768.             {
  1769.               error ("incomplete definition of type `%s'",
  1770.                  TYPE_NAME_STRING ($$));
  1771.               $$ = error_mark_node;
  1772.             }
  1773.         }
  1774.     | template_type
  1775.     ;
  1776.  
  1777. maybecomma:
  1778.       /* empty */
  1779.     | ','
  1780.     ;
  1781.  
  1782. maybecomma_warn:
  1783.       /* empty */
  1784.     | ','
  1785.         { if (pedantic) warning ("comma at end of enumerator list"); }
  1786.     ;
  1787.  
  1788. aggr:      AGGR
  1789.     | DYNAMIC AGGR
  1790.         { $$ = build_tree_list (NULL_TREE, $2); }
  1791.     | DYNAMIC '(' string ')' AGGR
  1792.         { $$ = build_tree_list ($3, $5); }
  1793.     | aggr SCSPEC
  1794.         { error ("storage class specifier `%s' not allow after struct or class", IDENTIFIER_POINTER ($2));
  1795.         }
  1796.     | aggr TYPESPEC
  1797.         { error ("type specifier `%s' not allow after struct or class", IDENTIFIER_POINTER ($2));
  1798.         }
  1799.     | aggr TYPE_QUAL
  1800.         { error ("type qualifier `%s' not allow after struct or class", IDENTIFIER_POINTER ($2));
  1801.         }
  1802.     | aggr AGGR
  1803.         { error ("no body nor ';' separates two class, struct or union declarations");
  1804.         }
  1805.     ;
  1806.  
  1807. named_class_head_sans_basetype:
  1808.       aggr identifier
  1809.         { aggr1: current_aggr = $$; $$ = $2; }
  1810.     | aggr template_type_name  %prec EMPTY
  1811.         { current_aggr = $$; $$ = $2; }
  1812.     | aggr TYPENAME_COLON
  1813.         { yyungetc (':', 1); goto aggr1; }
  1814.     | aggr template_type_name '{'
  1815.         { yyungetc ('{', 1);
  1816.         aggr2:
  1817.           current_aggr = $$;
  1818.           $$ = $2; }
  1819.     | aggr template_type_name ':'
  1820.         { yyungetc (':', 1); goto aggr2; }
  1821.     ;
  1822.  
  1823. named_class_head:
  1824.       named_class_head_sans_basetype
  1825.         {
  1826.           $<ttype>$ = xref_tag (current_aggr, $1, NULL_TREE);
  1827.           if (IDENTIFIER_TEMPLATE ($1)) overload_template_name ($1);
  1828.         }
  1829.       maybe_base_class_list %prec EMPTY
  1830.         {
  1831.           if ($3)
  1832.             $$ = xref_tag (current_aggr, $1, $3);
  1833.           else
  1834.             $$ = $<ttype>2;
  1835.         }
  1836.     ;
  1837.  
  1838. unnamed_class_head: aggr '{'
  1839.         { $$ = xref_tag ($$, make_anon_name (), NULL_TREE);
  1840.           yyungetc ('{', 1); }
  1841.     ;
  1842.  
  1843. class_head: unnamed_class_head | named_class_head ;
  1844.  
  1845. maybe_base_class_list:
  1846.       /* empty */
  1847.         { $$ = NULL_TREE; }
  1848.     | ':'  %prec EMPTY
  1849.         { yyungetc(':', 1); $$ = NULL_TREE; }
  1850.     | ':' base_class_list  %prec EMPTY
  1851.         { $$ = $2; }
  1852.     ;
  1853.  
  1854. base_class_list:
  1855.       base_class
  1856.     | base_class_list ',' base_class
  1857.         { $$ = chainon ($$, $3); }
  1858.     ;
  1859.  
  1860. base_class:
  1861.       base_class.1
  1862.         { if (! is_aggr_typedef ($$, 1))
  1863.             $$ = NULL_TREE;
  1864.           else $$ = build_tree_list ((tree)visibility_default, $$); }
  1865.     | base_class_visibility_list base_class.1
  1866.         { if (! is_aggr_typedef ($2, 1))
  1867.             $$ = NULL_TREE;
  1868.           else $$ = build_tree_list ((tree) $$, $2); }
  1869.     ;
  1870.  
  1871. base_class.1:
  1872.       template_type_name tmpl.2 template_instantiation
  1873.     | identifier
  1874.     ;
  1875.  
  1876. base_class_visibility_list:
  1877.       VISSPEC
  1878.         {
  1879.           if ($$ == visibility_protected)
  1880.             {
  1881.               warning ("`protected' visibility not implemented");
  1882.               $$ = visibility_public;
  1883.             }
  1884.         }
  1885.     | SCSPEC
  1886.         { if ($<ttype>$ != ridpointers[(int)RID_VIRTUAL])
  1887.             sorry ("non-virtual visibility");
  1888.           $$ = visibility_default_virtual; }
  1889.     | base_class_visibility_list VISSPEC
  1890.         { int err = 0;
  1891.           if ($2 == visibility_protected)
  1892.             {
  1893.               warning ("`protected' visibility not implemented");
  1894.               $2 = visibility_public;
  1895.               err++;
  1896.             }
  1897.           else if ($2 == visibility_public)
  1898.             {
  1899.               if ($1 == visibility_private)
  1900.             {
  1901.             mixed:
  1902.               error ("base class cannot be public and private");
  1903.             }
  1904.               else if ($1 == visibility_default_virtual)
  1905.             $$ = visibility_public_virtual;
  1906.             }
  1907.           else /* $2 == visibility_priavte */
  1908.             {
  1909.               if ($1 == visibility_public)
  1910.             goto mixed;
  1911.               else if ($1 == visibility_default_virtual)
  1912.             $$ = visibility_private_virtual;
  1913.             }
  1914.         }
  1915.     | base_class_visibility_list SCSPEC
  1916.         { if ($2 != ridpointers[(int)RID_VIRTUAL])
  1917.             sorry ("non-virtual visibility");
  1918.           if ($$ == visibility_public)
  1919.             $$ = visibility_public_virtual;
  1920.           else if ($$ == visibility_private)
  1921.             $$ = visibility_private_virtual; }
  1922.     ;
  1923.  
  1924. LC: '{'
  1925.         { int temp = allocation_temporary_p ();
  1926.           int momentary = suspend_momentary ();
  1927.           if (temp)
  1928.             end_temporary_allocation ();
  1929.           else
  1930.             permanent_allocation ();
  1931.  
  1932.           $$ = (momentary << 1) | temp;
  1933.           if (! IS_AGGR_TYPE ($<ttype>0))
  1934.             {
  1935.               $<ttype>0 = make_lang_type (RECORD_TYPE);
  1936.               TYPE_NAME ($<ttype>0) = get_identifier ("erroneous type");
  1937.             }
  1938.           pushclass ($<ttype>0, 0);
  1939.           TYPE_BEING_DEFINED ($<ttype>0) = 1;
  1940.         }
  1941.     ;
  1942.  
  1943. opt.component_decl_list:
  1944.     /* empty */
  1945.         { $$ = NULL_TREE; }
  1946.     | component_decl_list
  1947.         { $$ = build_tree_list ((tree)visibility_default, $$); }
  1948.     | opt.component_decl_list VISSPEC ':' component_decl_list
  1949.         { $$ = chainon ($$, build_tree_list ((tree) $2, $4)); }
  1950.     | opt.component_decl_list VISSPEC ':'
  1951.     ;
  1952.  
  1953. component_decl_list:
  1954.       component_decl
  1955.         { if ($$ == void_type_node) $$ = NULL_TREE; }
  1956.     | component_decl_list component_decl
  1957.         { if ($2 != NULL_TREE && $2 != void_type_node)
  1958.             $$ = chainon ($$, $2); }
  1959.     | component_decl_list ';'
  1960.         { if (pedantic)
  1961.             warning ("extra semicolon in struct or union specified"); }
  1962.     ;
  1963.  
  1964. component_decl:
  1965.       typed_declspecs components ';'
  1966.         {
  1967.         do_components:
  1968.           if ($2 == void_type_node)
  1969.             /* We just got some friends.
  1970.                They have been recorded elsewhere.  */
  1971.             $$ = NULL_TREE;
  1972.           else if ($2 == NULL_TREE)
  1973.             {
  1974.               tree t = groktypename (build_decl_list ($$, NULL_TREE));
  1975.               if (t == NULL_TREE)
  1976.             {
  1977.               error ("error in component specification");
  1978.               $$ = NULL_TREE;
  1979.             }
  1980.               else if (TREE_CODE (t) == UNION_TYPE)
  1981.             {
  1982.               /* handle anonymous unions */
  1983.               if (CLASSTYPE_METHOD_VEC (t))
  1984.                 sorry ("methods in anonymous unions");
  1985.               $$ = build_lang_field_decl (FIELD_DECL, NULL_TREE, t);
  1986.               DECL_ANON_UNION_ELEM ($$) = 1;
  1987.             }
  1988.               else if (TREE_CODE (t) == ENUMERAL_TYPE)
  1989.             $$ = grok_enum_decls (t, NULL_TREE);
  1990.               else if (TREE_CODE (t) == RECORD_TYPE)
  1991.             {
  1992.               if (TYPE_LANG_SPECIFIC (t)
  1993.                   && CLASSTYPE_DECLARED_EXCEPTION (t))
  1994.                 shadow_tag ($$);
  1995.               $$ = NULL_TREE;
  1996.             }
  1997.               else if (t != void_type_node)
  1998.             {
  1999.               error ("empty component declaration");
  2000.               $$ = NULL_TREE;
  2001.             }
  2002.               else $$ = NULL_TREE;
  2003.             }
  2004.           else
  2005.             {
  2006.               tree t = TREE_TYPE ($2);
  2007.               if (TREE_CODE (t) == ENUMERAL_TYPE && TREE_NONLOCAL_FLAG (t))
  2008.             $$ = grok_enum_decls (t, $2);
  2009.               else
  2010.             $$ = $2;
  2011.             }
  2012.           end_exception_decls ();
  2013.         }
  2014.     | typed_declspecs '(' parmlist ')' ';'
  2015.         { $$ = groktypefield ($$, $3); }
  2016.     | typed_declspecs '(' parmlist ')' '}'
  2017.         { error ("missing ';' before right brace");
  2018.           yyungetc ('}', 0);
  2019.           $$ = groktypefield ($$, $3); }
  2020.     | typed_declspecs LEFT_RIGHT ';'
  2021.         { $$ = groktypefield ($$, empty_parms ()); }
  2022.     | typed_declspecs LEFT_RIGHT '}'
  2023.         { error ("missing ';' before right brace");
  2024.           yyungetc ('}', 0);
  2025.           $$ = groktypefield ($$, empty_parms ()); }
  2026.     | declmods components ';'
  2027.         { goto do_components; }
  2028.     /* Normal case: make this fast.  */
  2029.     | declmods declarator ';'
  2030.         { $$ = grokfield ($2, $$, 0, 0, 0, 0); }
  2031.     | declmods components '}'
  2032.         { error ("missing ';' before right brace");
  2033.           yyungetc ('}', 0);
  2034.           goto do_components; }
  2035.     | declmods '(' parmlist ')' ';'
  2036.         { $$ = groktypefield ($$, $3); }
  2037.     | declmods '(' parmlist ')' '}'
  2038.         { error ("missing ';' before right brace");
  2039.           yyungetc ('}', 0);
  2040.           $$ = groktypefield ($$, $3); }
  2041.     | declmods LEFT_RIGHT ';'
  2042.         { $$ = groktypefield ($$, empty_parms ()); }
  2043.     | declmods LEFT_RIGHT '}'
  2044.         { error ("missing ';' before right brace");
  2045.           yyungetc ('}', 0);
  2046.           $$ = groktypefield ($$, empty_parms ()); }
  2047.     | ':' expr_no_commas ';'
  2048.         { $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); }
  2049.     | ':' expr_no_commas '}'
  2050.         { error ("missing ';' before right brace");
  2051.           yyungetc ('}', 0);
  2052.           $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); }
  2053.     | error
  2054.         { $$ = NULL_TREE; }
  2055.  
  2056.     /* C++: handle constructors, destructors and inline functions */
  2057.     /* note that INLINE is like a TYPESPEC */
  2058.     | fn.def2 ':' /* base_init compstmt */
  2059.         { $$ = finish_method ($$); }
  2060.     | fn.def2 '{' /* nodecls compstmt */
  2061.         { $$ = finish_method ($$); }
  2062.     | notype_declarator maybe_raises ';'
  2063.         { $$ = grokfield ($$, NULL_TREE, $2, NULL_TREE, NULL_TREE); }
  2064.     | notype_declarator maybe_raises '}'
  2065.         { error ("missing ';' before right brace");
  2066.           yyungetc ('}', 0);
  2067.           $$ = grokfield ($$, NULL_TREE, $2, NULL_TREE, NULL_TREE); }
  2068.     ;
  2069.  
  2070. components:
  2071.       /* empty: possibly anonymous */
  2072.         { $$ = NULL_TREE; }
  2073.     | component_declarator0
  2074.     | components ',' component_declarator
  2075.         {
  2076.           /* In this context, void_type_node encodes
  2077.              friends.  They have been recorded elsewhere.  */
  2078.           if ($$ == void_type_node)
  2079.             $$ = $3;
  2080.           else
  2081.             $$ = chainon ($$, $3);
  2082.         }
  2083.     ;
  2084.  
  2085. component_declarator0:
  2086.       declarator maybe_raises maybeasm
  2087.         { current_declspecs = $<ttype>0;
  2088.           $$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3); }
  2089.     | declarator maybe_raises maybeasm '=' init
  2090.         { current_declspecs = $<ttype>0;
  2091.           $$ = grokfield ($$, current_declspecs, $2, $5, $3); }
  2092.     | IDENTIFIER ':' expr_no_commas
  2093.         { current_declspecs = $<ttype>0;
  2094.           $$ = grokbitfield ($$, current_declspecs, $3); }
  2095.     | TYPENAME_COLON expr_no_commas
  2096.         { current_declspecs = $<ttype>0;
  2097.           $$ = grokbitfield ($$, current_declspecs, $2); }
  2098.     | ':' expr_no_commas
  2099.         { current_declspecs = $<ttype>0;
  2100.           $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); }
  2101.     ;
  2102.  
  2103. component_declarator:
  2104.       declarator maybe_raises maybeasm
  2105.         { $$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3); }
  2106.     | declarator maybe_raises maybeasm '=' init
  2107.         { $$ = grokfield ($$, current_declspecs, $2, $5, $3); }
  2108.     | IDENTIFIER ':' expr_no_commas
  2109.         { $$ = grokbitfield ($$, current_declspecs, $3); }
  2110.     | TYPENAME_COLON expr_no_commas
  2111.         { $$ = grokbitfield ($$, current_declspecs, $2); }
  2112.     | ':' expr_no_commas
  2113.         { $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); }
  2114.     ;
  2115.  
  2116. /* We chain the enumerators in reverse order.
  2117.    Because of the way enums are built, the order is
  2118.    insignificant.  Take advantage of this fact.  */
  2119.  
  2120. enumlist:
  2121.       enumerator
  2122.     | enumlist ',' enumerator
  2123.         { TREE_CHAIN ($3) = $$; $$ = $3; }
  2124.     ;
  2125.  
  2126. enumerator:
  2127.       identifier
  2128.         { $$ = build_enumerator ($$, NULL_TREE); }
  2129.     | identifier '=' expr_no_commas
  2130.         { $$ = build_enumerator ($$, $3); }
  2131.     ;
  2132.  
  2133. typename:
  2134.       typed_typespecs absdcl
  2135.         { $$ = build_decl_list ($$, $2); }
  2136.     | nonempty_type_quals absdcl
  2137.         { $$ = build_decl_list ($$, $2); }
  2138.     ;
  2139.  
  2140. absdcl:   /* an abstract declarator */
  2141.     /* empty */ %prec EMPTY
  2142.         { $$ = NULL_TREE; }
  2143.     | absdcl1  %prec EMPTY
  2144.     ;
  2145.  
  2146. nonempty_type_quals:
  2147.       TYPE_QUAL
  2148.         { $$ = IDENTIFIER_AS_LIST ($$); }
  2149.     | nonempty_type_quals TYPE_QUAL
  2150.         { $$ = decl_tree_cons (NULL_TREE, $2, $$); }
  2151.     ;
  2152.  
  2153. type_quals:
  2154.       /* empty */
  2155.         { $$ = NULL_TREE; }
  2156.     | type_quals TYPE_QUAL
  2157.         { $$ = decl_tree_cons (NULL_TREE, $2, $$); }
  2158.     ;
  2159.  
  2160. /* These rules must follow the rules for function declarations
  2161.    and component declarations.  That way, longer rules are prefered.  */
  2162.  
  2163. /* An expression which will not live on the momentary obstack.  */
  2164. nonmomentary_expr:
  2165.     { $<itype>$ = suspend_momentary (); } expr
  2166.     { resume_momentary ($<itype>1); $$ = $2; }
  2167.  
  2168. /* A declarator that is allowed only after an explicit typespec.  */
  2169. /* may all be followed by prec '.' */
  2170. after_type_declarator:
  2171.       after_type_declarator '(' nonnull_exprlist ')' type_quals  %prec '.'
  2172.         { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
  2173.     | after_type_declarator '(' parmlist ')' type_quals  %prec '.'
  2174.         { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
  2175.     | after_type_declarator LEFT_RIGHT type_quals  %prec '.'
  2176.         { $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $3); }
  2177.     | after_type_declarator '(' error ')' type_quals  %prec '.'
  2178.         { $$ = build_parse_node (CALL_EXPR, $$, NULL_TREE, NULL_TREE); }
  2179.     | after_type_declarator '[' nonmomentary_expr ']'
  2180.         { $$ = build_parse_node (ARRAY_REF, $$, $3); }
  2181.     | after_type_declarator '[' ']'
  2182.         { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); }
  2183.     | '(' after_type_declarator_no_typename ')'
  2184.         { $$ = $2; }
  2185.     | '(' '*' type_quals after_type_declarator ')'
  2186.         { $$ = make_pointer_declarator ($3, $4); }
  2187.     | PAREN_STAR_PAREN
  2188.         { see_typename (); }
  2189.     | after_type_member_declarator
  2190.     | '(' '&' type_quals after_type_declarator ')'
  2191.         { $$ = make_reference_declarator ($3, $4); }
  2192.     | '*' type_quals after_type_declarator  %prec UNARY
  2193.         { $$ = make_pointer_declarator ($2, $3); }
  2194.     | '&' type_quals after_type_declarator  %prec UNARY
  2195.         { $$ = make_reference_declarator ($2, $3); }
  2196.     | TYPENAME
  2197.     ;
  2198.  
  2199. after_type_declarator_no_typename:
  2200.       after_type_declarator_no_typename '(' nonnull_exprlist ')' type_quals  %prec '.'
  2201.         { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
  2202.     | after_type_declarator_no_typename '(' parmlist ')' type_quals  %prec '.'
  2203.         { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
  2204.     | after_type_declarator_no_typename LEFT_RIGHT type_quals  %prec '.'
  2205.         { $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $3); }
  2206.     | after_type_declarator_no_typename '(' error ')' type_quals  %prec '.'
  2207.         { $$ = build_parse_node (CALL_EXPR, $$, NULL_TREE, NULL_TREE); }
  2208.     | after_type_declarator_no_typename '[' nonmomentary_expr ']'
  2209.         { $$ = build_parse_node (ARRAY_REF, $$, $3); }
  2210.     | after_type_declarator_no_typename '[' ']'
  2211.         { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); }
  2212.     | '(' after_type_declarator_no_typename ')'
  2213.         { $$ = $2; }
  2214.     | PAREN_STAR_PAREN
  2215.         { see_typename (); }
  2216.     | after_type_member_declarator
  2217.     | '*' type_quals after_type_declarator  %prec UNARY
  2218.         { $$ = make_pointer_declarator ($2, $3); }
  2219.     | '&' type_quals after_type_declarator  %prec UNARY
  2220.         { $$ = make_reference_declarator ($2, $3); }
  2221.     ;
  2222.  
  2223. /* A declarator allowed whether or not there has been
  2224.    an explicit typespec.  These cannot redeclare a typedef-name.  */
  2225.  
  2226. notype_declarator:
  2227.       notype_declarator '(' nonnull_exprlist ')' type_quals  %prec '.'
  2228.         { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
  2229.     | notype_declarator '(' parmlist ')' type_quals  %prec '.'
  2230.         { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
  2231.     | notype_declarator LEFT_RIGHT type_quals  %prec '.'
  2232.         { $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $3); }
  2233.     | notype_declarator '(' error ')' type_quals  %prec '.'
  2234.         { $$ = build_parse_node (CALL_EXPR, $$, NULL_TREE, NULL_TREE); }
  2235.     | '(' notype_declarator ')'
  2236.         { $$ = $2; }
  2237.     | '*' type_quals notype_declarator  %prec UNARY
  2238.         { $$ = make_pointer_declarator ($2, $3); }
  2239.     | '&' type_quals notype_declarator  %prec UNARY
  2240.         { $$ = make_reference_declarator ($2, $3); }
  2241.     | notype_declarator '[' nonmomentary_expr ']'
  2242.         { $$ = build_parse_node (ARRAY_REF, $$, $3); }
  2243.     | notype_declarator '[' ']'
  2244.         { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); }
  2245.     | IDENTIFIER
  2246.         { see_typename (); }
  2247.  
  2248.     /* C++ extensions.  */
  2249.     | operator_name
  2250.         { see_typename (); }
  2251.  
  2252.     | '~' TYPENAME
  2253.         {
  2254.         destructor_name:
  2255.           see_typename ();
  2256.           $$ = build_parse_node (BIT_NOT_EXPR, $2);
  2257.         }
  2258.     | '~' IDENTIFIER
  2259.         { goto destructor_name; }
  2260.     | LEFT_RIGHT identifier
  2261.         {
  2262.           see_typename ();
  2263.           $$ = build_parse_node (WRAPPER_EXPR, $2);
  2264.         }
  2265.     | LEFT_RIGHT '?' identifier
  2266.         {
  2267.           see_typename ();
  2268.           $$ = build_parse_node (WRAPPER_EXPR,
  2269.                  build_parse_node (COND_EXPR, $3, NULL_TREE, NULL_TREE));
  2270.         }
  2271.     | '~' LEFT_RIGHT identifier
  2272.         { see_typename ();
  2273.           $$ = build_parse_node (ANTI_WRAPPER_EXPR, $3); }
  2274.     | scoped_id see_typename notype_declarator  %prec '('
  2275.         { see_typename ();
  2276.           $$ = build_push_scope ($$, $3); }
  2277.     | scoped_id see_typename TYPENAME  %prec '('
  2278.         { $$ = build_push_scope ($$, $3); }
  2279.     | scoped_id see_typename TYPENAME '(' nonnull_exprlist ')' type_quals  %prec '.'
  2280.         { $$ = build_push_scope ($$, build_parse_node (CALL_EXPR, $3, $5, $7)); }
  2281.     | scoped_id see_typename TYPENAME '(' parmlist ')' type_quals  %prec '.'
  2282.         { $$ = build_push_scope ($$, build_parse_node (CALL_EXPR, $3, $5, $7)); }
  2283.     | scoped_id see_typename TYPENAME LEFT_RIGHT type_quals  %prec '.'
  2284.         { $$ = build_push_scope ($$, build_parse_node (CALL_EXPR, $3, empty_parms (), $5)); }
  2285.     | scoped_id see_typename TYPENAME '(' error ')' type_quals  %prec '.'
  2286.         { $$ = build_push_scope ($$, build_parse_node (CALL_EXPR, $3, NULL_TREE, NULL_TREE)); }
  2287.     | SCOPE see_typename notype_declarator
  2288.         { $$ = build_parse_node (SCOPE_REF, NULL_TREE, $3); }
  2289.     ;
  2290.  
  2291. scoped_id:    TYPENAME_SCOPE
  2292.         { $$ = resolve_scope_to_name (NULL_TREE, $$); }
  2293.     | template_type SCOPE try_for_typename %prec EMPTY
  2294.         { $$ = resolve_scope_to_name (NULL_TREE, TYPE_IDENTIFIER ($$));
  2295.           popclass (1); }
  2296.     ;
  2297.  
  2298. scoped_typename: SCOPED_TYPENAME
  2299. /*    | scoped_id TYPENAME
  2300.         { $$ = resolve_scope_to_name ($$, $2); }*/
  2301.     ;
  2302.  
  2303. absdcl1:  /* a nonempty abstract declarator */
  2304.       '(' absdcl1 ')'
  2305.         { see_typename ();
  2306.           $$ = $2; }
  2307.       /* `(typedef)1' is `int'.  */
  2308.     | '*' type_quals absdcl1  %prec EMPTY
  2309.         { $$ = make_pointer_declarator ($2, $3); }
  2310.     | '*' type_quals  %prec EMPTY
  2311.         { $$ = make_pointer_declarator ($2, NULL_TREE); }
  2312.     | PAREN_STAR_PAREN
  2313.         { see_typename (); }
  2314.     | '(' abs_member_declarator ')'
  2315.         { $$ = $2; }
  2316.     | '&' type_quals absdcl1 %prec EMPTY
  2317.         { $$ = make_reference_declarator ($2, $3); }
  2318.     | '&' type_quals %prec EMPTY
  2319.         { $$ = make_reference_declarator ($2, NULL_TREE); }
  2320.     | absdcl1 '(' parmlist ')' type_quals  %prec '.'
  2321.         { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
  2322.     | absdcl1 LEFT_RIGHT type_quals  %prec '.'
  2323.         { $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $3); }
  2324.     | absdcl1 '[' nonmomentary_expr ']'  %prec '.'
  2325.         { $$ = build_parse_node (ARRAY_REF, $$, $3); }
  2326.     | absdcl1 '[' ']'  %prec '.'
  2327.         { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); }
  2328.     | '(' parmlist ')' type_quals  %prec '.'
  2329.         { $$ = build_parse_node (CALL_EXPR, NULL_TREE, $2, $4); }
  2330.     | LEFT_RIGHT type_quals  %prec '.'
  2331.         { $$ = build_parse_node (CALL_EXPR, NULL_TREE, empty_parms (), $2); }
  2332.     | '[' nonmomentary_expr ']'  %prec '.'
  2333.         { $$ = build_parse_node (ARRAY_REF, NULL_TREE, $2); }
  2334.     | '[' ']'  %prec '.'
  2335.         { $$ = build_parse_node (ARRAY_REF, NULL_TREE, NULL_TREE); }
  2336.     ;
  2337.  
  2338. abs_member_declarator:
  2339.       scoped_id '*' type_quals
  2340.         { tree t;
  2341.           t = $$;
  2342.           while (TREE_OPERAND (t, 1))
  2343.             t = TREE_OPERAND (t, 1);
  2344.           TREE_OPERAND (t, 1) = build_parse_node (INDIRECT_REF, 0);
  2345.         }
  2346.     | scoped_id '*' type_quals absdcl1
  2347.         { tree t;
  2348.           t = $$;
  2349.           while (TREE_OPERAND (t, 1))
  2350.             t = TREE_OPERAND (t, 1);
  2351.           TREE_OPERAND (t, 1) = build_parse_node (INDIRECT_REF, $4);
  2352.         }
  2353.     | scoped_id '&' type_quals
  2354.         { tree t;
  2355.           t = $$;
  2356.           while (TREE_OPERAND (t, 1))
  2357.             t = TREE_OPERAND (t, 1);
  2358.           TREE_OPERAND (t, 1) = build_parse_node (ADDR_EXPR, 0);
  2359.         }
  2360.     | scoped_id '&' type_quals absdcl1
  2361.         { tree t;
  2362.           t = $$;
  2363.           while (TREE_OPERAND (t, 1))
  2364.             t = TREE_OPERAND (t, 1);
  2365.           TREE_OPERAND (t, 1) = build_parse_node (ADDR_EXPR, $4);
  2366.         }
  2367.     ;
  2368.  
  2369. after_type_member_declarator:
  2370.       scoped_id see_typename '*' type_quals after_type_declarator
  2371.         { tree t;
  2372.           t = $$;
  2373.           while (TREE_OPERAND (t, 1))
  2374.             t = TREE_OPERAND (t, 1);
  2375.           TREE_OPERAND (t, 1) = build_parse_node (INDIRECT_REF, $5);
  2376.         }
  2377.     | scoped_id see_typename '&' type_quals after_type_declarator
  2378.         { tree t;
  2379.           t = $$;
  2380.           while (TREE_OPERAND (t, 1))
  2381.             t = TREE_OPERAND (t, 1);
  2382.           TREE_OPERAND (t, 1) = build_parse_node (ADDR_EXPR, $5);
  2383.         }
  2384.     ;
  2385.  
  2386. /* at least one statement, the first of which parses without error.  */
  2387. /* stmts is used only after decls, so an invalid first statement
  2388.    is actually regarded as an invalid decl and part of the decls.  */
  2389.  
  2390. stmts:
  2391.       stmt
  2392.     | stmts stmt
  2393.     | stmts errstmt
  2394.     ;
  2395.  
  2396. errstmt:  error ';'
  2397.     ;
  2398.  
  2399. /* build the LET_STMT node before parsing its contents,
  2400.   so that any LET_STMTs within the context can have their display pointers
  2401.   set up to point at this one.  */
  2402.  
  2403. .pushlevel:  /* empty */
  2404.         {
  2405.           pushlevel (0);
  2406.           clear_last_expr ();
  2407.           push_momentary ();
  2408.           expand_start_bindings (0);
  2409.           stmt_decl_msg = 0;
  2410.         }
  2411.     ;
  2412.  
  2413. /* This is the body of a function definition.
  2414.    It causes syntax errors to ignore to the next openbrace.  */
  2415. compstmt_or_error:
  2416.       compstmt
  2417.         {}
  2418.     | error compstmt
  2419.     ;
  2420.  
  2421. compstmt: '{' '}'
  2422.         { $$ = convert (void_type_node, integer_zero_node); }
  2423.     | '{' .pushlevel stmts '}'
  2424.         { tree decls;
  2425.  
  2426.           pop_implicit_try_blocks (NULL_TREE);
  2427.           decls = getdecls ();
  2428.           expand_end_bindings (decls, decls != 0, 1);
  2429.           $$ = poplevel (decls != 0, 1, 0);
  2430.           pop_momentary (); }
  2431.     | '{' .pushlevel error '}'
  2432.         { pop_implicit_try_blocks (NULL_TREE);
  2433.           expand_end_bindings (getdecls (), 0, 1);
  2434.           $$ = poplevel (0, 0, 0);
  2435.           pop_momentary (); }
  2436.     ;
  2437.  
  2438. simple_if:
  2439.       IF '(' expr ')'
  2440.         { emit_line_note (input_filename, lineno);
  2441.           expand_start_cond (truthvalue_conversion ($3), 0);
  2442.           stmt_decl_msg = "if"; }
  2443.       stmt
  2444.         { stmt_decl_msg = 0; }
  2445.     ;
  2446.  
  2447. stmt:
  2448.       compstmt
  2449.         { finish_stmt (); }
  2450.     | decl
  2451.         { if (stmt_decl_msg)
  2452.             error ("declaration after %s invalid", stmt_decl_msg);
  2453.           stmt_decl_msg = 0;
  2454.           finish_stmt (); }
  2455.     | expr ';'
  2456.         { emit_line_note (input_filename, lineno);
  2457.           /* Do default conversion if safe and possibly important,
  2458.              in case within ({...}).  */
  2459.           if ((TREE_CODE (TREE_TYPE ($1)) == ARRAY_TYPE
  2460.                && lvalue_p ($1))
  2461.               || TREE_CODE (TREE_TYPE ($1)) == FUNCTION_TYPE)
  2462.             $1 = default_conversion ($1);
  2463.           cplus_expand_expr_stmt ($1);
  2464.           clear_momentary ();
  2465.           finish_stmt (); }
  2466.     | simple_if ELSE
  2467.         { expand_start_else ();
  2468.           stmt_decl_msg = "else"; }
  2469.       stmt
  2470.         { expand_end_cond ();
  2471.           stmt_decl_msg = 0;
  2472.           finish_stmt (); }
  2473.     | simple_if %prec IF
  2474.         { expand_end_cond ();
  2475.           stmt_decl_msg = 0;
  2476.           finish_stmt (); }
  2477.     | WHILE
  2478.         { emit_nop ();
  2479.           emit_line_note (input_filename, lineno);
  2480.           expand_start_loop (1); }
  2481.       '(' expr ')'
  2482.         { expand_exit_loop_if_false (0, truthvalue_conversion ($4));
  2483.           stmt_decl_msg = "while"; }
  2484.       stmt
  2485.         { 
  2486.           expand_end_loop ();
  2487.           stmt_decl_msg = 0;
  2488.           finish_stmt (); }
  2489.     | DO
  2490.         { emit_nop ();
  2491.           emit_line_note (input_filename, lineno);
  2492.           expand_start_loop_continue_elsewhere (1);
  2493.           stmt_decl_msg = "do"; }
  2494.       stmt WHILE
  2495.         { stmt_decl_msg = 0;
  2496.           expand_loop_continue_here (); }
  2497.       '(' expr ')' ';'
  2498.         { emit_line_note (input_filename, lineno);
  2499.           expand_exit_loop_if_false (0, truthvalue_conversion ($7));
  2500.           expand_end_loop ();
  2501.           clear_momentary ();
  2502.           finish_stmt (); }
  2503.     | forhead.1
  2504.         { emit_nop ();
  2505.           emit_line_note (input_filename, lineno);
  2506.           if ($1) cplus_expand_expr_stmt ($1);
  2507.           expand_start_loop_continue_elsewhere (1); }
  2508.       xexpr ';'
  2509.         { emit_line_note (input_filename, lineno);
  2510.           if ($3) expand_exit_loop_if_false (0, truthvalue_conversion ($3)); }
  2511.       xexpr ')'
  2512.         /* Don't let the tree nodes for $6 be discarded
  2513.            by clear_momentary during the parsing of the next stmt.  */
  2514.         { push_momentary ();
  2515.           stmt_decl_msg = "for"; }
  2516.       stmt
  2517.         { emit_line_note (input_filename, lineno);
  2518.           expand_loop_continue_here ();
  2519.           if ($6) cplus_expand_expr_stmt ($6);
  2520.           pop_momentary ();
  2521.           expand_end_loop ();
  2522.           stmt_decl_msg = 0;
  2523.           finish_stmt (); }
  2524.     | forhead.2
  2525.         { emit_nop ();
  2526.           emit_line_note (input_filename, lineno);
  2527.           expand_start_loop_continue_elsewhere (1); }
  2528.       xexpr ';'
  2529.         { emit_line_note (input_filename, lineno);
  2530.           if ($3) expand_exit_loop_if_false (0, truthvalue_conversion ($3)); }
  2531.       xexpr ')'
  2532.         /* Don't let the tree nodes for $6 be discarded
  2533.            by clear_momentary during the parsing of the next stmt.  */
  2534.         { push_momentary ();
  2535.           stmt_decl_msg = "for";
  2536.           $<itype>7 = lineno; }
  2537.       stmt
  2538.         { emit_line_note (input_filename, $<itype>7);
  2539.           expand_loop_continue_here ();
  2540.           if ($6) cplus_expand_expr_stmt ($6);
  2541.           pop_momentary ();
  2542.           expand_end_loop ();
  2543.           pop_implicit_try_blocks (NULL_TREE);
  2544.           if ($1)
  2545.             {
  2546.               register keep = $1 > 0;
  2547.               if (keep) expand_end_bindings (0, keep, 1);
  2548.               poplevel (keep, 1, 0);
  2549.               pop_momentary ();
  2550.             }
  2551.           stmt_decl_msg = 0;
  2552.           finish_stmt ();
  2553.         }
  2554.     | SWITCH '(' expr ')'
  2555.         { emit_line_note (input_filename, lineno);
  2556.           c_expand_start_case ($3);
  2557.           /* Don't let the tree nodes for $3 be discarded by
  2558.              clear_momentary during the parsing of the next stmt.  */
  2559.           push_momentary ();
  2560.           stmt_decl_msg = "switch"; }
  2561.       stmt
  2562.         { expand_end_case ($3);
  2563.           pop_momentary ();
  2564.           stmt_decl_msg = 0;
  2565.           finish_stmt (); }
  2566.     | CASE expr ':'
  2567.         { register tree value = $2;
  2568.           register tree label
  2569.             = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
  2570.  
  2571.           /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
  2572.              Strip such NOP_EXPRs.  */
  2573.           if (TREE_CODE (value) == NOP_EXPR
  2574.               && TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0)))
  2575.             value = TREE_OPERAND (value, 0);
  2576.  
  2577.           if (TREE_READONLY_DECL_P (value))
  2578.             {
  2579.               value = decl_constant_value (value);
  2580.               /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
  2581.              Strip such NOP_EXPRs.  */
  2582.               if (TREE_CODE (value) == NOP_EXPR
  2583.               && TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0)))
  2584.             value = TREE_OPERAND (value, 0);
  2585.             }
  2586.           value = fold (value);
  2587.  
  2588.           if (TREE_CODE (value) != INTEGER_CST
  2589.               && value != error_mark_node)
  2590.             {
  2591.               error ("case label does not reduce to an integer constant");
  2592.               value = error_mark_node;
  2593.             }
  2594.           else
  2595.             /* Promote char or short to int.  */
  2596.             value = default_conversion (value);
  2597.           if (value != error_mark_node)
  2598.             {
  2599.               int success = pushcase (value, label);
  2600.               if (success == 1)
  2601.             error ("case label not within a switch statement");
  2602.               else if (success == 2)
  2603.             error ("duplicate case value");
  2604.               else if (success == 3)
  2605.             warning ("case value out of range");
  2606.             }
  2607.           define_case_label (label);
  2608.         }
  2609.       stmt
  2610.     | CASE expr RANGE expr ':'
  2611.         { register tree value1 = $2;
  2612.           register tree value2 = $4;
  2613.           register tree label
  2614.             = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
  2615.  
  2616.           if (pedantic)
  2617.             {
  2618.               error ("ANSI C does not allow range expressions in switch statement");
  2619.               value1 = error_mark_node;
  2620.               value2 = error_mark_node;
  2621.               break;
  2622.             }
  2623.           /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
  2624.              Strip such NOP_EXPRs.  */
  2625.           if (TREE_CODE (value1) == NOP_EXPR
  2626.               && TREE_TYPE (value1) == TREE_TYPE (TREE_OPERAND (value1, 0)))
  2627.             value1 = TREE_OPERAND (value1, 0);
  2628.  
  2629.           if (TREE_READONLY_DECL_P (value1))
  2630.             {
  2631.               value1 = decl_constant_value (value1);
  2632.               /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
  2633.              Strip such NOP_EXPRs.  */
  2634.               if (TREE_CODE (value1) == NOP_EXPR
  2635.               && TREE_TYPE (value1) == TREE_TYPE (TREE_OPERAND (value1, 0)))
  2636.             value1 = TREE_OPERAND (value1, 0);
  2637.             }
  2638.           value1 = fold (value1);
  2639.  
  2640.           /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
  2641.              Strip such NOP_EXPRs.  */
  2642.           if (TREE_CODE (value2) == NOP_EXPR
  2643.               && TREE_TYPE (value2) == TREE_TYPE (TREE_OPERAND (value2, 0)))
  2644.             value2 = TREE_OPERAND (value2, 0);
  2645.  
  2646.           if (TREE_READONLY_DECL_P (value2))
  2647.             {
  2648.               value2 = decl_constant_value (value2);
  2649.               /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
  2650.              Strip such NOP_EXPRs.  */
  2651.               if (TREE_CODE (value2) == NOP_EXPR
  2652.               && TREE_TYPE (value2) == TREE_TYPE (TREE_OPERAND (value2, 0)))
  2653.             value2 = TREE_OPERAND (value2, 0);
  2654.             }
  2655.           value2 = fold (value2);
  2656.  
  2657.  
  2658.           if (TREE_CODE (value1) != INTEGER_CST
  2659.               && value1 != error_mark_node)
  2660.             {
  2661.               error ("case label does not reduce to an integer constant");
  2662.               value1 = error_mark_node;
  2663.             }
  2664.           if (TREE_CODE (value2) != INTEGER_CST
  2665.               && value2 != error_mark_node)
  2666.             {
  2667.               error ("case label does not reduce to an integer constant");
  2668.               value2 = error_mark_node;
  2669.             }
  2670.           if (value1 != error_mark_node
  2671.               && value2 != error_mark_node)
  2672.             {
  2673.               int success = pushcase_range (value1, value2, label);
  2674.               if (success == 1)
  2675.             error ("case label not within a switch statement");
  2676.               else if (success == 2)
  2677.             error ("duplicate (or overlapping) case value");
  2678.               else if (success == 3)
  2679.             warning ("case value out of range");
  2680.               else if (success == 4)
  2681.             warning ("empty range specified");
  2682.             }
  2683.           define_case_label (label);
  2684.         }
  2685.       stmt
  2686.     | DEFAULT ':'
  2687.         {
  2688.           register tree label
  2689.             = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
  2690.           int success = pushcase (NULL_TREE, label);
  2691.           if (success == 1)
  2692.             error ("default label not within a switch statement");
  2693.           else if (success == 2)
  2694.             error ("multiple default labels in one switch");
  2695.         }
  2696.       stmt
  2697.     | BREAK ';'
  2698.         { emit_line_note (input_filename, lineno);
  2699.           if ( ! expand_exit_something ())
  2700.             error ("break statement not within loop or switch"); }
  2701.     | CONTINUE ';'
  2702.         { emit_line_note (input_filename, lineno);
  2703.           if (! expand_continue_loop (0))
  2704.             error ("continue statement not within a loop"); }
  2705.     | RETURN ';'
  2706.         { emit_line_note (input_filename, lineno);
  2707.           c_expand_return (NULL_TREE); }
  2708.     | RETURN expr ';'
  2709.         { emit_line_note (input_filename, lineno);
  2710.           c_expand_return ($2);
  2711.           finish_stmt ();
  2712.         }
  2713.     | ASM maybe_type_qual '(' string ')' ';'
  2714.         { if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
  2715.           emit_line_note (input_filename, lineno);
  2716.           expand_asm ($4);
  2717.           finish_stmt ();
  2718.         }
  2719.     /* This is the case with just output operands.  */
  2720.     | ASM maybe_type_qual '(' string ':' asm_operands ')' ';'
  2721.         { if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
  2722.           emit_line_note (input_filename, lineno);
  2723.           c_expand_asm_operands ($4, $6, NULL_TREE, NULL_TREE,
  2724.                      $2 == ridpointers[(int)RID_VOLATILE],
  2725.                      input_filename, lineno);
  2726.           finish_stmt ();
  2727.         }
  2728.     /* This is the case with input operands as well.  */
  2729.     | ASM maybe_type_qual '(' string ':' asm_operands ':' asm_operands ')' ';'
  2730.         { if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
  2731.           emit_line_note (input_filename, lineno);
  2732.           c_expand_asm_operands ($4, $6, $8, NULL_TREE,
  2733.                      $2 == ridpointers[(int)RID_VOLATILE],
  2734.                      input_filename, lineno);
  2735.           finish_stmt ();
  2736.         }
  2737.     /* This is the case with clobbered registers as well.  */
  2738.     | ASM maybe_type_qual '(' string ':' asm_operands ':'
  2739.         asm_operands ':' asm_clobbers ')' ';'
  2740.         { if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
  2741.           emit_line_note (input_filename, lineno);
  2742.           c_expand_asm_operands ($4, $6, $8, $10,
  2743.                      $2 == ridpointers[(int)RID_VOLATILE],
  2744.                      input_filename, lineno);
  2745.           finish_stmt ();
  2746.         }
  2747.     | GOTO identifier ';'
  2748.         { tree decl;
  2749.           emit_line_note (input_filename, lineno);
  2750.           decl = lookup_label ($2);
  2751.           TREE_USED (decl) = 1;
  2752.           expand_goto (decl); }
  2753.     | IDENTIFIER ':'
  2754.         { tree label = define_label (input_filename, lineno, $1);
  2755.           emit_nop ();
  2756.           if (label)
  2757.             expand_label (label); }
  2758.       stmt
  2759.         { finish_stmt (); }
  2760.     | PTYPENAME ':'
  2761.         { tree label = define_label (input_filename, lineno, $1);
  2762.           emit_nop ();
  2763.           if (label)
  2764.             expand_label (label); }
  2765.       stmt
  2766.         { finish_stmt (); }
  2767.     | TYPENAME_COLON
  2768.         { tree label = define_label (input_filename, lineno, $1);
  2769.           if (label)
  2770.             expand_label (label); }
  2771.       stmt
  2772.         { finish_stmt (); }
  2773.     | ';'
  2774.         { finish_stmt (); }
  2775.  
  2776.     /* Exception handling extentions.  */
  2777.     | RAISE raise_identifier '(' nonnull_exprlist ')' ';'
  2778.         { cplus_expand_raise ($2, $4, NULL_TREE, 0);
  2779.           finish_stmt (); }
  2780.     | RAISE raise_identifier LEFT_RIGHT ';'
  2781.         { cplus_expand_raise ($2, NULL_TREE, NULL_TREE, 0);
  2782.           finish_stmt (); }
  2783.     | RAISE identifier ';'
  2784.         { cplus_expand_reraise ($2);
  2785.           finish_stmt (); }
  2786.     | try EXCEPT identifier '{'
  2787.         {
  2788.           tree decl = cplus_expand_end_try ($1);
  2789.           $<ttype>2 = current_exception_type;
  2790.           $<ttype>4 = current_exception_decl;
  2791.           $<ttype>$ = current_exception_object;
  2792.           cplus_expand_start_except ($3, decl);
  2793.           pushlevel (0);
  2794.           clear_last_expr ();
  2795.           push_momentary ();
  2796.           expand_start_bindings (0);
  2797.           stmt_decl_msg = 0;
  2798.         }
  2799.       except_stmts '}'
  2800.         {
  2801.           tree decls = getdecls ();
  2802.           /* If there is a default exception to handle,
  2803.              handle it here.  */
  2804.           if ($6)
  2805.             {
  2806.               tree decl = build_decl (CPLUS_CATCH_DECL, NULL_TREE, 0);
  2807.               tree block;
  2808.  
  2809.               pushlevel (1);
  2810.               expand_start_bindings (0);
  2811.               expand_expr ($6, 0, 0, 0);
  2812.               expand_end_bindings (0, 1, 0);
  2813.               block = poplevel (1, 0, 0);
  2814.  
  2815.               /* This is a catch block.  */
  2816.               TREE_LANG_FLAG_2 (block) = 1;
  2817.               BLOCK_VARS (block) = decl;
  2818.             }
  2819.  
  2820.           expand_end_bindings (decls, decls != 0, 1);
  2821.           poplevel (decls != 0, 1, 0);
  2822.           pop_momentary ();
  2823.           current_exception_type = $<ttype>2;
  2824.           current_exception_decl = $<ttype>4;
  2825.           current_exception_object = $<ttype>5;
  2826.           cplus_expand_end_except ($6);
  2827.         }
  2828.     | try RERAISE raise_identifiers /* ';' checked for at bottom.  */
  2829.         { tree name = get_identifier ("(compiler error)");
  2830.           tree orig_ex_type = current_exception_type;
  2831.           tree orig_ex_decl = current_exception_decl;
  2832.           tree orig_ex_obj = current_exception_object;
  2833.           tree decl = cplus_expand_end_try ($1), decls;
  2834.  
  2835.           /* Start hidden EXCEPT.  */
  2836.           cplus_expand_start_except (name, decl);
  2837.           pushlevel (0);
  2838.           clear_last_expr ();
  2839.           push_momentary ();
  2840.           expand_start_bindings (0);
  2841.           stmt_decl_msg = 0;
  2842.  
  2843.           /* This sets up the reraise.  */
  2844.           cplus_expand_reraise ($3);
  2845.  
  2846.           decls = getdecls ();
  2847.           expand_end_bindings (decls, decls != 0, 1);
  2848.           poplevel (decls != 0, 1, 0);
  2849.           pop_momentary ();
  2850.           current_exception_type = orig_ex_type;
  2851.           current_exception_decl = orig_ex_decl;
  2852.           current_exception_object = orig_ex_obj;
  2853.           /* This will reraise for us.  */
  2854.           cplus_expand_end_except (error_mark_node);
  2855.           if (yychar == YYEMPTY)
  2856.             yychar = YYLEX;
  2857.           if (yychar != ';')
  2858.             error ("missing ';' after reraise statement");
  2859.         }
  2860.     | try  %prec EMPTY
  2861.         { yyerror ("`except' missing after `try' statement");
  2862.           /* Terminate the binding contour started by special
  2863.              code in `.pushlevel'.  Automagically pops off
  2864.              the conditional we started for `try' stmt.  */
  2865.           cplus_expand_end_try ($1);
  2866.           expand_end_bindings (0, 0, 1);
  2867.           poplevel (0, 0, 0);
  2868.           pop_momentary ();
  2869.           YYERROR; }
  2870.     ;
  2871.  
  2872. try:      TRY '{' '}'
  2873.         { $$ = 0; }
  2874.     | try_head stmts '}'
  2875.         {
  2876.           $$ = 1;
  2877.           pop_implicit_try_blocks (NULL_TREE);
  2878.         }
  2879.     | try_head error '}'
  2880.         {
  2881.           $$ = 0;
  2882.           pop_implicit_try_blocks (NULL_TREE);
  2883.         }
  2884.     ;
  2885.  
  2886. try_head: TRY '{' { cplus_expand_start_try (0); } .pushlevel
  2887.  
  2888. except_stmts:
  2889.       /* empty */
  2890.         { $$ = NULL_TREE; }
  2891.     | except_stmts raise_identifier
  2892.         {
  2893.           tree type = lookup_exception_type (current_class_type, current_class_name, $2);
  2894.           if (type == NULL_TREE)
  2895.             {
  2896.               error ("`%s' is not an exception type",
  2897.                  IDENTIFIER_POINTER (TREE_VALUE ($2)));
  2898.               current_exception_type = NULL_TREE;
  2899.               TREE_TYPE (current_exception_object) = error_mark_node;
  2900.             }
  2901.           else
  2902.             {
  2903.               current_exception_type = type;
  2904.               /* In-place union.  */
  2905.               TREE_TYPE (current_exception_object) = type;
  2906.             }
  2907.           $2 = cplus_expand_start_catch ($2);
  2908.           pushlevel (1);
  2909.           expand_start_bindings (0);
  2910.         }
  2911.       compstmt
  2912.         {
  2913.           expand_end_bindings (0, 1, 0);
  2914.           $4 = poplevel (1, 0, 0);
  2915.  
  2916.           cplus_expand_end_catch (0);
  2917.  
  2918.           /* Mark this as a catch block.  */
  2919.           TREE_LANG_FLAG_2 ($4) = 1;
  2920.           if ($2 != error_mark_node)
  2921.             {
  2922.               tree decl = build_decl (CPLUS_CATCH_DECL, DECL_NAME ($2), 0);
  2923.               DECL_RTL (decl) = DECL_RTL ($2);
  2924.               TREE_CHAIN (decl) = BLOCK_VARS ($4);
  2925.               BLOCK_VARS ($4) = decl;
  2926.             }
  2927.         }
  2928.     | except_stmts DEFAULT
  2929.         {
  2930.           if ($1)
  2931.             error ("duplicate default in exception handler");
  2932.           current_exception_type = NULL_TREE;
  2933.           /* Takes it right out of scope.  */
  2934.           TREE_TYPE (current_exception_object) = error_mark_node;
  2935.  
  2936.           if (! expand_catch_default ())
  2937.             compiler_error ("default catch botch");
  2938.  
  2939.           /* The default exception is handled as the
  2940.              last in the chain of exceptions handled.  */
  2941.           do_pending_stack_adjust ();
  2942.           start_sequence ();
  2943.           $1 = make_node (RTL_EXPR);
  2944.           TREE_TYPE ($1) = void_type_node;
  2945.         }
  2946.       compstmt
  2947.         {
  2948.           do_pending_stack_adjust ();
  2949.           if (! expand_catch (NULL_TREE))
  2950.             compiler_error ("except nesting botch");
  2951.           if (! expand_end_catch ())
  2952.             compiler_error ("except nesting botch");
  2953.           RTL_EXPR_SEQUENCE ($1) = (struct rtx_def *)get_insns ();
  2954.           if ($4)
  2955.             {
  2956.               /* Mark this block as the default catch block.  */
  2957.               TREE_LANG_FLAG_1 ($4) = 1;
  2958.               TREE_LANG_FLAG_2 ($4) = 1;
  2959.             }
  2960.           end_sequence ();
  2961.         }
  2962.     ;
  2963.  
  2964. forhead.1:
  2965.       FOR '(' ';'
  2966.         { $$ = NULL_TREE; }
  2967.     | FOR '(' expr ';'
  2968.         { $$ = $3; }
  2969.     | FOR '(' '{' '}'
  2970.         { $$ = NULL_TREE; }
  2971.     ;
  2972.  
  2973. forhead.2:
  2974.       FOR '(' decl
  2975.         { $$ = 0; }
  2976.     | FOR '(' error ';'
  2977.         { $$ = 0; }
  2978.     | FOR '(' '{' .pushlevel stmts '}'
  2979.         { $$ = 1; }
  2980.     | FOR '(' '{' .pushlevel error '}'
  2981.         { $$ = -1; }
  2982.     ;
  2983.  
  2984. /* Either a type-qualifier or nothing.  First thing in an `asm' statement.  */
  2985.  
  2986. maybe_type_qual:
  2987.     /* empty */
  2988.         { if (pedantic)
  2989.             warning ("ANSI C forbids use of `asm' keyword");
  2990.           emit_line_note (input_filename, lineno); }
  2991.     | TYPE_QUAL
  2992.         { if (pedantic)
  2993.             warning ("ANSI C forbids use of `asm' keyword");
  2994.           emit_line_note (input_filename, lineno); }
  2995.     ;
  2996.  
  2997. xexpr:
  2998.     /* empty */
  2999.         { $$ = NULL_TREE; }
  3000.     | expr
  3001.     | error
  3002.         { $$ = NULL_TREE; }
  3003.     ;
  3004.  
  3005. /* These are the operands other than the first string and colon
  3006.    in  asm ("addextend %2,%1": "=dm" (x), "0" (y), "g" (*x))  */
  3007. asm_operands: /* empty */
  3008.         { $$ = NULL_TREE; }
  3009.     | nonnull_asm_operands
  3010.     ;
  3011.  
  3012. nonnull_asm_operands:
  3013.       asm_operand
  3014.     | nonnull_asm_operands ',' asm_operand
  3015.         { $$ = chainon ($$, $3); }
  3016.     ;
  3017.  
  3018. asm_operand:
  3019.       STRING '(' expr ')'
  3020.         { $$ = build_tree_list ($$, $3); }
  3021.     ;
  3022.  
  3023. asm_clobbers:
  3024.       STRING
  3025.         { $$ = tree_cons (NULL_TREE, $$, NULL_TREE); }
  3026.     | asm_clobbers ',' STRING
  3027.         { $$ = tree_cons (NULL_TREE, $3, $$); }
  3028.     ;
  3029.  
  3030. /* This is what appears inside the parens in a function declarator.
  3031.    Its value is represented in the format that grokdeclarator expects.
  3032.  
  3033.    In C++, declaring a function with no parameters
  3034.    means that that function takes *no* parameters.  */
  3035. parmlist:  /* empty */
  3036.         {
  3037.           if (strict_prototype)
  3038.             $$ = void_list_node;
  3039.           else
  3040.             $$ = NULL_TREE;
  3041.         }
  3042.     | parms
  3043.           {
  3044.           $$ = chainon ($$, void_list_node);
  3045.           TREE_PARMLIST ($$) = 1;
  3046.         }
  3047.     | parms ',' ELLIPSIS
  3048.         {
  3049.           TREE_PARMLIST ($$) = 1;
  3050.         }
  3051.     /* C++ allows an ellipsis without a separating ',' */
  3052.     | parms ELLIPSIS
  3053.         {
  3054.           TREE_PARMLIST ($$) = 1;
  3055.         }
  3056.     | ELLIPSIS
  3057.         {
  3058.           $$ = NULL_TREE;
  3059.         }
  3060.     | TYPENAME_ELLIPSIS
  3061.         {
  3062.           TREE_PARMLIST ($$) = 1;
  3063.         }
  3064.     | parms TYPENAME_ELLIPSIS
  3065.         {
  3066.           TREE_PARMLIST ($$) = 1;
  3067.         }
  3068.     | parms ':'
  3069.         {
  3070.           /* This helps us recover from really nasty
  3071.              parse errors, for example, a missing right
  3072.              parenthesis.  */
  3073.           yyerror ("possibly missing ')'");
  3074.           $$ = chainon ($$, void_list_node);
  3075.           TREE_PARMLIST ($$) = 1;
  3076.           yyungetc (':', 0);
  3077.           yychar = ')';
  3078.         }
  3079.     ;
  3080.  
  3081. /* A nonempty list of parameter declarations or type names.  */
  3082. parms:
  3083.       parm
  3084.         { $$ = build_tree_list (NULL_TREE, $$); }
  3085.     | parm '=' init
  3086.         { $$ = build_tree_list ($3, $$); }
  3087.     | parms ',' parm
  3088.         { $$ = chainon ($$, build_tree_list (NULL_TREE, $3)); }
  3089.     | parms ',' parm '=' init
  3090.         { $$ = chainon ($$, build_tree_list ($5, $3)); }
  3091.     | parms ',' bad_parm
  3092.         { $$ = chainon ($$, build_tree_list (NULL_TREE, $3)); }
  3093.     | parms ',' bad_parm '=' init
  3094.         { $$ = chainon ($$, build_tree_list ($5, $3)); }
  3095.     ;
  3096.  
  3097. /* A single parameter declaration or parameter type name,
  3098.    as found in a parmlist.  The first four cases make up for 10%
  3099.    of the time spent parsing C++.  We cannot use them because
  3100.    of `int id[]' which won't get parsed properly.  */
  3101. parm:
  3102. /*
  3103.       typed_declspecs dont_see_typename '*' IDENTIFIER
  3104.         { $$ = build_tree_list ($$, build_parse_node (INDIRECT_REF, $4));
  3105.           see_typename (); }
  3106.     | typed_declspecs dont_see_typename '&' IDENTIFIER
  3107.         { $$ = build_tree_list ($$, build_parse_node (ADDR_EXPR, $4));
  3108.           see_typename (); }
  3109.     | TYPENAME IDENTIFIER
  3110.         { $$ = build_tree_list (list_hash_lookup_or_cons ($$), $2);  }
  3111.     | TYPESPEC IDENTIFIER
  3112.         { $$ = build_tree_list (list_hash_lookup_or_cons ($$), $2); }
  3113.     | */
  3114.       typed_declspecs dont_see_typename absdcl
  3115.         { $$ = build_tree_list ($$, $3);
  3116.           see_typename (); }
  3117.     | typed_declspecs dont_see_typename notype_declarator
  3118.         { $$ = build_tree_list ($$, $3);
  3119.           see_typename (); }
  3120.     | declmods dont_see_typename notype_declarator
  3121.         { $$ = build_tree_list ($$, $3);
  3122.           see_typename (); }
  3123.     | declmods dont_see_typename absdcl
  3124.         { $$ = build_tree_list ($$, $3);
  3125.           see_typename (); }
  3126.     ;
  3127.  
  3128. see_typename: type_quals
  3129.     { see_typename (); }
  3130.     ;
  3131.  
  3132. dont_see_typename: /* empty */
  3133.     { dont_see_typename (); }
  3134.     ;
  3135.  
  3136. try_for_typename:
  3137.     { pushclass ($<ttype>-1, 1); }
  3138.     ;
  3139.  
  3140. bad_parm:
  3141.       notype_declarator
  3142.         {
  3143.           warning ("type specifier omitted for parameter");
  3144.           $$ = build_tree_list (TREE_PURPOSE (TREE_VALUE ($<ttype>-1)), $$);
  3145.         }
  3146.     | absdcl
  3147.         {
  3148.           warning ("type specifier omitted for parameter");
  3149.           $$ = build_tree_list (TREE_PURPOSE (TREE_VALUE ($<ttype>-1)), $$);
  3150.         }
  3151.     ;
  3152.  
  3153. maybe_raises:
  3154.       /* empty */
  3155.         { $$ = NULL_TREE; }
  3156.     | RAISES raise_identifiers  %prec EMPTY
  3157.         { $$ = $2; }
  3158.     ;
  3159.  
  3160. raise_identifier:
  3161.       ALL
  3162.         { $$ = void_list_node; }
  3163.     | IDENTIFIER
  3164.         { $$ = build_decl_list (NULL_TREE, $$); }
  3165.     | TYPENAME
  3166.         { $$ = build_decl_list (NULL_TREE, $$); }
  3167.     | SCOPE IDENTIFIER
  3168.         { $$ = build_decl_list (void_type_node, $2); }
  3169.     | SCOPE TYPENAME
  3170.         { $$ = build_decl_list (void_type_node, $2); }
  3171.     | scoped_id IDENTIFIER
  3172.         { $$ = build_decl_list ($$, $2); }
  3173.     | scoped_typename
  3174.     ;
  3175.  
  3176. raise_identifiers:
  3177.       raise_identifier
  3178.     | raise_identifiers ',' raise_identifier
  3179.         {
  3180.             TREE_CHAIN ($3) = $$;
  3181.           $$ = $3;
  3182.         }
  3183.     ;
  3184.  
  3185. operator_name:
  3186.       OPERATOR '*'
  3187.         { $$ = build_opid (0, MULT_EXPR); }
  3188.     | OPERATOR '/'
  3189.         { $$ = build_opid (0, TRUNC_DIV_EXPR); }
  3190.     | OPERATOR '%'
  3191.         { $$ = build_opid (0, TRUNC_MOD_EXPR); }
  3192.     | OPERATOR '+'
  3193.         { $$ = build_opid (0, PLUS_EXPR); }
  3194.     | OPERATOR '-'
  3195.         { $$ = build_opid (0, MINUS_EXPR); }
  3196.     | OPERATOR '&'
  3197.         { $$ = build_opid (0, BIT_AND_EXPR); }
  3198.     | OPERATOR '|'
  3199.         { $$ = build_opid (0, BIT_IOR_EXPR); }
  3200.     | OPERATOR '^'
  3201.         { $$ = build_opid (0, BIT_XOR_EXPR); }
  3202.     | OPERATOR '~'
  3203.         { $$ = build_opid (0, BIT_NOT_EXPR); }
  3204.     | OPERATOR ','
  3205.         { $$ = build_opid (0, COMPOUND_EXPR); }
  3206.     | OPERATOR ARITHCOMPARE
  3207.         { $$ = build_opid (0, $2); }
  3208.     | OPERATOR '<'
  3209.         { $$ = build_opid (0, LT_EXPR); }
  3210.     | OPERATOR '>'
  3211.         { $$ = build_opid (0, GT_EXPR); }
  3212.     | OPERATOR EQCOMPARE
  3213.         { $$ = build_opid (0, $2); }
  3214.     | OPERATOR ASSIGN
  3215.         { $$ = build_opid (MODIFY_EXPR, $2); }
  3216.     | OPERATOR '='
  3217.         {
  3218.           $$ = build_opid (MODIFY_EXPR, NOP_EXPR);
  3219.           if (current_class_type)
  3220.             {
  3221.               TYPE_HAS_ASSIGNMENT (current_class_type) = 1;
  3222.               TYPE_GETS_ASSIGNMENT (current_class_type) = 1;
  3223.             }
  3224.         }
  3225.     | OPERATOR LSHIFT
  3226.         { $$ = build_opid (0, $2); }
  3227.     | OPERATOR RSHIFT
  3228.         { $$ = build_opid (0, $2); }
  3229.     | OPERATOR PLUSPLUS
  3230.         { $$ = build_opid (0, POSTINCREMENT_EXPR); }
  3231.     | OPERATOR MINUSMINUS
  3232.         { $$ = build_opid (0, PREDECREMENT_EXPR); }
  3233.     | OPERATOR ANDAND
  3234.         { $$ = build_opid (0, TRUTH_ANDIF_EXPR); }
  3235.     | OPERATOR OROR
  3236.         { $$ = build_opid (0, TRUTH_ORIF_EXPR); }
  3237.     | OPERATOR '!'
  3238.         { $$ = build_opid (0, TRUTH_NOT_EXPR); }
  3239.     | OPERATOR '?' ':'
  3240.         { $$ = build_opid (0, COND_EXPR); }
  3241.     | OPERATOR MIN_MAX
  3242.         { $$ = build_opid (0, $2); }
  3243.     | OPERATOR POINTSAT  %prec EMPTY
  3244.         { $$ = build_opid (0, COMPONENT_REF); }
  3245.     | OPERATOR POINTSAT_LEFT_RIGHT type_quals  %prec '.'
  3246.         {
  3247.           if (yychar == YYEMPTY)
  3248.             yychar = YYLEX;
  3249.           if (yychar == '(' || yychar == LEFT_RIGHT)
  3250.             {
  3251.               $$ = build_opid (0, METHOD_CALL_EXPR);
  3252.               if (current_class_type)
  3253.             {
  3254.               tree t = current_class_type;
  3255.               while (t)
  3256.                 {
  3257.                   TYPE_OVERLOADS_METHOD_CALL_EXPR (t) = 1;
  3258.                   t = TYPE_NEXT_VARIANT (t);
  3259.                 }
  3260.             }
  3261.             }
  3262.           else
  3263.             $$ = build_parse_node (CALL_EXPR, build_opid (0, COMPONENT_REF), void_list_node, $3);
  3264.         }
  3265.     | OPERATOR LEFT_RIGHT
  3266.         { $$ = build_opid (0, CALL_EXPR);
  3267.           if (current_class_type)
  3268.             {
  3269.               tree t = current_class_type;
  3270.               while (t)
  3271.             {
  3272.               TYPE_OVERLOADS_CALL_EXPR (t) = 1;
  3273.               t = TYPE_NEXT_VARIANT (t);
  3274.             }
  3275.             }
  3276.         }
  3277.     | OPERATOR '[' ']'
  3278.         { $$ = build_opid (0, ARRAY_REF);
  3279.           if (current_class_type)
  3280.             {
  3281.               tree t = current_class_type;
  3282.               while (t)
  3283.             {
  3284.               TYPE_OVERLOADS_ARRAY_REF (t) = 1;
  3285.               t = TYPE_NEXT_VARIANT (t);
  3286.             }
  3287.             }
  3288.         }
  3289.     | OPERATOR NEW
  3290.         {
  3291.           $$ = build_opid (0, NEW_EXPR);
  3292.           if (current_class_type)
  3293.             {
  3294.               tree t = current_class_type;
  3295.               while (t)
  3296.             {
  3297.               TREE_GETS_NEW (t) = 1;
  3298.               t = TYPE_NEXT_VARIANT (t);
  3299.             }
  3300.             }
  3301.         }
  3302.     | OPERATOR DELETE
  3303.         {
  3304.           $$ = build_opid (0, DELETE_EXPR);
  3305.           if (current_class_type)
  3306.             {
  3307.               tree t = current_class_type;
  3308.               while (t)
  3309.             {
  3310.               TREE_GETS_DELETE (t) = 1;
  3311.               t = TYPE_NEXT_VARIANT (t);
  3312.             }
  3313.             }
  3314.         }
  3315.  
  3316.     /* These should do `groktypename' and set up TREE_HAS_X_CONVERSION
  3317.        here, rather than doing it in class.c .  */
  3318.     | OPERATOR typed_typespecs absdcl
  3319.         {
  3320.           $$ = build1 (TYPE_EXPR, $2, $3);
  3321.         }
  3322.     | OPERATOR error
  3323.         { $$ = build_opid (ERROR_MARK, ERROR_MARK); }
  3324.     ;
  3325.  
  3326. %%
  3327.  
  3328. #if YYDEBUG != 0
  3329. db_yyerror (s, yyps, yychar)
  3330.      char *s;
  3331.      short *yyps;
  3332.      int yychar;
  3333. {
  3334.   FILE *yyout;
  3335.   char buf[1024];
  3336.   int st;
  3337.  
  3338.   yyerror (s);
  3339.   printf ("State is %d, input token number is %d.\n", *yyps, yychar);
  3340.  
  3341. #ifdef PARSE_OUTPUT
  3342.   if (*yyps < 1) fatal ("Cannot start from here");
  3343.   else if ((yyout = fopen (PARSE_OUTPUT, "r")) == NULL)
  3344.     error ("cannot open file %s", PARSE_OUTPUT);
  3345.   else
  3346.     {
  3347.       printf ("That is to say,\n\n");
  3348.       while (fgets(buf, sizeof (buf)-1, yyout))
  3349.     {
  3350.       if (buf[0] != 's') continue;
  3351.       st = atoi (buf+6);
  3352.       if (st != *yyps) continue;
  3353.       printf ("%s", buf);
  3354.       while (fgets (buf, sizeof (buf)-1, yyout))
  3355.         {
  3356.           if (buf[0] == 's') break;
  3357.           printf ("%s", buf);
  3358.         }
  3359.       break;
  3360.     }
  3361.       printf ("With the token %s\n", yytname[YYTRANSLATE (yychar)]);
  3362.       fclose (yyout);
  3363.     }
  3364. #endif
  3365. }
  3366. #endif
  3367.  
  3368. void
  3369. yyerror (string)
  3370.      char *string;
  3371. {
  3372.   extern int end_of_file;
  3373.   extern char *token_buffer;
  3374.   extern int input_redirected ();
  3375.   char buf[200];
  3376.  
  3377.   strcpy (buf, string);
  3378.  
  3379.   /* We can't print string and character constants well
  3380.      because the token_buffer contains the result of processing escapes.  */
  3381.   if (end_of_file)
  3382.     strcat (buf, input_redirected ()
  3383.         ? " at end of saved text"
  3384.         : " at end of input");
  3385.   else if (token_buffer[0] == 0)
  3386.     strcat (buf, " at null character");
  3387.   else if (token_buffer[0] == '"')
  3388.     strcat (buf, " before string constant");
  3389.   else if (token_buffer[0] == '\'')
  3390.     strcat (buf, " before character constant");
  3391.   else
  3392.     strcat (buf, " before `%s'");
  3393.  
  3394.   error (buf, token_buffer);
  3395. }
  3396.  
  3397. static int *reduce_count;
  3398. static int *token_count;
  3399.  
  3400. #define REDUCE_LENGTH (sizeof (yyr2) / sizeof (yyr2[0]))
  3401. #define TOKEN_LENGTH (256 + sizeof (yytname) / sizeof (yytname[0]))
  3402.  
  3403. int *
  3404. init_parse ()
  3405. {
  3406. #if YYDEBUG != 0
  3407. #ifdef GATHER_STATISTICS
  3408.   reduce_count = (int *)malloc (sizeof (int) * (REDUCE_LENGTH + 1));
  3409.   bzero (reduce_count, sizeof (int) * (REDUCE_LENGTH + 1));
  3410.   reduce_count += 1;
  3411.   token_count = (int *)malloc (sizeof (int) * (TOKEN_LENGTH + 1));
  3412.   bzero (token_count, sizeof (int) * (TOKEN_LENGTH + 1));
  3413.   token_count += 1;
  3414. #endif
  3415. #endif
  3416.   return token_count;
  3417. }
  3418.  
  3419. #ifdef GATHER_STATISTICS
  3420. void
  3421. yyhook (yyn)
  3422.      int yyn;
  3423. {
  3424.   reduce_count[yyn] += 1;
  3425. }
  3426. #endif
  3427.  
  3428. static int
  3429. reduce_cmp (p, q)
  3430.      int *p, *q;
  3431. {
  3432.   return reduce_count[*q] - reduce_count[*p];
  3433. }
  3434.  
  3435. static int
  3436. token_cmp (p, q)
  3437.      int *p, *q;
  3438. {
  3439.   return token_count[*q] - token_count[*p];
  3440. }
  3441.  
  3442. void
  3443. print_parse_statistics ()
  3444. {
  3445. #if YYDEBUG != 0
  3446.   int i;
  3447.   int maxlen = REDUCE_LENGTH;
  3448.   unsigned *sorted;
  3449.   
  3450.   if (reduce_count[-1] == 0)
  3451.     return;
  3452.  
  3453.   if (TOKEN_LENGTH > REDUCE_LENGTH)
  3454.     maxlen = TOKEN_LENGTH;
  3455.   sorted = (unsigned *) alloca (sizeof (int) * maxlen);
  3456.  
  3457.   for (i = 0; i < TOKEN_LENGTH; i++)
  3458.     sorted[i] = i;
  3459.   qsort (sorted, TOKEN_LENGTH, sizeof (int), token_cmp);
  3460.   for (i = 0; i < TOKEN_LENGTH; i++)
  3461.     {
  3462.       int index = sorted[i];
  3463.       if (token_count[index] == 0)
  3464.     break;
  3465.       if (token_count[index] < token_count[-1])
  3466.     break;
  3467.       fprintf (stderr, "token %d, `%s', count = %d\n",
  3468.            index, yytname[YYTRANSLATE (index)], token_count[index]);
  3469.     }
  3470.   fprintf (stderr, "\n");
  3471.   for (i = 0; i < REDUCE_LENGTH; i++)
  3472.     sorted[i] = i;
  3473.   qsort (sorted, REDUCE_LENGTH, sizeof (int), reduce_cmp);
  3474.   for (i = 0; i < REDUCE_LENGTH; i++)
  3475.     {
  3476.       int index = sorted[i];
  3477.       if (reduce_count[index] == 0)
  3478.     break;
  3479.       if (reduce_count[index] < reduce_count[-1])
  3480.     break;
  3481.       fprintf (stderr, "rule %d, line %d, count = %d\n",
  3482.            index, yyrline[index], reduce_count[index]);
  3483.     }
  3484.   fprintf (stderr, "\n");
  3485. #endif
  3486. }
  3487.