home *** CD-ROM | disk | FTP | other *** search
/ Education Sampler 1992 [NeXTSTEP] / Education_1992_Sampler.iso / NeXT / GnuSource / cc-61.0.1 / cc / objc-parse.y < prev    next >
Text File  |  1992-04-24  |  104KB  |  4,113 lines

  1. /* YACC parser for C syntax.
  2.    Copyright (C) 1987, 1988, 1989 Free Software Foundation, Inc.
  3.    Objective-C extensions by s.naroff.
  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. /* To whomever it may concern: I have heard that such a thing was once
  23. written by AT&T, but I have never seen it.  */
  24.  
  25. %expect 19
  26.  
  27. /* These are the 8 conflicts you should get in parse.output;
  28.    the state numbers may vary if minor changes in the grammar are made.
  29.  
  30. State 41 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
  31. State 92 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
  32. State 99 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
  33. State 103 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
  34. State 119 contains 1 shift/reduce conflict.  (See comment at component_decl.)
  35. State 183 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
  36. State 193 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
  37. State 199 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
  38. */
  39.  
  40. %{
  41. #include <stdio.h>
  42. #include <errno.h>
  43. #include <setjmp.h>
  44.  
  45. #include "config.h"
  46. #include "tree.h"
  47. #include "input.h"
  48. #include "c-parse.h"
  49. #include "c-tree.h"
  50. #include "flags.h"
  51.  
  52. #include "objc-actions.h"
  53.  
  54. #ifdef MULTIBYTE_CHARS
  55. #include <stdlib.h>
  56. #include <locale.h>
  57. #endif
  58.  
  59. #ifndef errno
  60. extern int errno;
  61. #endif
  62.  
  63. void yyerror ();
  64.  
  65. /* Like YYERROR but do call yyerror.  */
  66. #define YYERROR1 { yyerror ("syntax error"); YYERROR; }
  67.  
  68. static void position_after_white_space ();
  69.  
  70. /* The elements of `ridpointers' are identifier nodes
  71.    for the reserved type names and storage classes.
  72.    It is indexed by a RID_... value.  */
  73.  
  74. tree ridpointers[(int) RID_MAX];
  75. #define NORID RID_UNUSED
  76.  
  77. /* Cause the `yydebug' variable to be defined.  */
  78. #define YYDEBUG 1
  79. %}
  80.  
  81. %start program
  82.  
  83. %union {long itype; tree ttype; enum tree_code code;
  84.     char *filename; int lineno; }
  85.  
  86. /* All identifiers that are not reserved words
  87.    and are not declared typedefs in the current block */
  88. %token IDENTIFIER
  89.  
  90. /* All identifiers that are declared typedefs in the current block.
  91.    In some contexts, they are treated just like IDENTIFIER,
  92.    but they can also serve as typespecs in declarations.  */
  93. %token TYPENAME
  94.  
  95. /* Reserved words that specify storage class.
  96.    yylval contains an IDENTIFIER_NODE which indicates which one.  */
  97. %token SCSPEC
  98.  
  99. /* Reserved words that specify type.
  100.    yylval contains an IDENTIFIER_NODE which indicates which one.  */
  101. %token TYPESPEC
  102.  
  103. /* Reserved words that qualify type: "const" or "volatile".
  104.    yylval contains an IDENTIFIER_NODE which indicates which one.  */
  105. %token TYPE_QUAL
  106.  
  107. /* Character or numeric constants.
  108.    yylval is the node for the constant.  */
  109. %token CONSTANT
  110.  
  111. /* String constants in raw form.
  112.    yylval is a STRING_CST node.  */
  113. %token STRING
  114.  
  115. /* "...", used for functions with variable arglists.  */
  116. %token ELLIPSIS
  117.  
  118. /* the reserved words */
  119. %token SIZEOF ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT
  120. %token BREAK CONTINUE RETURN GOTO ASM TYPEOF ALIGNOF ALIGN
  121. %token ATTRIBUTE EXTENSION LABEL
  122.  
  123. /* the Objective-C keywords */
  124. %token INTERFACE IMPLEMENTATION END SELECTOR DEFS ENCODE
  125. %token CLASSNAME PRIVATE PROTECTED PUBLIC PROTOCOL OBJECTNAME CLASS ALIAS
  126.  
  127. /* Objective-C string constants in raw form.
  128.    yylval is a OBJC_STRING_CST node.  */
  129. %token OBJC_STRING
  130.  
  131. /* Add precedence rules to solve dangling else s/r conflict */
  132. %nonassoc IF
  133. %nonassoc ELSE
  134.  
  135. /* Define the operator tokens and their precedences.
  136.    The value is an integer because, if used, it is the tree code
  137.    to use in the expression made from the operator.  */
  138.  
  139. %right <code> ASSIGN '='
  140. %right <code> '?' ':'
  141. %left <code> OROR
  142. %left <code> ANDAND
  143. %left <code> '|'
  144. %left <code> '^'
  145. %left <code> '&'
  146. %left <code> EQCOMPARE
  147. %left <code> ARITHCOMPARE
  148. %left <code> LSHIFT RSHIFT
  149. %left <code> '+' '-'
  150. %left <code> '*' '/' '%'
  151. %right <code> UNARY PLUSPLUS MINUSMINUS
  152. %left HYPERUNARY
  153. %left <code> POINTSAT '.' '(' '['
  154.  
  155. %type <code> unop
  156.  
  157. %type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist exprlist
  158. %type <ttype> expr_no_commas cast_expr unary_expr primary string STRING
  159. %type <ttype> typed_declspecs reserved_declspecs
  160. %type <ttype> typed_typespecs reserved_typespecquals
  161. %type <ttype> declmods typespec typespecqual_reserved
  162. %type <ttype> SCSPEC TYPESPEC TYPE_QUAL nonempty_type_quals maybe_type_qual
  163. %type <ttype> initdecls notype_initdecls initdcl notype_initdcl
  164. %type <ttype> init initlist maybeasm
  165. %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
  166. %type <ttype> maybe_attribute attribute_list attrib
  167.  
  168. %type <ttype> compstmt
  169.  
  170. %type <ttype> declarator
  171. %type <ttype> notype_declarator after_type_declarator
  172. %type <ttype> parm_declarator
  173.  
  174. %type <ttype> structsp component_decl_list component_decl_list2
  175. %type <ttype> component_decl components component_declarator
  176. %type <ttype> enumlist enumerator
  177. %type <ttype> typename absdcl absdcl1 type_quals
  178. %type <ttype> xexpr parms parm identifiers
  179.  
  180. %type <ttype> parmlist parmlist_1 parmlist_2
  181. %type <ttype> parmlist_or_identifiers parmlist_or_identifiers_1
  182.  
  183. %type <itype> setspecs
  184.  
  185. %type <filename> save_filename
  186. %type <lineno> save_lineno
  187.  
  188. /* the Objective-C nonterminals */
  189.  
  190. %type <ttype> ivar_decl_list ivar_decls ivar_decl ivars ivar_declarator
  191. %type <ttype> methoddecl unaryselector keywordselector selector
  192. %type <ttype> keyworddecl receiver objcmessageexpr messageargs
  193. %type <ttype> keywordexpr keywordarglist keywordarg
  194. %type <ttype> myparms myparm optparmlist reservedwords objcselectorexpr
  195. %type <ttype> selectorarg keywordnamelist keywordname objcencodeexpr
  196. %type <ttype> objc_string protocolrefs identifier_list objcprotocolexpr
  197. %type <ttype> CLASSNAME OBJC_STRING OBJECTNAME
  198.  
  199. %{
  200. /* the declaration found for the last IDENTIFIER token read in.
  201.    yylex must look this up to detect typedefs, which get token type TYPENAME,
  202.    so it is left around in case the identifier is not a typedef but is
  203.    used in a context which makes it a reference to a variable.  */
  204. static tree lastiddecl;
  205.  
  206. static tree make_pointer_declarator ();
  207. static void reinit_parse_for_function ();
  208.  
  209. /* Number of statements (loosely speaking) seen so far.  */
  210. static int stmt_count;
  211.  
  212. /* Input file and line number of the end of the body of last simple_if;
  213.    used by the stmt-rule immediately after simple_if returns.  */
  214. static char *if_stmt_file;
  215. static int if_stmt_line;
  216.  
  217. /* List of types and structure classes of the current declaration.  */
  218. tree current_declspecs;
  219.  
  220. /* Stack of saved values of current_declspecs.  */
  221. tree declspec_stack;
  222.  
  223. int undeclared_variable_notice;    /* 1 if we explained undeclared var errors.  */
  224.  
  225. static int yylex ();
  226.  
  227. /* Objective-C specific information */
  228.  
  229. static void remember_protocol_qualifiers ();
  230. static void forget_protocol_qualifiers ();
  231.  
  232. static tree objc_interface_context;
  233. static tree objc_implementation_context;
  234. static tree objc_method_context;
  235. static tree objc_ivar_chain;
  236. static tree objc_ivar_context;
  237. static enum tree_code objc_inherit_code;
  238. static int objc_receiver_context;
  239. static int objc_public_flag;
  240.  
  241. static char *token_buffer;    /* Pointer to token buffer.
  242.                    Actual allocated length is maxtoken + 2.  */
  243.  
  244. /* Tell yyparse how to print a token's value, if yydebug is set.  */
  245.  
  246. #define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL)
  247.  
  248. static void
  249. yyprint (file, yychar, yylval)
  250.      FILE *file;
  251.      int yychar;
  252.      YYSTYPE yylval;
  253. {
  254.   tree t;
  255.   switch (yychar)
  256.     {
  257.     case IDENTIFIER:
  258.     case TYPENAME:
  259.     case OBJECTNAME:
  260.       t = yylval.ttype;
  261.       if (IDENTIFIER_POINTER (t))
  262.     fprintf (file, " `%s'", IDENTIFIER_POINTER (t));
  263.       break;
  264.  
  265.     case CONSTANT:
  266.       t = yylval.ttype;
  267.       if (TREE_CODE (t) == INTEGER_CST)
  268.     fprintf (file, " 0x%8x%8x", TREE_INT_CST_HIGH (t),
  269.          TREE_INT_CST_LOW (t));
  270.       break;
  271.     }
  272. }
  273.  
  274. /* Sets the value of the 'yydebug' varable to VALUE.
  275.    This is a function so we don't have to have YYDEBUG defined
  276.    in order to build the compiler.  */
  277. void
  278. set_yydebug (value)
  279.      int value;
  280. {
  281. #if YYDEBUG != 0
  282.   extern int yydebug;
  283.   yydebug = value;
  284. #else
  285.   warning ("YYDEBUG not defined.");
  286. #endif
  287. }
  288. %}
  289.  
  290. %%
  291. program: /* empty */
  292.         { if (pedantic)
  293.             pedwarn ("ANSI C forbids an empty source file");
  294.           objc_finish (); }
  295.     | extdefs
  296.         { objc_finish (); }
  297.     ;
  298.  
  299. /* the reason for the strange actions in this rule
  300.  is so that notype_initdecls when reached via datadef
  301.  can find a valid list of type and sc specs in $0. */
  302.  
  303. extdefs:
  304.     {$<ttype>$ = NULL_TREE; } extdef
  305.     | extdefs {$<ttype>$ = NULL_TREE; } extdef
  306.     ;
  307.  
  308. extdef:
  309.     fndef
  310.     | datadef
  311.     | objcdef
  312.     | ASM '(' string ')' ';'
  313.         { if (pedantic)
  314.             pedwarn ("ANSI C forbids use of `asm' keyword");
  315.           if (TREE_CHAIN ($3)) $3 = combine_strings ($3);
  316.           assemble_asm ($3); }
  317.     ;
  318.  
  319. datadef:
  320.       setspecs notype_initdecls ';'
  321.         { if (pedantic)
  322.             error ("ANSI C forbids data definition with no type or storage class");
  323.           else if (!flag_traditional)
  324.             warning ("data definition has no type or storage class"); }
  325.         | declmods setspecs notype_initdecls ';'
  326.       {}
  327.     | typed_declspecs setspecs initdecls ';'
  328.       {}
  329.         | declmods ';'
  330.       { error ("empty declaration"); }
  331.     | typed_declspecs ';'
  332.       { shadow_tag ($1); }
  333.     | error ';'
  334.     | error '}'
  335.     | ';'
  336.         { if (pedantic)
  337.             pedwarn ("ANSI C does not allow extra `;' outside of a function"); }
  338.     ;
  339.  
  340. fndef:
  341.       typed_declspecs setspecs declarator
  342.         { if (! start_function ($1, $3, 0))
  343.             YYERROR1;
  344.           reinit_parse_for_function (); }
  345.       xdecls
  346.         { store_parm_decls (); }
  347.       compstmt_or_error
  348.         { finish_function (0); }
  349.     | typed_declspecs setspecs declarator error
  350.         { }
  351.     | declmods setspecs notype_declarator
  352.         { if (! start_function ($1, $3, 0))
  353.             YYERROR1;
  354.           reinit_parse_for_function (); }
  355.       xdecls
  356.         { store_parm_decls (); }
  357.       compstmt_or_error
  358.         { finish_function (0); }
  359.     | declmods setspecs notype_declarator error
  360.         { }
  361.     | setspecs notype_declarator
  362.         { if (! start_function (0, $2, 0))
  363.             YYERROR1;
  364.           reinit_parse_for_function (); }
  365.       xdecls
  366.         { store_parm_decls (); }
  367.       compstmt_or_error
  368.         { finish_function (0); }
  369.     | setspecs notype_declarator error
  370.         { }
  371.     ;
  372.  
  373. identifier:
  374.     IDENTIFIER
  375.     | TYPENAME
  376.     | OBJECTNAME
  377.         | CLASSNAME
  378.     ;
  379.  
  380. unop:     '&'
  381.         { $$ = ADDR_EXPR; }
  382.     | '-'
  383.         { $$ = NEGATE_EXPR; }
  384.     | '+'
  385.         { $$ = CONVERT_EXPR; }
  386.     | PLUSPLUS
  387.         { $$ = PREINCREMENT_EXPR; }
  388.     | MINUSMINUS
  389.         { $$ = PREDECREMENT_EXPR; }
  390.     | '~'
  391.         { $$ = BIT_NOT_EXPR; }
  392.     | '!'
  393.         { $$ = TRUTH_NOT_EXPR; }
  394.     ;
  395.  
  396. expr:    nonnull_exprlist
  397.         { $$ = build_compound_expr ($1); }
  398.     ;
  399.  
  400. exprlist:
  401.       /* empty */
  402.         { $$ = NULL_TREE; }
  403.     | nonnull_exprlist
  404.     ;
  405.  
  406. nonnull_exprlist:
  407.     expr_no_commas
  408.         { $$ = build_tree_list (NULL_TREE, $1); }
  409.     | nonnull_exprlist ',' expr_no_commas
  410.         { chainon ($1, build_tree_list (NULL_TREE, $3)); }
  411.     ;
  412.  
  413. unary_expr:
  414.     primary
  415.     | '*' cast_expr   %prec UNARY
  416.         { $$ = build_indirect_ref ($2, "unary *"); }
  417.     /* __extension__ turns off -pedantic for following primary.  */
  418.     | EXTENSION
  419.         { $<itype>1 = pedantic;
  420.           pedantic = 0; }
  421.       cast_expr      %prec UNARY
  422.         { $$ = $3;
  423.           pedantic = $<itype>1; }
  424.     | unop cast_expr  %prec UNARY
  425.         { $$ = build_unary_op ($1, $2, 0); }
  426.     /* Refer to the address of a label as a pointer.  */
  427.     | ANDAND identifier
  428.         { tree label = lookup_label ($2);
  429.           TREE_USED (label) = 1;
  430.           $$ = build1 (ADDR_EXPR, ptr_type_node, label);
  431.           TREE_CONSTANT ($$) = 1; }
  432. /* This seems to be impossible on some machines, so let's turn it off.
  433.     | '&' ELLIPSIS
  434.         { tree types = TYPE_ARG_TYPES (TREE_TYPE (current_function_decl));
  435.           $$ = error_mark_node;
  436.           if (TREE_VALUE (tree_last (types)) == void_type_node)
  437.             error ("`&...' used in function with fixed number of arguments");
  438.           else
  439.             {
  440.               if (pedantic)
  441.             pedwarn ("ANSI C forbids `&...'");
  442.               $$ = tree_last (DECL_ARGUMENTS (current_function_decl));
  443.               $$ = build_unary_op (ADDR_EXPR, $$, 0);
  444.             } }
  445. */
  446.     | SIZEOF unary_expr  %prec UNARY
  447.         { if (TREE_CODE ($2) == COMPONENT_REF
  448.               && DECL_BIT_FIELD (TREE_OPERAND ($2, 1)))
  449.             error ("`sizeof' applied to a bit-field");
  450.           $$ = c_sizeof (TREE_TYPE ($2)); }
  451.     | SIZEOF '(' typename ')'  %prec HYPERUNARY
  452.         { $$ = c_sizeof (groktypename ($3)); }
  453.     | ALIGNOF unary_expr  %prec UNARY
  454.         { $$ = c_alignof_expr ($2); }
  455.     | ALIGNOF '(' typename ')'  %prec HYPERUNARY
  456.         { $$ = c_alignof (groktypename ($3)); }
  457.     ;
  458.  
  459. cast_expr:
  460.     unary_expr
  461.     | '(' typename ')' cast_expr  %prec UNARY
  462.         { tree type = groktypename ($2);
  463.           $$ = build_c_cast (type, $4); }
  464.     | '(' typename ')' '{' initlist maybecomma '}'  %prec UNARY
  465.         { tree type = groktypename ($2);
  466.           if (pedantic)
  467.             pedwarn ("ANSI C forbids constructor expressions");
  468.           $$ = digest_init (type, build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($5)), 0, 0, 0);
  469.           if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (type) == 0)
  470.             {
  471.               int failure = complete_array_type (type, $$, 1);
  472.               if (failure)
  473.             abort ();
  474.             }
  475.         }
  476.     ;
  477.  
  478. expr_no_commas:
  479.       cast_expr
  480.     | expr_no_commas '+' expr_no_commas
  481.         { $$ = parser_build_binary_op ($2, $1, $3); }
  482.     | expr_no_commas '-' expr_no_commas
  483.         { $$ = parser_build_binary_op ($2, $1, $3); }
  484.     | expr_no_commas '*' expr_no_commas
  485.         { $$ = parser_build_binary_op ($2, $1, $3); }
  486.     | expr_no_commas '/' expr_no_commas
  487.         { $$ = parser_build_binary_op ($2, $1, $3); }
  488.     | expr_no_commas '%' expr_no_commas
  489.         { $$ = parser_build_binary_op ($2, $1, $3); }
  490.     | expr_no_commas LSHIFT expr_no_commas
  491.         { $$ = parser_build_binary_op ($2, $1, $3); }
  492.     | expr_no_commas RSHIFT expr_no_commas
  493.         { $$ = parser_build_binary_op ($2, $1, $3); }
  494.     | expr_no_commas ARITHCOMPARE expr_no_commas
  495.         { $$ = parser_build_binary_op ($2, $1, $3); }
  496.     | expr_no_commas EQCOMPARE expr_no_commas
  497.         { $$ = parser_build_binary_op ($2, $1, $3); }
  498.     | expr_no_commas '&' expr_no_commas
  499.         { $$ = parser_build_binary_op ($2, $1, $3); }
  500.     | expr_no_commas '|' expr_no_commas
  501.         { $$ = parser_build_binary_op ($2, $1, $3); }
  502.     | expr_no_commas '^' expr_no_commas
  503.         { $$ = parser_build_binary_op ($2, $1, $3); }
  504.     | expr_no_commas ANDAND expr_no_commas
  505.         { $$ = parser_build_binary_op (TRUTH_ANDIF_EXPR, $1, $3); }
  506.     | expr_no_commas OROR expr_no_commas
  507.         { $$ = parser_build_binary_op (TRUTH_ORIF_EXPR, $1, $3); }
  508.     | expr_no_commas '?' xexpr ':' expr_no_commas
  509.         { $$ = build_conditional_expr ($1, $3, $5); }
  510.     | expr_no_commas '=' expr_no_commas
  511.         { $$ = build_modify_expr ($1, NOP_EXPR, $3); }
  512.     | expr_no_commas ASSIGN expr_no_commas
  513.         { $$ = build_modify_expr ($1, $2, $3); }
  514.     ;
  515.  
  516. primary:
  517.     IDENTIFIER
  518.         {
  519.           tree context;
  520.  
  521.           $$ = lastiddecl;
  522.           if (!$$ || $$ == error_mark_node)
  523.             {
  524.               if (yychar == YYEMPTY)
  525.             yychar = YYLEX;
  526.               if (yychar == '(')
  527.             {
  528.               tree decl;
  529.  
  530.               if (objc_receiver_context
  531.                   && ! (objc_receiver_context
  532.                     && strcmp (IDENTIFIER_POINTER ($1), "super")))
  533.                 /* we have a message to super */
  534.                 $$ = get_super_receiver ();
  535.               else if (objc_method_context
  536.                    && (decl = is_ivar (objc_ivar_chain, $1)))
  537.                 {
  538.                   if (is_private (decl))
  539.                     $$ = error_mark_node;
  540.                   else
  541.                     $$ = build_ivar_reference ($1);
  542.                 }
  543.               else
  544.                 {
  545.                   /* Ordinary implicit function declaration.  */
  546.                   $$ = implicitly_declare ($1);
  547.                   assemble_external ($$);
  548.                   TREE_USED ($$) = 1;
  549.                 }
  550.             }
  551.               else if (current_function_decl == 0)
  552.             {
  553.               error ("`%s' undeclared, outside of functions",
  554.                  IDENTIFIER_POINTER ($1));
  555.               $$ = error_mark_node;
  556.             }
  557.               else
  558.             {
  559.               tree decl;
  560.  
  561.                   if (objc_receiver_context
  562.                   && ! (objc_receiver_context
  563.                     && strcmp (IDENTIFIER_POINTER ($1), "super")))
  564.                 /* we have a message to super */
  565.                 $$ = get_super_receiver ();
  566.               else if (objc_method_context
  567.                    && (decl = is_ivar (objc_ivar_chain, $1)))
  568.                 {
  569.                   if (is_private (decl))
  570.                     $$ = error_mark_node;
  571.                   else
  572.                     $$ = build_ivar_reference ($1);
  573.                 }
  574.               else
  575.                 {
  576.                   if (IDENTIFIER_GLOBAL_VALUE ($1) != error_mark_node
  577.                   || IDENTIFIER_ERROR_LOCUS ($1) != current_function_decl)
  578.                 {
  579.                   error ("`%s' undeclared (first use this function)",
  580.                      IDENTIFIER_POINTER ($1));
  581.  
  582.                   if (! undeclared_variable_notice)
  583.                     {
  584.                       error ("(Each undeclared identifier is reported only once");
  585.                       error ("for each function it appears in.)");
  586.                       undeclared_variable_notice = 1;
  587.                     }
  588.                 }
  589.                   $$ = error_mark_node;
  590.                   /* Prevent repeated error messages.  */
  591.                   IDENTIFIER_GLOBAL_VALUE ($1) = error_mark_node;
  592.                   IDENTIFIER_ERROR_LOCUS ($1) = current_function_decl;
  593.                     }
  594.             }
  595.             }
  596.           else
  597.             {
  598.               if (! TREE_USED ($$))
  599.             {
  600.               if (TREE_EXTERNAL ($$))
  601.                 assemble_external ($$);
  602.               TREE_USED ($$) = 1;
  603.             }
  604.               /* we have a definition - still check if iVariable */
  605.  
  606.               if (!objc_receiver_context
  607.               || (objc_receiver_context
  608.                   && strcmp (IDENTIFIER_POINTER ($1), "super")))
  609.                         {
  610.               tree decl;
  611.  
  612.               if (objc_method_context
  613.                   && (decl = is_ivar (objc_ivar_chain, $1)))
  614.                             {
  615.                               if (IDENTIFIER_LOCAL_VALUE ($1))
  616.                                 warning ("local declaration of `%s' hides instance variable",
  617.                                      IDENTIFIER_POINTER ($1));
  618.                               else
  619.                 {
  620.                   if (is_private (decl))
  621.                     $$ = error_mark_node;
  622.                   else
  623.                     $$ = build_ivar_reference ($1);
  624.                 }
  625.                             }
  626.             }
  627.                       else /* we have a message to super */
  628.                 $$ = get_super_receiver ();
  629.             }
  630.           if (TREE_CODE ($$) == CONST_DECL)
  631.             $$ = DECL_INITIAL ($$);
  632.         }
  633.     | CONSTANT
  634.     | string
  635.         { $$ = combine_strings ($1); }
  636.     | '(' expr ')'
  637.         { char class = TREE_CODE_CLASS (TREE_CODE ($2));
  638.           if (class == 'e' || class == '1'
  639.               || class == '2' || class == '<')
  640.             C_SET_EXP_ORIGINAL_CODE ($2, ERROR_MARK);
  641.           $$ = $2; }
  642.     | '(' error ')'
  643.         { $$ = error_mark_node; }
  644.     | '('
  645.         { if (current_function_decl == 0)
  646.             {
  647.               error ("braced-group within expression allowed only inside a function");
  648.               YYERROR;
  649.             }
  650.           /* We must force a BLOCK for this level
  651.              so that, if it is not expanded later,
  652.              there is a way to turn off the entire subtree of blocks
  653.              that are contained in it.  */
  654.           keep_next_level ();
  655.           push_label_level ();
  656.           $<ttype>$ = expand_start_stmt_expr (); }
  657.       compstmt ')'
  658.         { tree rtl_exp;
  659.           if (pedantic)
  660.             pedwarn ("ANSI C forbids braced-groups within expressions");
  661.           pop_label_level ();
  662.           rtl_exp = expand_end_stmt_expr ($<ttype>2);
  663.           /* The statements have side effects, so the group does.  */
  664.           TREE_SIDE_EFFECTS (rtl_exp) = 1;
  665.  
  666.           /* Make a BIND_EXPR for the BLOCK already made.  */
  667.           $$ = build (BIND_EXPR, TREE_TYPE (rtl_exp),
  668.                   NULL_TREE, rtl_exp, $3);
  669.         }
  670.     | primary '(' exprlist ')'   %prec '.'
  671.         { $$ = build_function_call ($1, $3); }
  672.     | primary '[' expr ']'   %prec '.'
  673.         { $$ = build_array_ref ($1, $3); }
  674.     | primary '.' identifier
  675.         {
  676.                   if (doing_objc_thang)
  677.                     {
  678.               if (is_public ($1, $3))
  679.             $$ = build_component_ref ($1, $3);
  680.               else
  681.             $$ = error_mark_node;
  682.             }
  683.                   else
  684.                     $$ = build_component_ref ($1, $3);
  685.         }
  686.     | primary POINTSAT identifier
  687.         {
  688.                   tree anExpr = build_indirect_ref ($1, "->");
  689.  
  690.                   if (doing_objc_thang)
  691.                     {
  692.               if (is_public (anExpr, $3))
  693.             $$ = build_component_ref (anExpr, $3);
  694.               else
  695.             $$ = error_mark_node;
  696.             }
  697.                   else
  698.                     $$ = build_component_ref (anExpr, $3);
  699.         }
  700.     | primary PLUSPLUS
  701.         { $$ = build_unary_op (POSTINCREMENT_EXPR, $1, 0); }
  702.     | primary MINUSMINUS
  703.         { $$ = build_unary_op (POSTDECREMENT_EXPR, $1, 0); }
  704.  
  705.     /* Objective-C extensions */
  706.     | objcmessageexpr
  707.         { $$ = build_message_expr ($1); }
  708.     | objcselectorexpr
  709.         { $$ = build_selector_expr ($1); }
  710.     | objcprotocolexpr
  711.         { $$ = build_protocol_expr ($1); }
  712.     | objcencodeexpr
  713.         { $$ = build_encode_expr ($1); }
  714.     | objc_string
  715.         { $$ = build_objc_string_object ($1); }
  716.     ;
  717.  
  718. /* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it.  */
  719. string:
  720.       STRING
  721.     | string STRING
  722.         { $$ = chainon ($1, $2); }
  723.     ;
  724.  
  725. /* Produces an OBJC_STRING_CST with perhaps more OBJC_STRING_CSTs chained
  726.    onto it.  */
  727. objc_string:
  728.       OBJC_STRING
  729.     | objc_string OBJC_STRING
  730.         { $$ = chainon ($1, $2); }
  731.     ;
  732.  
  733. xdecls:
  734.     /* empty */
  735.     | decls
  736.     | decls ELLIPSIS
  737.         /* ... is used here to indicate a varargs function.  */
  738.         { c_mark_varargs ();
  739.           if (pedantic)
  740.             pedwarn ("ANSI C does not permit use of `varargs.h'"); }
  741.     ;
  742.  
  743. /* This combination which saves a lineno before a decl
  744.    is the normal thing to use, rather than decl itself.
  745.    This is to avoid shift/reduce conflicts in contexts
  746.    where statement labels are allowed.  */
  747. lineno_decl:
  748.       save_filename save_lineno decl
  749.         { }
  750.     ;
  751.  
  752. decls:
  753.     lineno_decl
  754.     | errstmt
  755.     | decls lineno_decl
  756.     | lineno_decl errstmt
  757.     ;
  758.  
  759. /* records the type and storage class specs to use for processing
  760.    the declarators that follow.
  761.    Maintains a stack of outer-level values of current_declspecs,
  762.    for the sake of parm declarations nested in function declarators.  */
  763. setspecs: /* empty */
  764.         { $$ = suspend_momentary ();
  765.           pending_xref_error ();
  766.           declspec_stack = tree_cons (0, current_declspecs,
  767.                           declspec_stack);
  768.           current_declspecs = $<ttype>0; 
  769.                 }
  770.     ;
  771.  
  772. decl:
  773.     typed_declspecs setspecs initdecls ';'
  774.         { current_declspecs = TREE_VALUE (declspec_stack);
  775.           declspec_stack = TREE_CHAIN (declspec_stack);
  776.           resume_momentary ($2); }
  777.     | declmods setspecs notype_initdecls ';'
  778.         { current_declspecs = TREE_VALUE (declspec_stack);
  779.           declspec_stack = TREE_CHAIN (declspec_stack);
  780.           resume_momentary ($2); }
  781.     | typed_declspecs setspecs nested_function
  782.         { current_declspecs = TREE_VALUE (declspec_stack);
  783.           declspec_stack = TREE_CHAIN (declspec_stack);
  784.           resume_momentary ($2); }
  785.     | declmods setspecs notype_nested_function
  786.         { current_declspecs = TREE_VALUE (declspec_stack);
  787.           declspec_stack = TREE_CHAIN (declspec_stack);
  788.           resume_momentary ($2); }
  789.     | typed_declspecs ';'
  790.         { shadow_tag ($1); }
  791.     | declmods ';'
  792.         { pedwarn ("empty declaration"); }
  793.     ;
  794.  
  795. /* Declspecs which contain at least one type specifier or typedef name.
  796.    (Just `const' or `volatile' is not enough.)
  797.    A typedef'd name following these is taken as a name to be declared.  */
  798.  
  799. typed_declspecs:
  800.       typespec reserved_declspecs
  801.         { $$ = tree_cons (NULL_TREE, $1, $2); }
  802.     | declmods typespec reserved_declspecs
  803.         { $$ = chainon ($3, tree_cons (NULL_TREE, $2, $1)); }
  804.     ;
  805.  
  806. reserved_declspecs:  /* empty */
  807.         { $$ = NULL_TREE; }
  808.     | reserved_declspecs typespecqual_reserved
  809.         { $$ = tree_cons (NULL_TREE, $2, $1); }
  810.     | reserved_declspecs SCSPEC
  811.         { $$ = tree_cons (NULL_TREE, $2, $1); }
  812.     ;
  813.  
  814. /* List of just storage classes and type modifiers.
  815.    A declaration can start with just this, but then it cannot be used
  816.    to redeclare a typedef-name.  */
  817.  
  818. declmods:
  819.       TYPE_QUAL
  820.         { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
  821.     | SCSPEC
  822.         { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
  823.     | declmods TYPE_QUAL
  824.         { $$ = tree_cons (NULL_TREE, $2, $1); }
  825.     | declmods SCSPEC
  826.         { $$ = tree_cons (NULL_TREE, $2, $1); }
  827.     ;
  828.  
  829.  
  830. /* Used instead of declspecs where storage classes are not allowed
  831.    (that is, for typenames and structure components).
  832.    Don't accept a typedef-name if anything but a modifier precedes it.  */
  833.  
  834. typed_typespecs:
  835.       typespec reserved_typespecquals
  836.         { $$ = tree_cons (NULL_TREE, $1, $2); }
  837.     | nonempty_type_quals typespec reserved_typespecquals
  838.         { $$ = chainon ($3, tree_cons (NULL_TREE, $2, $1)); }
  839.     ;
  840.  
  841. reserved_typespecquals:  /* empty */
  842.         { $$ = NULL_TREE; }
  843.     | reserved_typespecquals typespecqual_reserved
  844.         { $$ = tree_cons (NULL_TREE, $2, $1); }
  845.     ;
  846.  
  847. /* A typespec (but not a type qualifier).
  848.    Once we have seen one of these in a declaration,
  849.    if a typedef name appears then it is being redeclared.  */
  850.  
  851. typespec: TYPESPEC
  852.     | structsp
  853.     | TYPENAME
  854.         { /* For a typedef name, record the meaning, not the name.
  855.              In case of `foo foo, bar;'.  */
  856.           $$ = lookup_name ($1); }
  857.         | CLASSNAME protocolrefs
  858.         { $$ = get_static_reference ($1, $2); }
  859.     | OBJECTNAME protocolrefs
  860.             { $$ = get_object_reference ($2); }
  861.     | TYPEOF '(' expr ')'
  862.         { $$ = TREE_TYPE ($3);
  863.           if (pedantic)
  864.             pedwarn ("ANSI C forbids `typeof'"); }
  865.     | TYPEOF '(' typename ')'
  866.         { $$ = groktypename ($3);
  867.           if (pedantic)
  868.             pedwarn ("ANSI C forbids `typeof'"); }
  869.     ;
  870.  
  871. /* A typespec that is a reserved word, or a type qualifier.  */
  872.  
  873. typespecqual_reserved: TYPESPEC
  874.     | TYPE_QUAL
  875.     | structsp
  876.     ;
  877.  
  878. initdecls:
  879.     initdcl
  880.     | initdecls ',' initdcl
  881.     ;
  882.  
  883. notype_initdecls:
  884.     notype_initdcl
  885.     | notype_initdecls ',' initdcl
  886.     ;
  887.  
  888. maybeasm:
  889.       /* empty */
  890.         { $$ = NULL_TREE; }
  891.     | ASM '(' string ')'
  892.         { if (TREE_CHAIN ($3)) $3 = combine_strings ($3);
  893.           $$ = $3;
  894.           if (pedantic)
  895.             pedwarn ("ANSI C forbids use of `asm' keyword");
  896.         }
  897.     ;
  898.  
  899. initdcl:
  900.       declarator maybeasm maybe_attribute '='
  901.         { $<ttype>$ = start_decl ($1, current_declspecs, 1); }
  902.       init
  903. /* Note how the declaration of the variable is in effect while its init is parsed! */
  904.         { decl_attributes ($<ttype>5, $3);
  905.           finish_decl ($<ttype>5, $6, $2); }
  906.     | declarator maybeasm maybe_attribute
  907.         { tree d = start_decl ($1, current_declspecs, 0);
  908.           decl_attributes (d, $3);
  909.           finish_decl (d, NULL_TREE, $2); }
  910.     ;
  911.  
  912. notype_initdcl:
  913.       notype_declarator maybeasm maybe_attribute '='
  914.         { $<ttype>$ = start_decl ($1, current_declspecs, 1); }
  915.       init
  916. /* Note how the declaration of the variable is in effect while its init is parsed! */
  917.         { decl_attributes ($<ttype>5, $3);
  918.           finish_decl ($<ttype>5, $6, $2); }
  919.     | notype_declarator maybeasm maybe_attribute
  920.         { tree d = start_decl ($1, current_declspecs, 0);
  921.           decl_attributes (d, $3);
  922.           finish_decl (d, NULL_TREE, $2); }
  923.     ;
  924. /* the * rules are dummies to accept the Apollo extended syntax
  925.    so that the header files compile. */
  926. maybe_attribute:
  927.     /* empty */
  928.         { $$ = NULL_TREE; }
  929.     | ATTRIBUTE '(' '(' attribute_list ')' ')'
  930.         { $$ = $4; }
  931.     ;
  932.  
  933. attribute_list
  934.     : attrib
  935.     { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
  936.     | attribute_list ',' attrib
  937.     { $$ = tree_cons (NULL_TREE, $3, $1); }
  938.     ;
  939.  
  940. attrib
  941.     : IDENTIFIER
  942.     { warning ("`%s' attribute directive ignored",
  943.            IDENTIFIER_POINTER ($1));
  944.       $$ = $1; }
  945.     | IDENTIFIER '(' CONSTANT ')'
  946.     { /* if not "aligned(n)", then issue warning */
  947.       if (strcmp (IDENTIFIER_POINTER ($1), "aligned") != 0
  948.           || TREE_CODE ($3) != INTEGER_CST)
  949.         {
  950.           warning ("`%s' attribute directive ignored",
  951.                IDENTIFIER_POINTER ($1));
  952.           $$ = $1;
  953.         }
  954.       else
  955.         $$ = tree_cons ($1, $3); }
  956.     | IDENTIFIER '(' IDENTIFIER ',' CONSTANT ',' CONSTANT ')'
  957.     { /* if not "format(...)", then issue warning */
  958.       if (strcmp (IDENTIFIER_POINTER ($1), "format") != 0
  959.           || TREE_CODE ($5) != INTEGER_CST
  960.           || TREE_CODE ($7) != INTEGER_CST)
  961.         {
  962.           warning ("`%s' attribute directive ignored",
  963.                IDENTIFIER_POINTER ($1));
  964.           $$ = $1;
  965.         }
  966.       else
  967.         $$ = tree_cons ($1, tree_cons ($3, tree_cons ($5, $7))); }
  968.     ;
  969.  
  970. init:
  971.     expr_no_commas
  972.     | '{' '}'
  973.         { $$ = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE);
  974.           if (pedantic)
  975.             pedwarn ("ANSI C forbids empty initializer braces"); }
  976.     | '{' initlist '}'
  977.         { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); }
  978.     | '{' initlist ',' '}'
  979.         { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); }
  980.     | error
  981.         { $$ = NULL_TREE; }
  982.     ;
  983.  
  984. /* This chain is built in reverse order,
  985.    and put in forward order where initlist is used.  */
  986. initlist:
  987.       init
  988.         { $$ = build_tree_list (NULL_TREE, $1); }
  989.     | initlist ',' init
  990.         { $$ = tree_cons (NULL_TREE, $3, $1); }
  991.     /* These are for labeled elements.  */
  992.     | identifier ':' init
  993.         { $$ = build_tree_list ($1, $3); }
  994.     | initlist ',' identifier ':' init
  995.         { $$ = tree_cons ($3, $5, $1); }
  996.     ;
  997.  
  998. nested_function:
  999.       declarator
  1000.         { push_c_function_context ();
  1001.           if (! start_function (current_declspecs, $1, 1))
  1002.             {
  1003.               pop_c_function_context ();
  1004.               YYERROR1;
  1005.             }
  1006.           reinit_parse_for_function ();
  1007.           store_parm_decls (); }
  1008. /* This used to use compstmt_or_error.
  1009.    That caused a bug with input `f(g) int g {}',
  1010.    where the use of YYERROR1 above caused an error
  1011.    which then was handled by compstmt_or_error.
  1012.    There followed a repeated execution of that same rule,
  1013.    which called YYERROR1 again, and so on.  */
  1014.       compstmt
  1015.         { finish_function (1);
  1016.           pop_c_function_context (); }
  1017.     ;
  1018.  
  1019. notype_nested_function:
  1020.       notype_declarator
  1021.         { push_c_function_context ();
  1022.           if (! start_function (current_declspecs, $1, 1))
  1023.             {
  1024.               pop_c_function_context ();
  1025.               YYERROR1;
  1026.             }
  1027.           reinit_parse_for_function ();
  1028.           store_parm_decls (); }
  1029. /* This used to use compstmt_or_error.
  1030.    That caused a bug with input `f(g) int g {}',
  1031.    where the use of YYERROR1 above caused an error
  1032.    which then was handled by compstmt_or_error.
  1033.    There followed a repeated execution of that same rule,
  1034.    which called YYERROR1 again, and so on.  */
  1035.       compstmt
  1036.         { finish_function (1);
  1037.           pop_c_function_context (); }
  1038.     ;
  1039.  
  1040. /* Any kind of declarator (thus, all declarators allowed
  1041.    after an explicit typespec).  */
  1042.  
  1043. declarator:
  1044.       after_type_declarator
  1045.     | notype_declarator
  1046.     ;
  1047.  
  1048. /* A declarator that is allowed only after an explicit typespec.  */
  1049.  
  1050. after_type_declarator:
  1051.       '(' after_type_declarator ')'
  1052.         { $$ = $2; }
  1053.     | after_type_declarator '(' parmlist_or_identifiers  %prec '.'
  1054.         { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
  1055. /*    | after_type_declarator '(' error ')'  %prec '.'
  1056.         { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
  1057.           poplevel (0, 0, 0); }  */
  1058.     | after_type_declarator '[' expr ']'  %prec '.'
  1059.         { $$ = build_nt (ARRAY_REF, $1, $3); }
  1060.     | after_type_declarator '[' ']'  %prec '.'
  1061.         { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
  1062.     | '*' type_quals after_type_declarator  %prec UNARY
  1063.         { $$ = make_pointer_declarator ($2, $3); }
  1064.     | TYPENAME
  1065.     | OBJECTNAME
  1066.     ;
  1067.  
  1068. /* Kinds of declarator that can appear in a parameter list
  1069.    in addition to notype_declarator.  This is like after_type_declarator
  1070.    but does not allow a typedef name in parentheses as an identifier
  1071.    (because it would conflict with a function with that typedef as arg).  */
  1072.  
  1073. parm_declarator:
  1074.       parm_declarator '(' parmlist_or_identifiers  %prec '.'
  1075.         { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
  1076. /*    | parm_declarator '(' error ')'  %prec '.'
  1077.         { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
  1078.           poplevel (0, 0, 0); }  */
  1079.     | parm_declarator '[' expr ']'  %prec '.'
  1080.         { $$ = build_nt (ARRAY_REF, $1, $3); }
  1081.     | parm_declarator '[' ']'  %prec '.'
  1082.         { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
  1083.     | '*' type_quals parm_declarator  %prec UNARY
  1084.         { $$ = make_pointer_declarator ($2, $3); }
  1085.     | TYPENAME
  1086.     | OBJECTNAME
  1087.     ;
  1088.  
  1089. /* A declarator allowed whether or not there has been
  1090.    an explicit typespec.  These cannot redeclare a typedef-name.  */
  1091.  
  1092. notype_declarator:
  1093.       notype_declarator '(' parmlist_or_identifiers  %prec '.'
  1094.         { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
  1095. /*    | notype_declarator '(' error ')'  %prec '.'
  1096.         { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
  1097.           poplevel (0, 0, 0); }  */
  1098.     | '(' notype_declarator ')'
  1099.         { $$ = $2; }
  1100.     | '*' type_quals notype_declarator  %prec UNARY
  1101.         { $$ = make_pointer_declarator ($2, $3); }
  1102.     | notype_declarator '[' expr ']'  %prec '.'
  1103.         { $$ = build_nt (ARRAY_REF, $1, $3); }
  1104.     | notype_declarator '[' ']'  %prec '.'
  1105.         { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
  1106.     | IDENTIFIER
  1107.     ;
  1108.  
  1109. structsp:
  1110.       STRUCT identifier '{'
  1111.         { $$ = start_struct (RECORD_TYPE, $2);
  1112.           /* Start scope of tag before parsing components.  */
  1113.         }
  1114.       component_decl_list '}'
  1115.         { $$ = finish_struct ($<ttype>4, $5);
  1116.           /* Really define the structure.  */
  1117.         }
  1118.     | STRUCT '{' component_decl_list '}'
  1119.         { $$ = finish_struct (start_struct (RECORD_TYPE, NULL_TREE),
  1120.                       $3); }
  1121.     | STRUCT identifier
  1122.         { $$ = xref_tag (RECORD_TYPE, $2); }
  1123.     | UNION identifier '{'
  1124.         { $$ = start_struct (UNION_TYPE, $2); }
  1125.       component_decl_list '}'
  1126.         { $$ = finish_struct ($<ttype>4, $5); }
  1127.     | UNION '{' component_decl_list '}'
  1128.         { $$ = finish_struct (start_struct (UNION_TYPE, NULL_TREE),
  1129.                       $3); }
  1130.     | UNION identifier
  1131.         { $$ = xref_tag (UNION_TYPE, $2); }
  1132.     | ENUM identifier '{'
  1133.         { $<itype>3 = suspend_momentary ();
  1134.           $$ = start_enum ($2); }
  1135.       enumlist maybecomma_warn '}'
  1136.         { $$ = finish_enum ($<ttype>4, nreverse ($5));
  1137.           resume_momentary ($<itype>3); }
  1138.     | ENUM '{'
  1139.         { $<itype>2 = suspend_momentary ();
  1140.           $$ = start_enum (NULL_TREE); }
  1141.       enumlist maybecomma_warn '}'
  1142.         { $$ = finish_enum ($<ttype>3, nreverse ($4));
  1143.           resume_momentary ($<itype>2); }
  1144.     | ENUM identifier
  1145.         { $$ = xref_tag (ENUMERAL_TYPE, $2); }
  1146.     ;
  1147.  
  1148. maybecomma:
  1149.       /* empty */
  1150.     | ','
  1151.     ;
  1152.  
  1153. maybecomma_warn:
  1154.       /* empty */
  1155.     | ','
  1156.         { if (pedantic) pedwarn ("comma at end of enumerator list"); }
  1157.     ;
  1158.  
  1159. component_decl_list:
  1160.       component_decl_list2
  1161.         { $$ = $1; }
  1162.     | component_decl_list2 component_decl
  1163.         { $$ = chainon ($1, $2);
  1164.           warning ("no semicolon at end of struct or union"); }
  1165.     ;
  1166.  
  1167. component_decl_list2:    /* empty */
  1168.         { $$ = NULL_TREE; }
  1169.     | component_decl_list2 component_decl ';'
  1170.         { $$ = chainon ($1, $2); }
  1171.     | component_decl_list2 ';'
  1172.         { if (pedantic)
  1173.             warning ("extra semicolon in struct or union specified"); }
  1174.     /* foo(sizeof(struct{ @defs(ClassName)})); */
  1175.     | DEFS '(' CLASSNAME ')'
  1176.         {
  1177.           tree interface = lookup_interface ($3);
  1178.  
  1179.           if (interface)
  1180.             $$ = get_class_ivars (interface);
  1181.           else
  1182.             {
  1183.               error ("Cannot find interface declaration for `%s'",
  1184.                  IDENTIFIER_POINTER ($3));
  1185.               $$ = NULL_TREE;
  1186.             }
  1187.         }
  1188.     ;
  1189.  
  1190. /* There is a shift-reduce conflict here, because `components' may
  1191.    start with a `typename'.  It happens that shifting (the default resolution)
  1192.    does the right thing, because it treats the `typename' as part of
  1193.    a `typed_typespecs'.
  1194.  
  1195.    It is possible that this same technique would allow the distinction
  1196.    between `notype_initdecls' and `initdecls' to be eliminated.
  1197.    But I am being cautious and not trying it.  */
  1198.  
  1199. component_decl:
  1200.       typed_typespecs setspecs components
  1201.         { $$ = $3;
  1202.           current_declspecs = TREE_VALUE (declspec_stack);
  1203.           declspec_stack = TREE_CHAIN (declspec_stack);
  1204.           resume_momentary ($2); }
  1205.     | typed_typespecs
  1206.         { if (pedantic)
  1207.             pedwarn ("ANSI C forbids member declarations with no members");
  1208.           shadow_tag($1);
  1209.           $$ = NULL_TREE; }
  1210.     | nonempty_type_quals setspecs components
  1211.         { $$ = $3;
  1212.           current_declspecs = TREE_VALUE (declspec_stack);
  1213.           declspec_stack = TREE_CHAIN (declspec_stack);
  1214.           resume_momentary ($2); }
  1215.     | nonempty_type_quals
  1216.         { if (pedantic)
  1217.             pedwarn ("ANSI C forbids member declarations with no members");
  1218.           shadow_tag($1);
  1219.           $$ = NULL_TREE; }
  1220.     | error
  1221.         { $$ = NULL_TREE; }
  1222.     ;
  1223.  
  1224. components:
  1225.       component_declarator
  1226.     | components ',' component_declarator
  1227.         { $$ = chainon ($1, $3); }
  1228.     ;
  1229.  
  1230. component_declarator:
  1231.       save_filename save_lineno declarator maybe_attribute
  1232.         { $$ = grokfield ($1, $2, $3, current_declspecs, NULL_TREE);
  1233.           decl_attributes ($$, $4); }
  1234.     | save_filename save_lineno
  1235.       declarator ':' expr_no_commas maybe_attribute
  1236.         { $$ = grokfield ($1, $2, $3, current_declspecs, $5);
  1237.           decl_attributes ($$, $6); }
  1238.     | save_filename save_lineno ':' expr_no_commas
  1239.         { $$ = grokfield ($1, $2, NULL_TREE, current_declspecs, $4); }
  1240.     ;
  1241.  
  1242. /* We chain the enumerators in reverse order.
  1243.    They are put in forward order where enumlist is used.
  1244.    (The order used to be significant, but no longer is so.
  1245.    However, we still maintain the order, just to be clean.)  */
  1246.  
  1247. enumlist:
  1248.       enumerator
  1249.     | enumlist ',' enumerator
  1250.         { $$ = chainon ($3, $1); }
  1251.     ;
  1252.  
  1253.  
  1254. enumerator:
  1255.       identifier
  1256.         { $$ = build_enumerator ($1, NULL_TREE); }
  1257.     | identifier '=' expr_no_commas
  1258.         { $$ = build_enumerator ($1, $3); }
  1259.     ;
  1260.  
  1261. typename:
  1262.     typed_typespecs absdcl
  1263.         { $$ = build_tree_list ($1, $2); }
  1264.     | nonempty_type_quals absdcl
  1265.         { $$ = build_tree_list ($1, $2); }
  1266.     ;
  1267.  
  1268. absdcl:   /* an absolute declarator */
  1269.     /* empty */
  1270.         { $$ = NULL_TREE; }
  1271.     | absdcl1
  1272.     ;
  1273.  
  1274. nonempty_type_quals:
  1275.       TYPE_QUAL
  1276.         { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
  1277.     | nonempty_type_quals TYPE_QUAL
  1278.         { $$ = tree_cons (NULL_TREE, $2, $1); }
  1279.     ;
  1280.  
  1281. type_quals:
  1282.       /* empty */
  1283.         { $$ = NULL_TREE; }
  1284.     | type_quals TYPE_QUAL
  1285.         { $$ = tree_cons (NULL_TREE, $2, $1); }
  1286.     ;
  1287.  
  1288. absdcl1:  /* a nonempty absolute declarator */
  1289.       '(' absdcl1 ')'
  1290.         { $$ = $2; }
  1291.       /* `(typedef)1' is `int'.  */
  1292.     | '*' type_quals absdcl1  %prec UNARY
  1293.         { $$ = make_pointer_declarator ($2, $3); }
  1294.     | '*' type_quals  %prec UNARY
  1295.         { $$ = make_pointer_declarator ($2, NULL_TREE); }
  1296.     | absdcl1 '(' parmlist  %prec '.'
  1297.         { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
  1298.     | absdcl1 '[' expr ']'  %prec '.'
  1299.         { $$ = build_nt (ARRAY_REF, $1, $3); }
  1300.     | absdcl1 '[' ']'  %prec '.'
  1301.         { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
  1302.     | '(' parmlist  %prec '.'
  1303.         { $$ = build_nt (CALL_EXPR, NULL_TREE, $2, NULL_TREE); }
  1304.     | '[' expr ']'  %prec '.'
  1305.         { $$ = build_nt (ARRAY_REF, NULL_TREE, $2); }
  1306.     | '[' ']'  %prec '.'
  1307.         { $$ = build_nt (ARRAY_REF, NULL_TREE, NULL_TREE); }
  1308.     ;
  1309.  
  1310. /* at least one statement, the first of which parses without error.  */
  1311. /* stmts is used only after decls, so an invalid first statement
  1312.    is actually regarded as an invalid decl and part of the decls.  */
  1313.  
  1314. stmts:
  1315.     lineno_stmt
  1316.     | stmts lineno_stmt
  1317.     | stmts errstmt
  1318.     ;
  1319.  
  1320. xstmts:
  1321.     /* empty */
  1322.     | stmts
  1323.     ;
  1324.  
  1325. errstmt:  error ';'
  1326.     ;
  1327.  
  1328. pushlevel:  /* empty */
  1329.         { emit_line_note (input_filename, lineno);
  1330.           pushlevel (0);
  1331.           clear_last_expr ();
  1332.           push_momentary ();
  1333.           expand_start_bindings (0);
  1334.           if (objc_method_context)
  1335.             add_objc_decls (); }
  1336.     ;
  1337.  
  1338. /* Read zero or more forward-declarations for labels
  1339.    that nested functions can jump to.  */
  1340. maybe_label_decls:
  1341.       /* empty */
  1342.     | label_decls
  1343.         { if (pedantic)
  1344.             pedwarn ("ANSI C forbids label declarations"); }
  1345.     ;
  1346.  
  1347. label_decls:
  1348.       label_decl
  1349.     | label_decls label_decl
  1350.     ;
  1351.  
  1352. label_decl:
  1353.       LABEL identifiers ';'
  1354.         { tree link;
  1355.           for (link = $2; link; link = TREE_CHAIN (link))
  1356.             {
  1357.               tree label = shadow_label (TREE_VALUE (link));
  1358.               C_DECLARED_LABEL_FLAG (label) = 1;
  1359.               declare_nonlocal_label (label);
  1360.             }
  1361.         }
  1362.     ;
  1363.  
  1364. /* This is the body of a function definition.
  1365.    It causes syntax errors to ignore to the next openbrace.  */
  1366. compstmt_or_error:
  1367.       compstmt
  1368.         {}
  1369.     | error compstmt
  1370.     ;
  1371.  
  1372. compstmt: '{' '}'
  1373.         { $$ = convert (void_type_node, integer_zero_node); }
  1374.     | '{' pushlevel maybe_label_decls decls xstmts '}'
  1375.         { emit_line_note (input_filename, lineno);
  1376.           expand_end_bindings (getdecls (), 1, 0);
  1377.           $$ = poplevel (1, 1, 0);
  1378.           pop_momentary (); }
  1379.     | '{' pushlevel maybe_label_decls error '}'
  1380.         { emit_line_note (input_filename, lineno);
  1381.           expand_end_bindings (getdecls (), kept_level_p (), 0);
  1382.           $$ = poplevel (kept_level_p (), 0, 0);
  1383.           pop_momentary (); }
  1384.     | '{' pushlevel maybe_label_decls stmts '}'
  1385.         { emit_line_note (input_filename, lineno);
  1386.           expand_end_bindings (getdecls (), kept_level_p (), 0);
  1387.           $$ = poplevel (kept_level_p (), 0, 0);
  1388.           pop_momentary (); }
  1389.     ;
  1390.  
  1391. /* Value is number of statements counted as of the closeparen.  */
  1392. simple_if:
  1393.       if_prefix lineno_stmt
  1394. /* Make sure expand_end_cond is run once
  1395.    for each call to expand_start_cond.
  1396.    Otherwise a crash is likely.  */
  1397.     | if_prefix error
  1398.     ;
  1399.  
  1400. if_prefix:
  1401.       IF '(' expr ')'
  1402.         { emit_line_note ($<filename>-1, $<lineno>0);
  1403.           expand_start_cond (truthvalue_conversion ($3), 0);
  1404.           $<itype>1 = stmt_count;
  1405.           if_stmt_file = $<filename>-1;
  1406.           if_stmt_line = $<lineno>0;
  1407.           position_after_white_space (); }
  1408.     ;
  1409.  
  1410. save_filename:
  1411.         { $$ = input_filename; }
  1412.     ;
  1413.  
  1414. save_lineno:
  1415.         { $$ = lineno; }
  1416.     ;
  1417.  
  1418. lineno_stmt:
  1419.       save_filename save_lineno stmt
  1420.         { }
  1421.     ;
  1422.  
  1423. stmt:
  1424.       compstmt
  1425.         { stmt_count++; }
  1426.     | expr ';'
  1427.         { stmt_count++;
  1428.           emit_line_note ($<filename>-1, $<lineno>0);
  1429.           c_expand_expr_stmt ($1);
  1430.           clear_momentary (); }
  1431.     | simple_if ELSE
  1432.         { expand_start_else ();
  1433.           $<itype>1 = stmt_count;
  1434.           position_after_white_space (); }
  1435.       lineno_stmt
  1436.         { expand_end_cond ();
  1437.           if (extra_warnings && stmt_count == $<itype>1)
  1438.             warning ("empty body in an else-statement"); }
  1439.     | simple_if %prec IF
  1440.         { expand_end_cond ();
  1441.           if (extra_warnings && stmt_count == $<itype>1)
  1442.             warning_with_file_and_line (if_stmt_file, if_stmt_line,
  1443.                         "empty body in an if-statement"); }
  1444. /* Make sure expand_end_cond is run once
  1445.    for each call to expand_start_cond.
  1446.    Otherwise a crash is likely.  */
  1447.     | simple_if ELSE error
  1448.         { expand_end_cond (); }
  1449.     | WHILE
  1450.         { emit_nop ();
  1451.           stmt_count++;
  1452.           emit_line_note ($<filename>-1, $<lineno>0);
  1453.           expand_start_loop (1); }
  1454.       '(' expr ')'
  1455.         { emit_line_note (input_filename, lineno);
  1456.           expand_exit_loop_if_false (0, truthvalue_conversion ($4));
  1457.           position_after_white_space (); }
  1458.       lineno_stmt
  1459.         { expand_end_loop (); }
  1460.     | DO
  1461.         { emit_nop ();
  1462.           stmt_count++;
  1463.           emit_line_note ($<filename>-1, $<lineno>0);
  1464.           expand_start_loop_continue_elsewhere (1);
  1465.           position_after_white_space (); }
  1466.       lineno_stmt WHILE
  1467.         { expand_loop_continue_here (); }
  1468.       '(' expr ')' ';'
  1469.         { emit_line_note (input_filename, lineno);
  1470.           expand_exit_loop_if_false (0, truthvalue_conversion ($7));
  1471.           expand_end_loop ();
  1472.           clear_momentary (); }
  1473.     | FOR
  1474.       '(' xexpr ';'
  1475.         { emit_nop ();
  1476.           stmt_count++;
  1477.           emit_line_note ($<filename>-1, $<lineno>0);
  1478.           if ($3) c_expand_expr_stmt ($3);
  1479.           expand_start_loop_continue_elsewhere (1); }
  1480.       xexpr ';'
  1481.         { emit_line_note (input_filename, lineno);
  1482.           if ($6)
  1483.             expand_exit_loop_if_false (0, truthvalue_conversion ($6)); }
  1484.       xexpr ')'
  1485.         /* Don't let the tree nodes for $9 be discarded
  1486.            by clear_momentary during the parsing of the next stmt.  */
  1487.         { push_momentary ();
  1488.           position_after_white_space (); }
  1489.       lineno_stmt
  1490.         { emit_line_note ($<filename>-1, $<lineno>0);
  1491.           expand_loop_continue_here ();
  1492.           if ($9)
  1493.             c_expand_expr_stmt ($9);
  1494.           pop_momentary ();
  1495.           expand_end_loop (); }
  1496.     | SWITCH '(' expr ')'
  1497.         { stmt_count++;
  1498.           emit_line_note ($<filename>-1, $<lineno>0);
  1499.           c_expand_start_case ($3);
  1500.           /* Don't let the tree nodes for $3 be discarded by
  1501.              clear_momentary during the parsing of the next stmt.  */
  1502.           push_momentary ();
  1503.           position_after_white_space (); }
  1504.       lineno_stmt
  1505.         { expand_end_case ($3);
  1506.           pop_momentary (); }
  1507.     | CASE expr ':'
  1508.         { register tree value = check_case_value ($2);
  1509.           register tree label
  1510.             = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
  1511.  
  1512.           stmt_count++;
  1513.  
  1514.           if (value != error_mark_node)
  1515.             {
  1516.               int success = pushcase (value, label);
  1517.               if (success == 1)
  1518.             error ("case label not within a switch statement");
  1519.               else if (success == 2)
  1520.             error ("duplicate case value");
  1521.               else if (success == 3)
  1522.             warning ("case value out of range");
  1523.             }
  1524.           position_after_white_space (); }
  1525.       lineno_stmt
  1526.     | CASE expr ELLIPSIS expr ':'
  1527.         { register tree value1 = check_case_value ($2);
  1528.           register tree value2 = check_case_value ($4);
  1529.           register tree label
  1530.             = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
  1531.  
  1532.           stmt_count++;
  1533.  
  1534.           if (value1 != error_mark_node && value2 != error_mark_node)
  1535.             {
  1536.               int success = pushcase_range (value1, value2, label);
  1537.               if (success == 1)
  1538.             error ("case label not within a switch statement");
  1539.               else if (success == 2)
  1540.             error ("duplicate case value");
  1541.               else if (success == 3)
  1542.             warning ("case value out of range");
  1543.               else if (success == 4)
  1544.             warning ("empty case range");
  1545.             }
  1546.           position_after_white_space (); }
  1547.       lineno_stmt
  1548.     | DEFAULT ':'
  1549.         {
  1550.           register tree label
  1551.             = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
  1552.           int success = pushcase (NULL_TREE, label);
  1553.           stmt_count++;
  1554.           if (success == 1)
  1555.             error ("default label not within a switch statement");
  1556.           else if (success == 2)
  1557.             error ("multiple default labels in one switch");
  1558.           position_after_white_space (); }
  1559.       lineno_stmt
  1560.     | BREAK ';'
  1561.         { stmt_count++;
  1562.           emit_line_note ($<filename>-1, $<lineno>0);
  1563.           if ( ! expand_exit_something ())
  1564.             error ("break statement not within loop or switch"); }
  1565.     | CONTINUE ';'
  1566.         { stmt_count++;
  1567.           emit_line_note ($<filename>-1, $<lineno>0);
  1568.           if (! expand_continue_loop (0))
  1569.             error ("continue statement not within a loop"); }
  1570.     | RETURN ';'
  1571.         { stmt_count++;
  1572.           emit_line_note ($<filename>-1, $<lineno>0);
  1573.           c_expand_return (NULL_TREE); }
  1574.     | RETURN expr ';'
  1575.         { stmt_count++;
  1576.           emit_line_note ($<filename>-1, $<lineno>0);
  1577.           c_expand_return ($2); }
  1578.     | ASM maybe_type_qual '(' string ')' ';'
  1579.         { stmt_count++;
  1580.           emit_line_note ($<filename>-1, $<lineno>0);
  1581.           if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
  1582.           expand_asm ($4); }
  1583.     /* This is the case with just output operands.  */
  1584.     | ASM maybe_type_qual '(' string ':' asm_operands ')' ';'
  1585.         { stmt_count++;
  1586.           emit_line_note ($<filename>-1, $<lineno>0);
  1587.           if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
  1588.           c_expand_asm_operands ($4, $6, NULL_TREE, NULL_TREE,
  1589.                      $2 == ridpointers[(int)RID_VOLATILE],
  1590.                      input_filename, lineno); }
  1591.     /* This is the case with input operands as well.  */
  1592.     | ASM maybe_type_qual '(' string ':' asm_operands ':' asm_operands ')' ';'
  1593.         { stmt_count++;
  1594.           emit_line_note ($<filename>-1, $<lineno>0);
  1595.           if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
  1596.           c_expand_asm_operands ($4, $6, $8, NULL_TREE,
  1597.                      $2 == ridpointers[(int)RID_VOLATILE],
  1598.                      input_filename, lineno); }
  1599.     /* This is the case with clobbered registers as well.  */
  1600.     | ASM maybe_type_qual '(' string ':' asm_operands ':'
  1601.         asm_operands ':' asm_clobbers ')' ';'
  1602.         { stmt_count++;
  1603.           emit_line_note ($<filename>-1, $<lineno>0);
  1604.           if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
  1605.           c_expand_asm_operands ($4, $6, $8, $10,
  1606.                      $2 == ridpointers[(int)RID_VOLATILE],
  1607.                      input_filename, lineno); }
  1608.     | GOTO identifier ';'
  1609.         { tree decl;
  1610.           stmt_count++;
  1611.           emit_line_note ($<filename>-1, $<lineno>0);
  1612.           decl = lookup_label ($2);
  1613.           if (decl != 0)
  1614.             {
  1615.               TREE_USED (decl) = 1;
  1616.               expand_goto (decl);
  1617.             }
  1618.         }
  1619.     | GOTO '*' expr ';'
  1620.         { stmt_count++;
  1621.           emit_line_note ($<filename>-1, $<lineno>0);
  1622.           expand_computed_goto ($3); }
  1623.     | identifier ':'
  1624.         { tree label = define_label (input_filename, lineno, $1);
  1625.           stmt_count++;
  1626.           emit_nop ();
  1627.           if (label)
  1628.             expand_label (label);
  1629.           position_after_white_space (); }
  1630.       lineno_stmt
  1631.     | ';'
  1632.     ;
  1633.  
  1634. /* Either a type-qualifier or nothing.  First thing in an `asm' statement.  */
  1635.  
  1636. maybe_type_qual:
  1637.     /* empty */
  1638.         { if (pedantic)
  1639.             pedwarn ("ANSI C forbids use of `asm' keyword");
  1640.           emit_line_note (input_filename, lineno); }
  1641.     | TYPE_QUAL
  1642.         { if (pedantic)
  1643.             pedwarn ("ANSI C forbids use of `asm' keyword");
  1644.           emit_line_note (input_filename, lineno); }
  1645.     ;
  1646.  
  1647. xexpr:
  1648.     /* empty */
  1649.         { $$ = NULL_TREE; }
  1650.     | expr
  1651.     ;
  1652.  
  1653. /* These are the operands other than the first string and colon
  1654.    in  asm ("addextend %2,%1": "=dm" (x), "0" (y), "g" (*x))  */
  1655. asm_operands: /* empty */
  1656.         { $$ = NULL_TREE; }
  1657.     | nonnull_asm_operands
  1658.     ;
  1659.  
  1660. nonnull_asm_operands:
  1661.       asm_operand
  1662.     | nonnull_asm_operands ',' asm_operand
  1663.         { $$ = chainon ($1, $3); }
  1664.     ;
  1665.  
  1666. asm_operand:
  1667.       STRING '(' expr ')'
  1668.         { $$ = build_tree_list ($1, $3); }
  1669.     ;
  1670.  
  1671. asm_clobbers:
  1672.       string
  1673.         { $$ = tree_cons (NULL_TREE, combine_strings ($1), NULL_TREE); }
  1674.     | asm_clobbers ',' string
  1675.         { $$ = tree_cons (NULL_TREE, combine_strings ($3), $1); }
  1676.     ;
  1677.  
  1678. /* This is what appears inside the parens in a function declarator.
  1679.    Its value is a list of ..._TYPE nodes.  */
  1680. parmlist:
  1681.         { pushlevel (0);
  1682.           declare_parm_level (0); }
  1683.       parmlist_1
  1684.         { $$ = $2;
  1685.           parmlist_tags_warning ();
  1686.           poplevel (0, 0, 0); }
  1687.     ;
  1688.  
  1689. /* This is referred to where either a parmlist or an identifier list is ok.
  1690.    Its value is a list of ..._TYPE nodes or a list of identifiers.  */
  1691. parmlist_or_identifiers:
  1692.         { pushlevel (0);
  1693.           declare_parm_level (1); }
  1694.       parmlist_or_identifiers_1
  1695.         { $$ = $2;
  1696.           parmlist_tags_warning ();
  1697.           poplevel (0, 0, 0); }
  1698.     ;
  1699.  
  1700. parmlist_or_identifiers_1:
  1701.       parmlist_2 ')'
  1702.     | identifiers ')'
  1703.         { $$ = tree_cons (NULL_TREE, NULL_TREE, $1); }
  1704.     | error ')'
  1705.         { $$ = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE); }
  1706.     ;
  1707.  
  1708. parmlist_1:
  1709.       parmlist_2 ')'
  1710.     | error ')'
  1711.         { $$ = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE); }
  1712.     ;
  1713.  
  1714. /* This is what appears inside the parens in a function declarator.
  1715.    Is value is represented in the format that grokdeclarator expects.  */
  1716. parmlist_2:  /* empty */
  1717.         { $$ = get_parm_info (0); }
  1718.     | parms
  1719.         { $$ = get_parm_info (1); }
  1720.     | parms ',' ELLIPSIS
  1721.         { $$ = get_parm_info (0); }
  1722.     ;
  1723.  
  1724. parms:
  1725.     parm
  1726.         { push_parm_decl ($1); }
  1727.     | parms ',' parm
  1728.         { push_parm_decl ($3); }
  1729.     ;
  1730.  
  1731. /* A single parameter declaration or parameter type name,
  1732.    as found in a parmlist.  */
  1733. parm:
  1734.       typed_declspecs parm_declarator
  1735.         { $$ = build_tree_list ($1, $2)    ; }
  1736.     | typed_declspecs notype_declarator
  1737.         { $$ = build_tree_list ($1, $2)    ; }
  1738.     | typed_declspecs absdcl
  1739.         { $$ = build_tree_list ($1, $2); }
  1740.     | declmods notype_declarator
  1741.         { $$ = build_tree_list ($1, $2)    ; }
  1742.     | declmods absdcl
  1743.         { $$ = build_tree_list ($1, $2); }
  1744.     ;
  1745.  
  1746. /* A nonempty list of identifiers.  */
  1747. identifiers:
  1748.     IDENTIFIER
  1749.         { $$ = build_tree_list (NULL_TREE, $1); }
  1750.     | identifiers ',' IDENTIFIER
  1751.         { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
  1752.     ;
  1753.  
  1754. /*
  1755.  *    Objective-C productions.
  1756.  */
  1757. objcdef:
  1758.       classdef
  1759.     | classdecl
  1760.     | aliasdecl
  1761.     | protocoldef
  1762.     | methoddef
  1763.     | END
  1764.         {
  1765.           if (objc_implementation_context)
  1766.                     {
  1767.               finish_class (objc_implementation_context);
  1768.               objc_ivar_chain = NULL_TREE;
  1769.               objc_implementation_context = NULL_TREE;
  1770.             }
  1771.           else
  1772.             warning ("`@end' must appear in an implementation context");
  1773.         }
  1774.     ;
  1775.  
  1776. /* A nonempty list of identifiers.  */
  1777. identifier_list:
  1778.     identifier
  1779.         { $$ = build_tree_list (NULL_TREE, $1); }
  1780.     | identifier_list ',' identifier
  1781.         { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
  1782.     ;
  1783.  
  1784. classdecl:
  1785.       CLASS identifier_list ';'
  1786.         {
  1787.           objc_declare_class ($2);
  1788.         }
  1789.  
  1790. aliasdecl:
  1791.       ALIAS identifier identifier ';'
  1792.         {
  1793.           objc_declare_alias ($2, $3);
  1794.         }
  1795.  
  1796. classdef:
  1797.       INTERFACE identifier protocolrefs '{'
  1798.         {
  1799.           objc_interface_context = objc_ivar_context
  1800.             = start_class (CLASS_INTERFACE, $2, NULL_TREE, $3);
  1801.                   objc_public_flag = 0;
  1802.         }
  1803.       ivar_decl_list '}'
  1804.         {
  1805.                   continue_class (objc_interface_context);
  1806.         }
  1807.       methodprotolist
  1808.       END
  1809.         {
  1810.           finish_class (objc_interface_context);
  1811.           objc_interface_context = NULL_TREE;
  1812.         }
  1813.  
  1814.     | INTERFACE identifier protocolrefs
  1815.         {
  1816.           objc_interface_context
  1817.             = start_class (CLASS_INTERFACE, $2, NULL_TREE, $3);
  1818.                   continue_class (objc_interface_context);
  1819.         }
  1820.       methodprotolist
  1821.       END
  1822.         {
  1823.           finish_class (objc_interface_context);
  1824.           objc_interface_context = NULL_TREE;
  1825.         }
  1826.  
  1827.     | INTERFACE identifier ':' identifier protocolrefs '{'
  1828.         {
  1829.           objc_interface_context = objc_ivar_context
  1830.             = start_class (CLASS_INTERFACE, $2, $4, $5);
  1831.                   objc_public_flag = 0;
  1832.         }
  1833.       ivar_decl_list '}'
  1834.         {
  1835.                   continue_class (objc_interface_context);
  1836.         }
  1837.       methodprotolist
  1838.       END
  1839.         {
  1840.           finish_class (objc_interface_context);
  1841.           objc_interface_context = NULL_TREE;
  1842.         }
  1843.  
  1844.     | INTERFACE identifier ':' identifier protocolrefs
  1845.         {
  1846.           objc_interface_context
  1847.             = start_class (CLASS_INTERFACE, $2, $4, $5);
  1848.                   continue_class (objc_interface_context);
  1849.         }
  1850.       methodprotolist
  1851.       END
  1852.         {
  1853.           finish_class (objc_interface_context);
  1854.           objc_interface_context = NULL_TREE;
  1855.         }
  1856.  
  1857.     | IMPLEMENTATION identifier '{'
  1858.         {
  1859.           objc_implementation_context = objc_ivar_context
  1860.             = start_class (CLASS_IMPLEMENTATION, $2, NULL_TREE, NULL_TREE);
  1861.                   objc_public_flag = 0;
  1862.         }
  1863.       ivar_decl_list '}'
  1864.         {
  1865.                   objc_ivar_chain
  1866.             = continue_class (objc_implementation_context);
  1867.         }
  1868.  
  1869.     | IMPLEMENTATION identifier
  1870.         {
  1871.           objc_implementation_context
  1872.             = start_class (CLASS_IMPLEMENTATION, $2, NULL_TREE, NULL_TREE);
  1873.                   objc_ivar_chain
  1874.             = continue_class (objc_implementation_context);
  1875.         }
  1876.  
  1877.     | IMPLEMENTATION identifier ':' identifier '{'
  1878.         {
  1879.           objc_implementation_context = objc_ivar_context
  1880.             = start_class (CLASS_IMPLEMENTATION, $2, $4, NULL_TREE);
  1881.                   objc_public_flag = 0;
  1882.         }
  1883.       ivar_decl_list '}'
  1884.         {
  1885.                   objc_ivar_chain
  1886.             = continue_class (objc_implementation_context);
  1887.         }
  1888.  
  1889.     | IMPLEMENTATION identifier ':' identifier
  1890.         {
  1891.           objc_implementation_context
  1892.             = start_class (CLASS_IMPLEMENTATION, $2, $4, NULL_TREE);
  1893.                   objc_ivar_chain
  1894.             = continue_class (objc_implementation_context);
  1895.         }
  1896.  
  1897.     | INTERFACE identifier '(' identifier ')' protocolrefs
  1898.         {
  1899.           objc_interface_context
  1900.             = start_class (CATEGORY_INTERFACE, $2, $4, $6);
  1901.                   continue_class (objc_interface_context);
  1902.         }
  1903.       methodprotolist
  1904.       END
  1905.         {
  1906.           finish_class (objc_interface_context);
  1907.           objc_interface_context = NULL_TREE;
  1908.         }
  1909.  
  1910.     | IMPLEMENTATION identifier '(' identifier ')'
  1911.         {
  1912.           objc_implementation_context
  1913.             = start_class (CATEGORY_IMPLEMENTATION, $2, $4, NULL_TREE);
  1914.                   objc_ivar_chain
  1915.             = continue_class (objc_implementation_context);
  1916.         }
  1917.     ;
  1918.  
  1919. protocoldef:
  1920.       PROTOCOL identifier protocolrefs
  1921.         {
  1922.         remember_protocol_qualifiers ();
  1923.         objc_interface_context = 
  1924.             start_protocol(PROTOCOL_INTERFACE, $2, $3);
  1925.         }
  1926.       methodprotolist
  1927.       END
  1928.         {
  1929.         forget_protocol_qualifiers();
  1930.         finish_protocol(objc_interface_context);
  1931.         objc_interface_context = NULL_TREE;
  1932.         }
  1933.     ;
  1934.  
  1935. protocolrefs:
  1936.           /* empty */
  1937.         {
  1938.                   $$ = NULL_TREE;
  1939.                 }
  1940.     | ARITHCOMPARE identifier_list ARITHCOMPARE
  1941.         {
  1942.           if ($1 == LT_EXPR && $3 == GT_EXPR)
  1943.                     $$ = $2;
  1944.           else
  1945.             YYERROR1;
  1946.         }
  1947.     ;
  1948.  
  1949. ivar_decl_list:
  1950.           ivar_decl_list visibility_spec ivar_decls
  1951.         | ivar_decls
  1952.         ;
  1953.  
  1954. visibility_spec:
  1955.       PRIVATE { objc_public_flag = 2; }
  1956.     | PROTECTED { objc_public_flag = 0; }
  1957.     | PUBLIC { objc_public_flag = 1; }
  1958.     ;
  1959.  
  1960. ivar_decls:
  1961.           /* empty */
  1962.         {
  1963.                   $$ = NULL_TREE;
  1964.                 }
  1965.     | ivar_decls ivar_decl ';'
  1966.     | ivar_decls ';'
  1967.         {
  1968.                   if (pedantic)
  1969.             warning ("extra semicolon in struct or union specified");
  1970.                 }
  1971.     ;
  1972.  
  1973.  
  1974. /* There is a shift-reduce conflict here, because `components' may
  1975.    start with a `typename'.  It happens that shifting (the default resolution)
  1976.    does the right thing, because it treats the `typename' as part of
  1977.    a `typed_typespecs'.
  1978.  
  1979.    It is possible that this same technique would allow the distinction
  1980.    between `notype_initdecls' and `initdecls' to be eliminated.
  1981.    But I am being cautious and not trying it.  */
  1982.  
  1983. ivar_decl:
  1984.     typed_typespecs setspecs ivars
  1985.             {
  1986.                   $$ = $3;
  1987.           resume_momentary ($2);
  1988.                 }
  1989.     | nonempty_type_quals setspecs ivars
  1990.         {
  1991.                   $$ = $3;
  1992.           resume_momentary ($2);
  1993.                 }
  1994.     | error
  1995.         { $$ = NULL_TREE; }
  1996.     ;
  1997.  
  1998. ivars:
  1999.       /* empty */
  2000.         { $$ = NULL_TREE; }
  2001.     | ivar_declarator
  2002.     | ivars ',' ivar_declarator
  2003.     ;
  2004.  
  2005. ivar_declarator:
  2006.       declarator
  2007.         {
  2008.           $$ = add_instance_variable (objc_ivar_context,
  2009.                           objc_public_flag,
  2010.                           $1, current_declspecs,
  2011.                           NULL_TREE);
  2012.                 }
  2013.     | declarator ':' expr_no_commas
  2014.         {
  2015.           $$ = add_instance_variable (objc_ivar_context,
  2016.                           objc_public_flag,
  2017.                           $1, current_declspecs, $3);
  2018.                 }
  2019.     | ':' expr_no_commas
  2020.         {
  2021.           $$ = add_instance_variable (objc_ivar_context,
  2022.                           objc_public_flag,
  2023.                           NULL_TREE,
  2024.                           current_declspecs, $2);
  2025.                 }
  2026.     ;
  2027.  
  2028. methoddef:
  2029.       '+'
  2030.         {
  2031.           remember_protocol_qualifiers ();
  2032.           if (objc_implementation_context)
  2033.             objc_inherit_code = CLASS_METHOD_DECL;
  2034.                   else
  2035.             fatal ("method definition not in class context");
  2036.         }
  2037.       methoddecl
  2038.         {
  2039.           forget_protocol_qualifiers ();
  2040.           add_class_method (objc_implementation_context, $3);
  2041.           start_method_def ($3);
  2042.           objc_method_context = $3;
  2043.         }
  2044.       optarglist
  2045.         {
  2046.           continue_method_def ();
  2047.         }
  2048.       compstmt_or_error
  2049.         {
  2050.           finish_method_def ();
  2051.           objc_method_context = NULL_TREE;
  2052.         }
  2053.  
  2054.     | '-'
  2055.         {
  2056.           remember_protocol_qualifiers ();
  2057.           if (objc_implementation_context)
  2058.             objc_inherit_code = INSTANCE_METHOD_DECL;
  2059.                   else
  2060.             fatal ("method definition not in class context");
  2061.         }
  2062.       methoddecl
  2063.         {
  2064.           forget_protocol_qualifiers ();
  2065.           add_instance_method (objc_implementation_context, $3);
  2066.           start_method_def ($3);
  2067.           objc_method_context = $3;
  2068.         }
  2069.       optarglist
  2070.         {
  2071.           continue_method_def ();
  2072.         }
  2073.       compstmt_or_error
  2074.         {
  2075.           finish_method_def ();
  2076.           objc_method_context = NULL_TREE;
  2077.         }
  2078.     ;
  2079.  
  2080. /* the reason for the strange actions in this rule
  2081.  is so that notype_initdecls when reached via datadef
  2082.  can find a valid list of type and sc specs in $0. */
  2083.  
  2084. methodprotolist:
  2085.       /* empty  */
  2086.     | {$<ttype>$ = NULL_TREE; } methodprotolist2
  2087.     ;
  2088.  
  2089. methodprotolist2:         /* eliminates a shift/reduce conflict */
  2090.        methodproto
  2091.     |  datadef
  2092.     | methodprotolist2 methodproto
  2093.     | methodprotolist2 {$<ttype>$ = NULL_TREE; } datadef
  2094.     ;
  2095.  
  2096. semi_or_error:
  2097.       ';'
  2098.     | error
  2099.     ;
  2100.  
  2101. methodproto:
  2102.       '+'
  2103.         {
  2104.           objc_inherit_code = CLASS_METHOD_DECL;
  2105.         }
  2106.       methoddecl
  2107.         {
  2108.           add_class_method (objc_interface_context, $3);
  2109.         }
  2110.       semi_or_error
  2111.  
  2112.     | '-'
  2113.         {
  2114.           objc_inherit_code = INSTANCE_METHOD_DECL;
  2115.         }
  2116.       methoddecl
  2117.         {
  2118.           add_instance_method (objc_interface_context, $3);
  2119.         }
  2120.       semi_or_error
  2121.     ;
  2122.  
  2123. methoddecl:
  2124.       '(' typename ')' unaryselector
  2125.         {
  2126.           $$ = build_method_decl (objc_inherit_code, $2, $4, NULL_TREE);
  2127.         }
  2128.  
  2129.     | unaryselector
  2130.         {
  2131.           $$ = build_method_decl (objc_inherit_code, NULL_TREE, $1, NULL_TREE);
  2132.         }
  2133.  
  2134.     | '(' typename ')' keywordselector optparmlist
  2135.         {
  2136.           $$ = build_method_decl (objc_inherit_code, $2, $4, $5);
  2137.         }
  2138.  
  2139.     | keywordselector optparmlist
  2140.         {
  2141.           $$ = build_method_decl (objc_inherit_code, NULL_TREE, $1, $2);
  2142.         }
  2143.     ;
  2144.  
  2145. /* "optarglist" assumes that start_method_def has already been called...
  2146.    if it is not, the "xdecls" will not be placed in the proper scope */
  2147.  
  2148. optarglist:
  2149.       /* empty */
  2150.     | ';' myxdecls
  2151.     ;
  2152.  
  2153. /* to get around the following situation: "int foo (int a) int b; {}" that
  2154.    is synthesized when parsing "- a:a b:b; id c; id d; { ... }" */
  2155.  
  2156. myxdecls:
  2157.       /* empty */
  2158.     | mydecls
  2159.     ;
  2160.  
  2161. mydecls:
  2162.     mydecl
  2163.     | errstmt
  2164.     | mydecls mydecl
  2165.     | mydecl errstmt
  2166.     ;
  2167.  
  2168. mydecl:
  2169.     typed_declspecs setspecs myparms ';'
  2170.         { resume_momentary ($2); }
  2171.     | typed_declspecs ';'
  2172.         { shadow_tag ($1); }
  2173.     | declmods ';'
  2174.         { warning ("empty declaration"); }
  2175.     ;
  2176.  
  2177. myparms:
  2178.     myparm
  2179.         { push_parm_decl ($1); }
  2180.     | myparms ',' myparm
  2181.         { push_parm_decl ($3); }
  2182.     ;
  2183.  
  2184. /* A single parameter declaration or parameter type name,
  2185.    as found in a parmlist. DOES NOT ALLOW AN INITIALIZER OR ASMSPEC */
  2186.  
  2187. myparm:
  2188.       parm_declarator
  2189.         { $$ = build_tree_list (current_declspecs, $1)    ; }
  2190.     | notype_declarator
  2191.         { $$ = build_tree_list (current_declspecs, $1)    ; }
  2192.     | absdcl
  2193.         { $$ = build_tree_list (current_declspecs, $1)    ; }
  2194.     ;
  2195.  
  2196. optparmlist:
  2197.       /* empty */
  2198.         {
  2199.               $$ = NULL_TREE;
  2200.         }
  2201.     | ',' ELLIPSIS
  2202.         {
  2203.           /* oh what a kludge! */
  2204.           $$ = (tree)1;
  2205.         }
  2206.     | ','
  2207.         {
  2208.           pushlevel (0);
  2209.         }
  2210.       parmlist_2
  2211.         {
  2212.             /* returns a tree list node generated by get_parm_info */
  2213.           $$ = $3;
  2214.           poplevel (0, 0, 0);
  2215.         }
  2216.     ;
  2217.  
  2218. unaryselector:
  2219.       selector
  2220.     ;
  2221.  
  2222. keywordselector:
  2223.       keyworddecl
  2224.  
  2225.     | keywordselector keyworddecl
  2226.         {
  2227.           $$ = chainon ($1, $2);
  2228.         }
  2229.     ;
  2230.  
  2231. selector:
  2232.       IDENTIFIER
  2233.         | TYPENAME
  2234.     | OBJECTNAME
  2235.     | reservedwords
  2236.     ;
  2237.  
  2238. reservedwords:
  2239.       ENUM { $$ = get_identifier (token_buffer); }
  2240.     | STRUCT { $$ = get_identifier (token_buffer); }
  2241.     | UNION { $$ = get_identifier (token_buffer); }
  2242.     | IF { $$ = get_identifier (token_buffer); }
  2243.     | ELSE { $$ = get_identifier (token_buffer); }
  2244.     | WHILE { $$ = get_identifier (token_buffer); }
  2245.     | DO { $$ = get_identifier (token_buffer); }
  2246.     | FOR { $$ = get_identifier (token_buffer); }
  2247.     | SWITCH { $$ = get_identifier (token_buffer); }
  2248.     | CASE { $$ = get_identifier (token_buffer); }
  2249.     | DEFAULT { $$ = get_identifier (token_buffer); }
  2250.     | BREAK { $$ = get_identifier (token_buffer); }
  2251.     | CONTINUE { $$ = get_identifier (token_buffer); }
  2252.     | RETURN  { $$ = get_identifier (token_buffer); }
  2253.     | GOTO { $$ = get_identifier (token_buffer); }
  2254.     | ASM { $$ = get_identifier (token_buffer); }
  2255.         | SIZEOF { $$ = get_identifier (token_buffer); }
  2256.     | TYPEOF { $$ = get_identifier (token_buffer); }
  2257.     | ALIGNOF { $$ = get_identifier (token_buffer); }
  2258.     | TYPESPEC | TYPE_QUAL
  2259.     ;
  2260.  
  2261. keyworddecl:
  2262.       selector ':' '(' typename ')' identifier
  2263.         {
  2264.           $$ = build_keyword_decl ($1, $4, $6);
  2265.         }
  2266.  
  2267.     | selector ':' identifier
  2268.         {
  2269.           $$ = build_keyword_decl ($1, NULL_TREE, $3);
  2270.         }
  2271.  
  2272.     | ':' '(' typename ')' identifier
  2273.         {
  2274.           $$ = build_keyword_decl (NULL_TREE, $3, $5);
  2275.         }
  2276.  
  2277.     | ':' identifier
  2278.         {
  2279.           $$ = build_keyword_decl (NULL_TREE, NULL_TREE, $2);
  2280.         }
  2281.     ;
  2282.  
  2283. messageargs:
  2284.       selector
  2285.         | keywordarglist
  2286.     ;
  2287.  
  2288. keywordarglist:
  2289.       keywordarg
  2290.     | keywordarglist keywordarg
  2291.         {
  2292.           $$ = chainon ($1, $2);
  2293.         }
  2294.     ;
  2295.  
  2296.  
  2297. keywordexpr:
  2298.       nonnull_exprlist
  2299.         {
  2300.           if (TREE_CHAIN ($1) == NULL_TREE)
  2301.             /* just return the expr., remove a level of indirection */
  2302.             $$ = TREE_VALUE ($1);
  2303.                   else
  2304.             /* we have a comma expr., we will collapse later */
  2305.             $$ = $1;
  2306.         }
  2307.     ;
  2308.  
  2309. keywordarg:
  2310.       selector ':' keywordexpr
  2311.         {
  2312.           $$ = build_tree_list ($1, $3);
  2313.         }
  2314.     | ':' keywordexpr
  2315.         {
  2316.           $$ = build_tree_list (NULL_TREE, $2);
  2317.         }
  2318.     ;
  2319.  
  2320. receiver:
  2321.       expr
  2322.     | CLASSNAME
  2323.         {
  2324.           $$ = get_class_reference ($1);
  2325.         }
  2326.     ;
  2327.  
  2328. objcmessageexpr:
  2329.       '['
  2330.         { objc_receiver_context = 1; }
  2331.       receiver
  2332.         { objc_receiver_context = 0; }
  2333.       messageargs ']'
  2334.         {
  2335.           $$ = build_tree_list ($3, $5);
  2336.         }
  2337.     ;
  2338.  
  2339. selectorarg:
  2340.       selector
  2341.         | keywordnamelist
  2342.     ;
  2343.  
  2344. keywordnamelist:
  2345.       keywordname
  2346.     | keywordnamelist keywordname
  2347.         {
  2348.           $$ = chainon ($1, $2);
  2349.         }
  2350.     ;
  2351.  
  2352. keywordname:
  2353.       selector ':'
  2354.         {
  2355.           $$ = build_tree_list ($1, NULL_TREE);
  2356.         }
  2357.     | ':'
  2358.         {
  2359.           $$ = build_tree_list (NULL_TREE, NULL_TREE);
  2360.         }
  2361.     ;
  2362.  
  2363. objcselectorexpr:
  2364.       SELECTOR '(' selectorarg ')'
  2365.         {
  2366.           $$ = $3;
  2367.         }
  2368.     ;
  2369.  
  2370. objcprotocolexpr:
  2371.       PROTOCOL '(' identifier ')'
  2372.         {
  2373.           $$ = $3;
  2374.         }
  2375.     ;
  2376.  
  2377. /* extension to support C-structures in the archiver */
  2378.  
  2379. objcencodeexpr:
  2380.       ENCODE '(' typename ')'
  2381.         {
  2382.           $$ = groktypename ($3);
  2383.         }
  2384.     ;
  2385. %%
  2386.  
  2387. /* Return something to represent absolute declarators containing a *.
  2388.    TARGET is the absolute declarator that the * contains.
  2389.    TYPE_QUALS is a list of modifiers such as const or volatile
  2390.    to apply to the pointer type, represented as identifiers.
  2391.  
  2392.    We return an INDIRECT_REF whose "contents" are TARGET
  2393.    and whose type is the modifier list.  */
  2394.  
  2395. static tree
  2396. make_pointer_declarator (type_quals, target)
  2397.      tree type_quals, target;
  2398. {
  2399.   return build1 (INDIRECT_REF, type_quals, target);
  2400. }
  2401.  
  2402. /* lexical analyzer */
  2403.  
  2404. #ifndef WCHAR_TYPE_SIZE
  2405. #ifdef INT_TYPE_SIZE
  2406. #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
  2407. #else
  2408. #define WCHAR_TYPE_SIZE    BITS_PER_WORD
  2409. #endif
  2410. #endif
  2411.  
  2412. /* Number of bytes in a wide character.  */
  2413. #define WCHAR_BYTES (WCHAR_TYPE_SIZE / BITS_PER_UNIT)
  2414.  
  2415. static int maxtoken;        /* Current nominal length of token buffer.  */
  2416. static char *token_buffer;    /* Pointer to token buffer.
  2417.                    Actual allocated length is maxtoken + 2.  */
  2418.  
  2419. /* Nonzero if end-of-file has been seen on input.  */
  2420. static int end_of_file;
  2421.  
  2422. static int nextchar = -1;
  2423.  
  2424. int check_newline ();
  2425.  
  2426. /* Command-line: gperf -p -j1 -i 1 -g -o -t -N is_reserved_word -k1,3,$ objc.gperf  */ 
  2427. struct resword { char *name; short token; enum rid rid; };
  2428.  
  2429. #define TOTAL_KEYWORDS 70
  2430. #define MIN_WORD_LENGTH 2
  2431. #define MAX_WORD_LENGTH 20
  2432. #define MIN_HASH_VALUE 10
  2433. #define MAX_HASH_VALUE 111
  2434. /* maximum key range = 102, duplicates = 0 */
  2435.  
  2436. #ifdef __GNUC__
  2437. inline
  2438. #endif
  2439. static unsigned int
  2440. hash (str, len)
  2441.      register char *str;
  2442.      register int unsigned len;
  2443. {
  2444.   static unsigned char asso_values[] =
  2445.     {
  2446.      112, 112, 112, 112, 112, 112, 112, 112, 112, 112,
  2447.      112, 112, 112, 112, 112, 112, 112, 112, 112, 112,
  2448.      112, 112, 112, 112, 112, 112, 112, 112, 112, 112,
  2449.      112, 112, 112, 112, 112, 112, 112, 112, 112, 112,
  2450.      112, 112, 112, 112, 112, 112, 112, 112, 112, 112,
  2451.      112, 112, 112, 112, 112, 112, 112, 112, 112, 112,
  2452.      112, 112, 112, 112,   1, 112, 112, 112, 112, 112,
  2453.      112, 112, 112, 112, 112, 112, 112, 112, 112, 112,
  2454.      112, 112, 112, 112, 112, 112, 112, 112, 112, 112,
  2455.      112, 112, 112, 112, 112,   1, 112,  26,   3,  58,
  2456.       42,   5,  56,  34,   2,   5, 112,   1,  12,  40,
  2457.       40,  26,  11, 112,   1,  13,   1,  28,  57,   3,
  2458.      112,   1,   1, 112, 112, 112, 112, 112,
  2459.     };
  2460.   register int hval = len;
  2461.  
  2462.   switch (hval)
  2463.     {
  2464.       default:
  2465.       case 3:
  2466.         hval += asso_values[str[2]];
  2467.       case 2:
  2468.       case 1:
  2469.         hval += asso_values[str[0]];
  2470.     }
  2471.   return hval + asso_values[str[len - 1]];
  2472. }
  2473.  
  2474. static struct resword wordlist[] =
  2475. {
  2476.   {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
  2477.   {"",}, 
  2478.   {"int",  TYPESPEC, RID_INT},
  2479.   {"",}, {"",}, 
  2480.   {"__typeof__",  TYPEOF, NORID},
  2481.   {"break",  BREAK, NORID},
  2482.   {"@private",  PRIVATE, NORID},
  2483.   {"@selector",  SELECTOR, NORID},
  2484.   {"__inline__",  SCSPEC, RID_INLINE},
  2485.   {"while",  WHILE, NORID},
  2486.   {"__inline",  SCSPEC, RID_INLINE},
  2487.   {"__extension__",  EXTENSION, NORID},
  2488.   {"struct",  STRUCT, NORID},
  2489.   {"",}, 
  2490.   {"@protocol",  PROTOCOL, NORID},
  2491.   {"@defs",  DEFS, NORID},
  2492.   {"__signed__",  TYPESPEC, RID_SIGNED},
  2493.   {"switch",  SWITCH, NORID},
  2494.   {"else",  ELSE, NORID},
  2495.   {"inline",  SCSPEC, RID_INLINE},
  2496.   {"",}, {"",}, 
  2497.   {"out",  TYPE_QUAL, RID_OUT},
  2498.   {"@class",  CLASS, NORID},
  2499.   {"",}, {"",}, 
  2500.   {"__asm__",  ASM, NORID},
  2501.   {"",}, 
  2502.   {"inout",  TYPE_QUAL, RID_INOUT},
  2503.   {"oneway",  TYPE_QUAL, RID_ONEWAY},
  2504.   {"__alignof__",  ALIGNOF, NORID},
  2505.   {"",}, 
  2506.   {"__attribute__",  ATTRIBUTE, NORID},
  2507.   {"",}, 
  2508.   {"__attribute",  ATTRIBUTE, NORID},
  2509.   {"register",  SCSPEC, RID_REGISTER},
  2510.   {"short",  TYPESPEC, RID_SHORT},
  2511.   {"",}, 
  2512.   {"in",  TYPE_QUAL, RID_IN},
  2513.   {"return",  RETURN, NORID},
  2514.   {"id",  OBJECTNAME, RID_ID},
  2515.   {"",}, {"",}, 
  2516.   {"extern",  SCSPEC, RID_EXTERN},
  2517.   {"@encode",  ENCODE, NORID},
  2518.   {"@protected",  PROTECTED, NORID},
  2519.   {"",}, 
  2520.   {"@interface",  INTERFACE, NORID},
  2521.   {"auto",  SCSPEC, RID_AUTO},
  2522.   {"",}, {"",}, 
  2523.   {"@compatibility_alias",  ALIAS, NORID},
  2524.   {"for",  FOR, NORID},
  2525.   {"",}, 
  2526.   {"if",  IF, NORID},
  2527.   {"__signed",  TYPESPEC, RID_SIGNED},
  2528.   {"goto",  GOTO, NORID},
  2529.   {"__typeof",  TYPEOF, NORID},
  2530.   {"__const",  TYPE_QUAL, RID_CONST},
  2531.   {"bycopy",  TYPE_QUAL, RID_BYCOPY},
  2532.   {"__const__",  TYPE_QUAL, RID_CONST},
  2533.   {"do",  DO, NORID},
  2534.   {"__volatile__",  TYPE_QUAL, RID_VOLATILE},
  2535.   {"__asm",  ASM, NORID},
  2536.   {"__volatile",  TYPE_QUAL, RID_VOLATILE},
  2537.   {"typeof",  TYPEOF, NORID},
  2538.   {"typedef",  SCSPEC, RID_TYPEDEF},
  2539.   {"sizeof",  SIZEOF, NORID},
  2540.   {"enum",  ENUM, NORID},
  2541.   {"union",  UNION, NORID},
  2542.   {"",}, 
  2543.   {"case",  CASE, NORID},
  2544.   {"double",  TYPESPEC, RID_DOUBLE},
  2545.   {"volatile",  TYPE_QUAL, RID_VOLATILE},
  2546.   {"",}, {"",}, {"",}, {"",}, 
  2547.   {"@end",  END, NORID},
  2548.   {"float",  TYPESPEC, RID_FLOAT},
  2549.   {"char",  TYPESPEC, RID_CHAR},
  2550.   {"long",  TYPESPEC, RID_LONG},
  2551.   {"unsigned",  TYPESPEC, RID_UNSIGNED},
  2552.   {"__alignof",  ALIGNOF, NORID},
  2553.   {"",}, 
  2554.   {"@public",  PUBLIC, NORID},
  2555.   {"signed",  TYPESPEC, RID_SIGNED},
  2556.   {"@implementation",  IMPLEMENTATION, NORID},
  2557.   {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 
  2558.   {"static",  SCSPEC, RID_STATIC},
  2559.   {"const",  TYPE_QUAL, RID_CONST},
  2560.   {"",}, 
  2561.   {"default",  DEFAULT, NORID},
  2562.   {"",}, 
  2563.   {"void",  TYPESPEC, RID_VOID},
  2564.   {"asm",  ASM, NORID},
  2565.   {"",}, 
  2566.   {"continue",  CONTINUE, NORID},
  2567. };
  2568.  
  2569. #ifdef __GNUC__
  2570. inline
  2571. #endif
  2572. struct resword *
  2573. is_reserved_word (str, len)
  2574.      register char *str;
  2575.      register unsigned int len;
  2576. {
  2577.   if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
  2578.     {
  2579.       register int key = hash (str, len);
  2580.  
  2581.       if (key <= MAX_HASH_VALUE && key >= 0)
  2582.         {
  2583.           register char *s = wordlist[key].name;
  2584.  
  2585.           if (*s == *str && !strcmp (str + 1, s + 1))
  2586.             return &wordlist[key];
  2587.         }
  2588.     }
  2589.   return 0;
  2590. }
  2591.  
  2592. static void
  2593. forget_protocol_qualifiers ()
  2594. {
  2595.   int i, n = sizeof wordlist / sizeof (struct resword);
  2596.  
  2597.   for (i = 0; i < n; i++)
  2598.     {
  2599.       if (wordlist[i].rid >= RID_IN && wordlist[i].rid <= RID_ONEWAY)
  2600.         wordlist[i].name = "";
  2601.     }
  2602. }
  2603.  
  2604. static void
  2605. remember_protocol_qualifiers ()
  2606. {
  2607.   int i, n = sizeof wordlist / sizeof (struct resword);
  2608.  
  2609.   for (i = 0; i < n; i++)
  2610.     {
  2611.       if (wordlist[i].rid == RID_IN)
  2612.         wordlist[i].name = "in";
  2613.       else if (wordlist[i].rid == RID_OUT)
  2614.         wordlist[i].name = "out";
  2615.       else if (wordlist[i].rid == RID_INOUT)
  2616.         wordlist[i].name = "inout";
  2617.       else if (wordlist[i].rid == RID_BYCOPY)
  2618.         wordlist[i].name = "bycopy";
  2619.       else if (wordlist[i].rid == RID_ONEWAY)
  2620.         wordlist[i].name = "oneway";   
  2621.     }
  2622. }
  2623.  
  2624. void
  2625. init_lex ()
  2626. {
  2627.   /* Make identifier nodes long enough for the language-specific slots.  */
  2628.   set_identifier_size (sizeof (struct lang_identifier));
  2629.  
  2630.   /* Start it at 0, because check_newline is called at the very beginning
  2631.      and will increment it to 1.  */
  2632.   lineno = 0;
  2633.  
  2634. #ifdef MULTIBYTE_CHARS
  2635.   /* Change to the native locale for multibyte conversions.  */
  2636.   setlocale (LC_CTYPE, "");
  2637. #endif
  2638.  
  2639.   maxtoken = 40;
  2640.   token_buffer = (char *) xmalloc (maxtoken + 2);
  2641.  
  2642.   ridpointers[(int) RID_INT] = get_identifier ("int");
  2643.   ridpointers[(int) RID_CHAR] = get_identifier ("char");
  2644.   ridpointers[(int) RID_VOID] = get_identifier ("void");
  2645.   ridpointers[(int) RID_FLOAT] = get_identifier ("float");
  2646.   ridpointers[(int) RID_DOUBLE] = get_identifier ("double");
  2647.   ridpointers[(int) RID_SHORT] = get_identifier ("short");
  2648.   ridpointers[(int) RID_LONG] = get_identifier ("long");
  2649.   ridpointers[(int) RID_UNSIGNED] = get_identifier ("unsigned");
  2650.   ridpointers[(int) RID_SIGNED] = get_identifier ("signed");
  2651.   ridpointers[(int) RID_INLINE] = get_identifier ("inline");
  2652.   ridpointers[(int) RID_CONST] = get_identifier ("const");
  2653.   ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile");
  2654.   ridpointers[(int) RID_AUTO] = get_identifier ("auto");
  2655.   ridpointers[(int) RID_STATIC] = get_identifier ("static");
  2656.   ridpointers[(int) RID_EXTERN] = get_identifier ("extern");
  2657.   ridpointers[(int) RID_TYPEDEF] = get_identifier ("typedef");
  2658.   ridpointers[(int) RID_REGISTER] = get_identifier ("register");
  2659.  
  2660.   /* protocol additions */
  2661.   ridpointers[(int) RID_ID] = get_identifier ("id");
  2662.   ridpointers[(int) RID_IN] = get_identifier ("in");
  2663.   ridpointers[(int) RID_OUT] = get_identifier ("out");
  2664.   ridpointers[(int) RID_INOUT] = get_identifier ("inout");
  2665.   ridpointers[(int) RID_BYCOPY] = get_identifier ("bycopy");
  2666.   ridpointers[(int) RID_ONEWAY] = get_identifier ("oneway");
  2667.   forget_protocol_qualifiers();
  2668.  
  2669.   /* Some options inhibit certain reserved words.
  2670.      Clear those words out of the hash table so they won't be recognized.  */
  2671. #define UNSET_RESERVED_WORD(STRING) \
  2672.   do { struct resword *s = is_reserved_word (STRING, sizeof (STRING) - 1); \
  2673.        if (s) s->name = ""; } while (0)
  2674.  
  2675.   if (!doing_objc_thang)
  2676.       UNSET_RESERVED_WORD ("id");
  2677.  
  2678.   if (flag_traditional)
  2679.     {
  2680.       UNSET_RESERVED_WORD ("const");
  2681.       UNSET_RESERVED_WORD ("volatile");
  2682.       UNSET_RESERVED_WORD ("typeof");
  2683.       UNSET_RESERVED_WORD ("signed");
  2684.       UNSET_RESERVED_WORD ("inline");
  2685.     }
  2686.   if (flag_no_asm)
  2687.     {
  2688.       UNSET_RESERVED_WORD ("asm");
  2689.       UNSET_RESERVED_WORD ("typeof");
  2690.       UNSET_RESERVED_WORD ("inline");
  2691.     }
  2692. }
  2693.  
  2694. static void
  2695. reinit_parse_for_function ()
  2696. {
  2697. }
  2698.  
  2699. /* If C is not whitespace, return C.
  2700.    Otherwise skip whitespace and return first nonwhite char read.  */
  2701.  
  2702. static int
  2703. skip_white_space (c)
  2704.      register int c;
  2705. {
  2706. #if 0
  2707.   register int inside;
  2708. #endif
  2709.  
  2710.   for (;;)
  2711.     {
  2712.       switch (c)
  2713.     {
  2714.       /* Don't recognize comments in cc1: all comments are removed by cpp,
  2715.          and cpp output can include / and * consecutively as operators.  */
  2716. #if 0
  2717.     case '/':
  2718.       c = getc (finput);
  2719.       if (c != '*')
  2720.         {
  2721.           ungetc (c, finput);
  2722.           return '/';
  2723.         }
  2724.  
  2725.       c = getc (finput);
  2726.  
  2727.       inside = 1;
  2728.       while (inside)
  2729.         {
  2730.           if (c == '*')
  2731.         {
  2732.           while (c == '*')
  2733.             c = getc (finput);
  2734.  
  2735.           if (c == '/')
  2736.             {
  2737.               inside = 0;
  2738.               c = getc (finput);
  2739.             }
  2740.         }
  2741.           else if (c == '\n')
  2742.         {
  2743.           lineno++;
  2744.           c = getc (finput);
  2745.         }
  2746.           else if (c == EOF)
  2747.         {
  2748.           error ("unterminated comment");
  2749.           break;
  2750.         }
  2751.           else
  2752.         c = getc (finput);
  2753.         }
  2754.  
  2755.       break;
  2756. #endif
  2757.  
  2758.     case '\n':
  2759.       c = check_newline ();
  2760.       break;
  2761.  
  2762.     case '\r':
  2763.       if (pedantic)    /* ANSI says no */
  2764.         return (c);
  2765.     case ' ':
  2766.     case '\t':
  2767.     case '\f':
  2768.     case '\v':
  2769.     case '\b':
  2770.       c = getc (finput);
  2771.       break;
  2772.  
  2773.     case '\\':
  2774.       c = getc (finput);
  2775.       if (c == '\n')
  2776.         lineno++;
  2777.       else
  2778.         error ("stray '\\' in program");
  2779.       c = getc (finput);
  2780.       break;
  2781.  
  2782.     default:
  2783.       return (c);
  2784.     }
  2785.     }
  2786. }
  2787.  
  2788. /* Skips all of the white space at the current location in the input file.
  2789.    Must use and reset nextchar if it has the next character.  */
  2790.  
  2791. static void
  2792. position_after_white_space ()
  2793. {
  2794.   register int c;
  2795.  
  2796.   if (nextchar != -1)
  2797.     c = nextchar, nextchar = -1;
  2798.   else
  2799.     c = getc (finput);
  2800.  
  2801.   ungetc (skip_white_space (c), finput);
  2802. }
  2803.  
  2804. /* Make the token buffer longer, preserving the data in it.
  2805.    P should point to just beyond the last valid character in the old buffer.
  2806.    The value we return is a pointer to the new buffer
  2807.    at a place corresponding to P.  */
  2808.  
  2809. static char *
  2810. extend_token_buffer (p)
  2811.      char *p;
  2812. {
  2813.   int offset = p - token_buffer;
  2814.  
  2815.   maxtoken = maxtoken * 2 + 10;
  2816.   token_buffer = (char *) xrealloc (token_buffer, maxtoken + 2);
  2817.  
  2818.   return token_buffer + offset;
  2819. }
  2820.  
  2821. /* At the beginning of a line, increment the line number
  2822.    and process any #-directive on this line.
  2823.    If the line is a #-directive, read the entire line and return a newline.
  2824.    Otherwise, return the line's first non-whitespace character.  */
  2825.  
  2826. int
  2827. check_newline ()
  2828. {
  2829.   register int c;
  2830.   register int token;
  2831.  
  2832.   lineno++;
  2833.  
  2834.   /* Read first nonwhite char on the line.  */
  2835.  
  2836.   c = getc (finput);
  2837.   while (c == ' ' || c == '\t')
  2838.     c = getc (finput);
  2839.  
  2840.   if (c != '#')
  2841.     {
  2842.       /* If not #, return it so caller will use it.  */
  2843.       return c;
  2844.     }
  2845.  
  2846.   /* Read first nonwhite char after the `#'.  */
  2847.  
  2848.   c = getc (finput);
  2849.   while (c == ' ' || c == '\t')
  2850.     c = getc (finput);
  2851.  
  2852.   /* If a letter follows, then if the word here is `line', skip
  2853.      it and ignore it; otherwise, ignore the line, with an error
  2854.      if the word isn't `pragma'.  */
  2855.  
  2856.   if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
  2857.     {
  2858.       if (c == 'p')
  2859.     {
  2860.       if (getc (finput) == 'r'
  2861.           && getc (finput) == 'a'
  2862.           && getc (finput) == 'g'
  2863.           && getc (finput) == 'm'
  2864.           && getc (finput) == 'a'
  2865.           && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n'))
  2866.         {
  2867. #ifdef HANDLE_PRAGMA
  2868.           HANDLE_PRAGMA (finput);
  2869. #endif /* HANDLE_PRAGMA */
  2870.           goto skipline;
  2871.         }
  2872.     }
  2873.  
  2874.       else if (c == 'l')
  2875.     {
  2876.       if (getc (finput) == 'i'
  2877.           && getc (finput) == 'n'
  2878.           && getc (finput) == 'e'
  2879.           && ((c = getc (finput)) == ' ' || c == '\t'))
  2880.         goto linenum;
  2881.     }
  2882.       else if (c == 'i')
  2883.     {
  2884.       if (getc (finput) == 'd'
  2885.           && getc (finput) == 'e'
  2886.           && getc (finput) == 'n'
  2887.           && getc (finput) == 't'
  2888.           && ((c = getc (finput)) == ' ' || c == '\t'))
  2889.         {
  2890.           extern FILE *asm_out_file;
  2891.  
  2892.           if (pedantic)
  2893.         error ("ANSI C does not allow #ident");
  2894.  
  2895.           /* Here we have just seen `#ident '.
  2896.          A string constant should follow.  */
  2897.  
  2898.           while (c == ' ' || c == '\t')
  2899.         c = getc (finput);
  2900.  
  2901.           /* If no argument, ignore the line.  */
  2902.           if (c == '\n')
  2903.         return c;
  2904.  
  2905.           ungetc (c, finput);
  2906.           token = yylex ();
  2907.           if (token != STRING
  2908.           || TREE_CODE (yylval.ttype) != STRING_CST)
  2909.         {
  2910.           error ("invalid #ident");
  2911.           goto skipline;
  2912.         }
  2913.  
  2914. #ifdef ASM_OUTPUT_IDENT
  2915.           ASM_OUTPUT_IDENT (asm_out_file, TREE_STRING_POINTER (yylval.ttype));
  2916. #endif
  2917.  
  2918.           /* Skip the rest of this line.  */
  2919.           goto skipline;
  2920.         }
  2921.     }
  2922.  
  2923.       error ("undefined or invalid # directive");
  2924.       goto skipline;
  2925.     }
  2926.  
  2927. linenum:
  2928.   /* Here we have either `#line' or `# <nonletter>'.
  2929.      In either case, it should be a line number; a digit should follow.  */
  2930.  
  2931.   while (c == ' ' || c == '\t')
  2932.     c = getc (finput);
  2933.  
  2934.   /* If the # is the only nonwhite char on the line,
  2935.      just ignore it.  Check the new newline.  */
  2936.   if (c == '\n')
  2937.     return c;
  2938.  
  2939.   /* Something follows the #; read a token.  */
  2940.  
  2941.   ungetc (c, finput);
  2942.   token = yylex ();
  2943.  
  2944.   if (token == CONSTANT
  2945.       && TREE_CODE (yylval.ttype) == INTEGER_CST)
  2946.     {
  2947.       int old_lineno = lineno;
  2948.       /* subtract one, because it is the following line that
  2949.      gets the specified number */
  2950.  
  2951.       int l = TREE_INT_CST_LOW (yylval.ttype) - 1;
  2952.  
  2953.       /* Is this the last nonwhite stuff on the line?  */
  2954.       c = getc (finput);
  2955.       while (c == ' ' || c == '\t')
  2956.     c = getc (finput);
  2957.       if (c == '\n')
  2958.     {
  2959.       /* No more: store the line number and check following line.  */
  2960.       lineno = l;
  2961.       return c;
  2962.     }
  2963.       ungetc (c, finput);
  2964.  
  2965.       /* More follows: it must be a string constant (filename).  */
  2966.  
  2967.       token = yylex ();
  2968.       if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
  2969.     {
  2970.       error ("invalid #line");
  2971.       goto skipline;
  2972.     }
  2973.  
  2974.       input_filename
  2975.     = (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1);
  2976.       strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype));
  2977.       lineno = l;
  2978.  
  2979.       if (main_input_filename == 0)
  2980.     main_input_filename = input_filename;
  2981.  
  2982.       /* Is this the last nonwhite stuff on the line?  */
  2983.       c = getc (finput);
  2984.       while (c == ' ' || c == '\t')
  2985.     c = getc (finput);
  2986.       if (c == '\n')
  2987.     return c;
  2988.       ungetc (c, finput);
  2989.  
  2990.       token = yylex ();
  2991.  
  2992.       /* `1' after file name means entering new file.
  2993.      `2' after file name means just left a file.  */
  2994.  
  2995.       if (token == CONSTANT
  2996.       && TREE_CODE (yylval.ttype) == INTEGER_CST)
  2997.     {
  2998.       if (TREE_INT_CST_LOW (yylval.ttype) == 1)
  2999.         {
  3000.           struct file_stack *p
  3001.         = (struct file_stack *) xmalloc (sizeof (struct file_stack));
  3002.           input_file_stack->line = old_lineno;
  3003.           p->next = input_file_stack;
  3004.           p->name = input_filename;
  3005.           input_file_stack = p;
  3006.           input_file_stack_tick++;
  3007.         }
  3008.       else if (input_file_stack->next)
  3009.         {
  3010.           struct file_stack *p = input_file_stack;
  3011.           input_file_stack = p->next;
  3012.           free (p);
  3013.           input_file_stack_tick++;
  3014.         }
  3015.       else
  3016.         error ("#-lines for entering and leaving files don't match");
  3017.     }
  3018.     }
  3019.   else
  3020.     error ("invalid #-line");
  3021.  
  3022.   /* skip the rest of this line.  */
  3023.  skipline:
  3024.   if (c == '\n')
  3025.     return c;
  3026.   while ((c = getc (finput)) != EOF && c != '\n');
  3027.   return c;
  3028. }
  3029.  
  3030. #define isalnum(char) ((char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') || (char >= '0' && char <= '9'))
  3031. #define isdigit(char) (char >= '0' && char <= '9')
  3032. #define ENDFILE -1  /* token that represents end-of-file */
  3033.  
  3034.  
  3035. static int
  3036. readescape ()
  3037. {
  3038.   register int c = getc (finput);
  3039.   register int count, code;
  3040.   int firstdig;
  3041.  
  3042.   switch (c)
  3043.     {
  3044.     case 'x':
  3045.       code = 0;
  3046.       count = 0;
  3047.       while (1)
  3048.     {
  3049.       c = getc (finput);
  3050.       if (!(c >= 'a' && c <= 'f')
  3051.           && !(c >= 'A' && c <= 'F')
  3052.           && !(c >= '0' && c <= '9'))
  3053.         {
  3054.           ungetc (c, finput);
  3055.           break;
  3056.         }
  3057.       code *= 16;
  3058.       if (c >= 'a' && c <= 'f')
  3059.         code += c - 'a' + 10;
  3060.       if (c >= 'A' && c <= 'F')
  3061.         code += c - 'A' + 10;
  3062.       if (c >= '0' && c <= '9')
  3063.         code += c - '0';
  3064.       if (count == 0)
  3065.         firstdig = code;
  3066.       count++;
  3067.     }
  3068.       if (count == 0)
  3069.     error ("\\x used with no following hex digits");
  3070.       else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node)
  3071.            || (count > 1
  3072.            && ((1 << (TYPE_PRECISION (integer_type_node) - (count - 1) * 4))
  3073.                <= firstdig)))
  3074.     pedwarn ("hex escape out of range");
  3075.       return code;
  3076.  
  3077.     case '0':  case '1':  case '2':  case '3':  case '4':
  3078.     case '5':  case '6':  case '7':
  3079.       code = 0;
  3080.       count = 0;
  3081.       while ((c <= '7') && (c >= '0') && (count++ < 3))
  3082.     {
  3083.       code = (code * 8) + (c - '0');
  3084.       c = getc (finput);
  3085.     }
  3086.       ungetc (c, finput);
  3087.       return code;
  3088.  
  3089.     case '\\': case '\'': case '"':
  3090.       return c;
  3091.  
  3092.     case '\n':
  3093.       lineno++;
  3094.       return -1;
  3095.  
  3096.     case 'n':
  3097.       return TARGET_NEWLINE;
  3098.  
  3099.     case 't':
  3100.       return TARGET_TAB;
  3101.  
  3102.     case 'r':
  3103.       return TARGET_CR;
  3104.  
  3105.     case 'f':
  3106.       return TARGET_FF;
  3107.  
  3108.     case 'b':
  3109.       return TARGET_BS;
  3110.  
  3111.     case 'a':
  3112.       return TARGET_BELL;
  3113.  
  3114.     case 'v':
  3115.       return TARGET_VT;
  3116.  
  3117.     case 'E':
  3118.       pedwarn ("non-ANSI-standard escape sequence, `\\E'");
  3119.       return 033;
  3120.  
  3121.     case '?':
  3122.       /* `\(', etc, are used at beginning of line to avoid confusing Emacs.  */
  3123.     case '(':
  3124.     case '{':
  3125.     case '[':
  3126.       return c;
  3127.     }
  3128.   if (c >= 040 && c <= 0177)
  3129.     pedwarn ("unknown escape sequence `\\%c'", c);
  3130.   else
  3131.     pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c);
  3132.   return c;
  3133. }
  3134.  
  3135. void
  3136. yyerror (string)
  3137.      char *string;
  3138. {
  3139.   char buf[200];
  3140.  
  3141.   strcpy (buf, string);
  3142.  
  3143.   /* We can't print string and character constants well
  3144.      because the token_buffer contains the result of processing escapes.  */
  3145.   if (end_of_file)
  3146.     strcat (buf, " at end of input");
  3147.   else if (token_buffer[0] == 0)
  3148.     strcat (buf, " at null character");
  3149.   else if (token_buffer[0] == '"')
  3150.     strcat (buf, " before string constant");
  3151.   else if (token_buffer[0] == '\'')
  3152.     strcat (buf, " before character constant");
  3153.   else if (token_buffer[0] < 040 || token_buffer[0] >= 0177)
  3154.     sprintf (buf + strlen (buf), " before character 0%o", token_buffer[0]);
  3155.   else
  3156.     strcat (buf, " before `%s'");
  3157.  
  3158.   error (buf, token_buffer);
  3159. }
  3160.  
  3161. struct try_type
  3162. {
  3163.   tree *node_var;
  3164.   char unsigned_flag;
  3165.   char long_flag;
  3166.   char long_long_flag;
  3167. };
  3168.  
  3169. struct try_type type_sequence[] = 
  3170. {
  3171.   { &integer_type_node, 0, 0, 0},
  3172.   { &unsigned_type_node, 1, 0, 0},
  3173.   { &long_integer_type_node, 0, 1, 0},
  3174.   { &long_unsigned_type_node, 1, 1, 0},
  3175.   { &long_long_integer_type_node, 0, 1, 1},
  3176.   { &long_long_unsigned_type_node, 1, 1, 1}
  3177. };
  3178.  
  3179. static int
  3180. yylex ()
  3181. {
  3182.   register int c;
  3183.   register char *p;
  3184.   register int value;
  3185.   int wide_flag = 0;
  3186.   int objc_flag = 0;
  3187.  
  3188.   if (nextchar >= 0)
  3189.     c = nextchar, nextchar = -1;
  3190.   else
  3191.     c = getc (finput);
  3192.  
  3193.   /* Effectively do c = skip_white_space (c)
  3194.      but do it faster in the usual cases.  */
  3195.   while (1)
  3196.     switch (c)
  3197.       {
  3198.       case '\r':
  3199.     if (pedantic)    /* ANSI says no */
  3200.       goto found_nonwhite;
  3201.       case ' ':
  3202.       case '\t':
  3203.       case '\f':
  3204.       case '\v':
  3205.       case '\b':
  3206.     c = getc (finput);
  3207.     break;
  3208.  
  3209.       case '\n':
  3210.       case '/':
  3211.       case '\\':
  3212.     c = skip_white_space (c);
  3213.       default:
  3214.     goto found_nonwhite;
  3215.       }
  3216.  found_nonwhite:
  3217.  
  3218.   token_buffer[0] = c;
  3219.   token_buffer[1] = 0;
  3220.  
  3221. /*  yylloc.first_line = lineno; */
  3222.  
  3223.   switch (c)
  3224.     {
  3225.     case EOF:
  3226.       end_of_file = 1;
  3227.       token_buffer[0] = 0;
  3228.       value = ENDFILE;
  3229.       break;
  3230.  
  3231.     case '$':
  3232.       if (dollars_in_ident)
  3233.     goto letter;
  3234.       return '$';
  3235.  
  3236.     case 'L':
  3237.       /* Capital L may start a wide-string or wide-character constant.  */
  3238.       {
  3239.     register int c = getc (finput);
  3240.     if (c == '\'')
  3241.       {
  3242.         wide_flag = 1;
  3243.         goto char_constant;
  3244.       }
  3245.     if (c == '"')
  3246.       {
  3247.         wide_flag = 1;
  3248.         goto string_constant;
  3249.       }
  3250.     ungetc (c, finput);
  3251.       }
  3252.  
  3253.     case '@':
  3254.       /* '@' may start a constant string object.  */
  3255.       {
  3256.     register int c = getc (finput);
  3257.     if (c == '"')
  3258.       {
  3259.         objc_flag = 1;
  3260.         goto string_constant;
  3261.       }
  3262.     ungetc (c, finput);
  3263.       }
  3264.  
  3265.     case 'A':  case 'B':  case 'C':  case 'D':  case 'E':
  3266.     case 'F':  case 'G':  case 'H':  case 'I':  case 'J':
  3267.     case 'K':          case 'M':  case 'N':  case 'O':
  3268.     case 'P':  case 'Q':  case 'R':  case 'S':  case 'T':
  3269.     case 'U':  case 'V':  case 'W':  case 'X':  case 'Y':
  3270.     case 'Z':
  3271.     case 'a':  case 'b':  case 'c':  case 'd':  case 'e':
  3272.     case 'f':  case 'g':  case 'h':  case 'i':  case 'j':
  3273.     case 'k':  case 'l':  case 'm':  case 'n':  case 'o':
  3274.     case 'p':  case 'q':  case 'r':  case 's':  case 't':
  3275.     case 'u':  case 'v':  case 'w':  case 'x':  case 'y':
  3276.     case 'z':
  3277.     case '_':
  3278.     letter:
  3279.       p = token_buffer;
  3280.       while (isalnum (c) || c == '_' || c == '$' || c == '@')
  3281.     {
  3282.       if (p >= token_buffer + maxtoken)
  3283.         p = extend_token_buffer (p);
  3284.       if (c == '$' && ! dollars_in_ident)
  3285.         break;
  3286.  
  3287.       *p++ = c;
  3288.       c = getc (finput);
  3289.     }
  3290.  
  3291.       *p = 0;
  3292.       nextchar = c;
  3293.  
  3294.       value = IDENTIFIER;
  3295.       yylval.itype = 0;
  3296.  
  3297.       /* Try to recognize a keyword.  Uses minimum-perfect hash function */
  3298.  
  3299.       {
  3300.     register struct resword *ptr;
  3301.  
  3302.     if (ptr = is_reserved_word (token_buffer, p - token_buffer))
  3303.       {
  3304.         if (ptr->rid)
  3305.           yylval.ttype = ridpointers[(int) ptr->rid];
  3306.         value = (int) ptr->token;
  3307.  
  3308.         /* Only return OBJECTNAME if it is a typedef.  */
  3309.         if (doing_objc_thang && value == OBJECTNAME)
  3310.           {
  3311.         lastiddecl = lookup_name (yylval.ttype);
  3312.  
  3313.         if (lastiddecl == 0 || TREE_CODE (lastiddecl) != TYPE_DECL)
  3314.           value = IDENTIFIER;
  3315.           }
  3316.       }
  3317.       }
  3318.  
  3319.       /* If we did not find a keyword, look for an identifier
  3320.      (or a typename).  */
  3321.  
  3322.       if (value == IDENTIFIER)
  3323.     {
  3324.       if (token_buffer[0] == '@')
  3325.         error ("invalid identifier `%s'", token_buffer);
  3326.           yylval.ttype = get_identifier (token_buffer);
  3327.       lastiddecl = lookup_name (yylval.ttype);
  3328.  
  3329.       if (lastiddecl != 0 && TREE_CODE (lastiddecl) == TYPE_DECL)
  3330.         value = TYPENAME;
  3331.           else if (doing_objc_thang)
  3332.         {
  3333.           tree ident = is_class_name (yylval.ttype);
  3334.           
  3335.           if (ident)
  3336.             {
  3337.               yylval.ttype = ident;
  3338.           value = CLASSNAME;
  3339.         }
  3340.         }
  3341.     }
  3342.  
  3343.       break;
  3344.  
  3345.     case '0':  case '1':  case '2':  case '3':  case '4':
  3346.     case '5':  case '6':  case '7':  case '8':  case '9':
  3347.     case '.':
  3348.       {
  3349.     int base = 10;
  3350.     int count = 0;
  3351.     int largest_digit = 0;
  3352.     int numdigits = 0;
  3353.     /* for multi-precision arithmetic,
  3354.        we store only 8 live bits in each short,
  3355.        giving us 64 bits of reliable precision */
  3356.     short shorts[8];
  3357.     int overflow = 0;
  3358.  
  3359.     enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag
  3360.       = NOT_FLOAT;
  3361.  
  3362.     for (count = 0; count < 8; count++)
  3363.       shorts[count] = 0;
  3364.  
  3365.     p = token_buffer;
  3366.     *p++ = c;
  3367.  
  3368.     if (c == '0')
  3369.       {
  3370.         *p++ = (c = getc (finput));
  3371.         if ((c == 'x') || (c == 'X'))
  3372.           {
  3373.         base = 16;
  3374.         *p++ = (c = getc (finput));
  3375.           }
  3376.         /* Leading 0 forces octal unless the 0 is the only digit.  */
  3377.         else if (c >= '0' && c <= '9')
  3378.           {
  3379.         base = 8;
  3380.         numdigits++;
  3381.           }
  3382.         else
  3383.           numdigits++;
  3384.       }
  3385.  
  3386.     /* Read all the digits-and-decimal-points.  */
  3387.  
  3388.     while (c == '.'
  3389.            || (isalnum (c) && (c != 'l') && (c != 'L')
  3390.            && (c != 'u') && (c != 'U')
  3391.            && (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F')))))
  3392.       {
  3393.         if (c == '.')
  3394.           {
  3395.         if (base == 16)
  3396.           error ("floating constant may not be in radix 16");
  3397.         if (floatflag == AFTER_POINT)
  3398.           {
  3399.             error ("malformed floating constant");
  3400.             floatflag = TOO_MANY_POINTS;
  3401.           }
  3402.         else
  3403.           floatflag = AFTER_POINT;
  3404.  
  3405.         base = 10;
  3406.         *p++ = c = getc (finput);
  3407.         /* Accept '.' as the start of a floating-point number
  3408.            only when it is followed by a digit.
  3409.            Otherwise, unread the following non-digit
  3410.            and use the '.' as a structural token.  */
  3411.         if (p == token_buffer + 2 && !isdigit (c))
  3412.           {
  3413.             if (c == '.')
  3414.               {
  3415.             c = getc (finput);
  3416.             if (c == '.')
  3417.               {
  3418.                 *p++ = c;
  3419.                 *p = 0;
  3420.                 return ELLIPSIS;
  3421.               }
  3422.             error ("parse error at `..'");
  3423.               }
  3424.             ungetc (c, finput);
  3425.             token_buffer[1] = 0;
  3426.             value = '.';
  3427.             goto done;
  3428.           }
  3429.           }
  3430.         else
  3431.           {
  3432.         /* It is not a decimal point.
  3433.            It should be a digit (perhaps a hex digit).  */
  3434.  
  3435.         if (isdigit (c))
  3436.           {
  3437.             c = c - '0';
  3438.           }
  3439.         else if (base <= 10)
  3440.           {
  3441.             if ((c&~040) == 'E')
  3442.               {
  3443.             base = 10;
  3444.             floatflag = AFTER_POINT;
  3445.             break;   /* start of exponent */
  3446.               }
  3447.             error ("nondigits in number and not hexadecimal");
  3448.             c = 0;
  3449.           }
  3450.         else if (c >= 'a')
  3451.           {
  3452.             c = c - 'a' + 10;
  3453.           }
  3454.         else
  3455.           {
  3456.             c = c - 'A' + 10;
  3457.           }
  3458.         if (c >= largest_digit)
  3459.           largest_digit = c;
  3460.         numdigits++;
  3461.  
  3462.         for (count = 0; count < 8; count++)
  3463.           {
  3464.             shorts[count] *= base;
  3465.             if (count)
  3466.               {
  3467.             shorts[count] += (shorts[count-1] >> 8);
  3468.             shorts[count-1] &= (1<<8)-1;
  3469.               }
  3470.             else shorts[0] += c;
  3471.           }
  3472.  
  3473.         if (shorts[7] >= 1<<8
  3474.             || shorts[7] < - (1 << 8))
  3475.           overflow = TRUE;
  3476.  
  3477.         if (p >= token_buffer + maxtoken - 3)
  3478.           p = extend_token_buffer (p);
  3479.         *p++ = (c = getc (finput));
  3480.           }
  3481.       }
  3482.  
  3483.     if (numdigits == 0)
  3484.       error ("numeric constant with no digits");
  3485.  
  3486.     if (largest_digit >= base)
  3487.       error ("numeric constant contains digits beyond the radix");
  3488.  
  3489.     /* Remove terminating char from the token buffer and delimit the string */
  3490.     *--p = 0;
  3491.  
  3492.     if (floatflag != NOT_FLOAT)
  3493.       {
  3494.         tree type = double_type_node;
  3495.         char f_seen = 0;
  3496.         char l_seen = 0;
  3497.         REAL_VALUE_TYPE value;
  3498.         jmp_buf handler;
  3499.  
  3500.         /* Read explicit exponent if any, and put it in tokenbuf.  */
  3501.  
  3502.         if ((c == 'e') || (c == 'E'))
  3503.           {
  3504.         if (p >= token_buffer + maxtoken - 3)
  3505.           p = extend_token_buffer (p);
  3506.         *p++ = c;
  3507.         c = getc (finput);
  3508.         if ((c == '+') || (c == '-'))
  3509.           {
  3510.             *p++ = c;
  3511.             c = getc (finput);
  3512.           }
  3513.         if (! isdigit (c))
  3514.           error ("floating constant exponent has no digits");
  3515.             while (isdigit (c))
  3516.           {
  3517.             if (p >= token_buffer + maxtoken - 3)
  3518.               p = extend_token_buffer (p);
  3519.             *p++ = c;
  3520.             c = getc (finput);
  3521.           }
  3522.           }
  3523.  
  3524.         *p = 0;
  3525.         errno = 0;
  3526.  
  3527.         /* Convert string to a double, checking for overflow.  */
  3528.         if (setjmp (handler))
  3529.           {
  3530.         error ("floating constant out of range");
  3531.         value = dconst0;
  3532.           }
  3533.         else
  3534.           {
  3535.         set_float_handler (handler);
  3536.         value = REAL_VALUE_ATOF (token_buffer);
  3537.         set_float_handler (0);
  3538.           }
  3539. #ifdef ERANGE
  3540.         if (errno == ERANGE && !flag_traditional)
  3541.           {
  3542.         char *p1 = token_buffer;
  3543.         /* Check for "0.0" and variants;
  3544.            Sunos 4 spuriously returns ERANGE for them.  */
  3545.         while (*p1 == '0') p1++;
  3546.         if (*p1 == '.')
  3547.           {
  3548.             p1++;
  3549.             while (*p1 == '0') p1++;
  3550.           }
  3551.         if (*p1 == 'e' || *p1 == 'E')
  3552.           {
  3553.             /* with significand==0, ignore the exponent */
  3554.             p1++;
  3555.             while (*p1 != 0) p1++;
  3556.           }
  3557.         /* ERANGE is also reported for underflow,
  3558.            so test the value to distinguish overflow from that.  */
  3559.         if (*p1 != 0 && (value > 1.0 || value < -1.0))
  3560.           warning ("floating point number exceeds range of `double'");
  3561.           }
  3562. #endif
  3563.  
  3564.         /* Read the suffixes to choose a data type.  */
  3565.         while (1)
  3566.           {
  3567.         if (c == 'f' || c == 'F')
  3568.           {
  3569.             if (f_seen)
  3570.               error ("two `f's in floating constant");
  3571.             f_seen = 1;
  3572.             type = float_type_node;
  3573.             value = REAL_VALUE_TRUNCATE (value);
  3574.           }
  3575.         else if (c == 'l' || c == 'L')
  3576.           {
  3577.             if (l_seen)
  3578.               error ("two `l's in floating constant");
  3579.             l_seen = 1;
  3580.             type = long_double_type_node;
  3581.           }
  3582.         else
  3583.           {
  3584.             if (isalnum (c))
  3585.               {
  3586.             error ("garbage at end of number");
  3587.             while (isalnum (c))
  3588.               {
  3589.                 if (p >= token_buffer + maxtoken - 3)
  3590.                   p = extend_token_buffer (p);
  3591.                 *p++ = c;
  3592.                 c = getc (finput);
  3593.               }
  3594.               }
  3595.             break;
  3596.           }
  3597.         if (p >= token_buffer + maxtoken - 3)
  3598.           p = extend_token_buffer (p);
  3599.         *p++ = c;
  3600.         c = getc (finput);
  3601.           }
  3602.  
  3603.         /* Create a node with determined type and value.  */
  3604.         yylval.ttype = build_real (type, value);
  3605.  
  3606.         ungetc (c, finput);
  3607.         *p = 0;
  3608.       }
  3609.     else
  3610.       {
  3611.         tree type;
  3612.         int spec_unsigned = 0;
  3613.         int spec_long = 0;
  3614.         int spec_long_long = 0;
  3615.  
  3616.         while (1)
  3617.           {
  3618.         if (c == 'u' || c == 'U')
  3619.           {
  3620.             if (spec_unsigned)
  3621.               error ("two `u's in integer constant");
  3622.             spec_unsigned = 1;
  3623.           }
  3624.         else if (c == 'l' || c == 'L')
  3625.           {
  3626.             if (spec_long)
  3627.               {
  3628.             if (spec_long_long)
  3629.               error ("three `l's in integer constant");
  3630.             else if (pedantic)
  3631.               pedwarn ("ANSI C forbids long long integer constants");
  3632.             spec_long_long = 1;
  3633.               }
  3634.             spec_long = 1;
  3635.           }
  3636.         else
  3637.           {
  3638.             if (isalnum (c))
  3639.               {
  3640.             error ("garbage at end of number");
  3641.             while (isalnum (c))
  3642.               {
  3643.                 if (p >= token_buffer + maxtoken - 3)
  3644.                   p = extend_token_buffer (p);
  3645.                 *p++ = c;
  3646.                 c = getc (finput);
  3647.               }
  3648.               }
  3649.             break;
  3650.           }
  3651.         if (p >= token_buffer + maxtoken - 3)
  3652.           p = extend_token_buffer (p);
  3653.         *p++ = c;
  3654.         c = getc (finput);
  3655.           }
  3656.  
  3657.         ungetc (c, finput);
  3658.  
  3659.         if ((overflow || shorts[7] || shorts[6] || shorts[5] || shorts[4])
  3660.         && !spec_long_long)
  3661.           warning ("integer constant out of range");
  3662.  
  3663.         /* If it won't fit in a signed long long, make it unsigned.
  3664.            We can't distinguish based on the tree node because
  3665.            any integer constant fits any long long type.  */
  3666.         if (shorts[7] >= (1<<8))
  3667.           spec_unsigned = 1;
  3668.  
  3669.         /* This is simplified by the fact that our constant
  3670.            is always positive.  */
  3671.         yylval.ttype
  3672.           = (build_int_2
  3673.          ((shorts[3]<<24) + (shorts[2]<<16) + (shorts[1]<<8) + shorts[0],
  3674.           (spec_long_long
  3675.            ? (shorts[7]<<24) + (shorts[6]<<16) + (shorts[5]<<8) + shorts[4]
  3676.            : 0)));
  3677.  
  3678. #if 0
  3679.         /* Find the first allowable type that the value fits in.  */
  3680.         type = 0;
  3681.         for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]);
  3682.          i++)
  3683.           if (!(spec_long && !type_sequence[i].long_flag)
  3684.           && !(spec_long_long && !type_sequence[i].long_long_flag)
  3685.           && !(spec_unsigned && !type_sequence[i].unsigned_flag)
  3686.           /* A decimal constant can't be unsigned int
  3687.              unless explicitly specified.  */
  3688.           && !(base == 10 && !spec_unsigned
  3689.                && *type_sequence[i].node_var == unsigned_type_node))
  3690.         if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var))
  3691.           {
  3692.             type = *type_sequence[i].node_var;
  3693.             break;
  3694.           }
  3695.         if (flag_traditional && type == long_unsigned_type_node
  3696.         && !spec_unsigned)
  3697.           type = long_integer_type_node;
  3698.           
  3699.         if (type == 0)
  3700.           {
  3701.         type = long_long_integer_type_node;
  3702.         warning ("integer constant out of range");
  3703.           }
  3704.  
  3705.         /* Warn about some cases where the type of a given constant
  3706.            changes from traditional C to ANSI C.  */
  3707.         if (warn_traditional)
  3708.           {
  3709.         tree other_type = 0;
  3710.  
  3711.         /* This computation is the same as the previous one
  3712.            except that flag_traditional is used backwards.  */
  3713.         for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]);
  3714.              i++)
  3715.           if (!(spec_long && !type_sequence[i].long_flag)
  3716.               && !(spec_long_long && !type_sequence[i].long_long_flag)
  3717.               && !(spec_unsigned && !type_sequence[i].unsigned_flag)
  3718.               /* A decimal constant can't be unsigned int
  3719.              unless explicitly specified.  */
  3720.               && !(base == 10 && !spec_unsigned
  3721.                && *type_sequence[i].node_var == unsigned_type_node))
  3722.             if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var))
  3723.               {
  3724.             other_type = *type_sequence[i].node_var;
  3725.             break;
  3726.               }
  3727.         if (!flag_traditional && type == long_unsigned_type_node
  3728.             && !spec_unsigned)
  3729.           type = long_integer_type_node;
  3730.           
  3731.         if (other_type != 0 && other_type != type)
  3732.           {
  3733.             if (flag_traditional)
  3734.               warning ("type of integer constant would be different without -traditional");
  3735.             else
  3736.               warning ("type of integer constant would be different with -traditional");
  3737.           }
  3738.           }
  3739.  
  3740. #else /* 1 */
  3741.         if (!spec_long && !spec_unsigned
  3742.         && !(flag_traditional && base != 10)
  3743.         && int_fits_type_p (yylval.ttype, integer_type_node))
  3744.           {
  3745.         if (warn_traditional && base != 10)
  3746.           warning ("small nondecimal constant becomes signed in ANSI C");
  3747.         type = integer_type_node;
  3748.           }
  3749.         else if (!spec_long && (base != 10 || spec_unsigned)
  3750.              && int_fits_type_p (yylval.ttype, unsigned_type_node))
  3751.           {
  3752.         /* Nondecimal constants try unsigned even in traditional C.  */
  3753.         type = unsigned_type_node;
  3754.           }
  3755.  
  3756.         else if (!spec_unsigned && !spec_long_long
  3757.              && int_fits_type_p (yylval.ttype, long_integer_type_node))
  3758.           type = long_integer_type_node;
  3759.  
  3760.         else if (! spec_long_long
  3761.              && int_fits_type_p (yylval.ttype,
  3762.                      long_unsigned_type_node))
  3763.           {
  3764.         if (warn_traditional && !spec_unsigned)
  3765.           warning ("large integer constant becomes unsigned in ANSI C");
  3766.         if (flag_traditional && !spec_unsigned)
  3767.           type = long_integer_type_node;
  3768.         else
  3769.           type = long_unsigned_type_node;
  3770.           }
  3771.  
  3772.         else if (! spec_unsigned
  3773.              && int_fits_type_p (yylval.ttype,
  3774.                      long_long_integer_type_node))
  3775.           type = long_long_integer_type_node;
  3776.  
  3777.         else if (int_fits_type_p (yylval.ttype,
  3778.                       long_long_unsigned_type_node))
  3779.           {
  3780.         if (warn_traditional && !spec_unsigned)
  3781.           warning ("large nondecimal constant is unsigned in ANSI C");
  3782.         if (flag_traditional && !spec_unsigned)
  3783.           type = long_long_integer_type_node;
  3784.         else
  3785.           type = long_long_unsigned_type_node;
  3786.           }
  3787.  
  3788.         else
  3789.           {
  3790.         type = long_long_integer_type_node;
  3791.         warning ("integer constant out of range");
  3792.           }
  3793. #endif
  3794.  
  3795.         TREE_TYPE (yylval.ttype) = type;
  3796.         *p = 0;
  3797.       }
  3798.  
  3799.     value = CONSTANT; break;
  3800.       }
  3801.  
  3802.     case '\'':
  3803.     char_constant:
  3804.       {
  3805.     register int result = 0;
  3806.     register num_chars = 0;
  3807.     int width = TYPE_PRECISION (char_type_node);
  3808.     int max_chars;
  3809.  
  3810.     if (wide_flag)
  3811.       {
  3812.         width = WCHAR_TYPE_SIZE;
  3813. #ifdef MULTIBYTE_CHARS
  3814.         max_chars = MB_CUR_MAX;
  3815. #else
  3816.         max_chars = 1;
  3817. #endif
  3818.       }
  3819.     else
  3820.       max_chars = TYPE_PRECISION (integer_type_node) / width;
  3821.  
  3822.     while (1)
  3823.       {
  3824.       tryagain:
  3825.  
  3826.         c = getc (finput);
  3827.  
  3828.         if (c == '\'' || c == EOF)
  3829.           break;
  3830.  
  3831.         if (c == '\\')
  3832.           {
  3833.         c = readescape ();
  3834.         if (c < 0)
  3835.           goto tryagain;
  3836.         if (width < HOST_BITS_PER_INT
  3837.             && (unsigned) c >= (1 << width))
  3838.           pedwarn ("escape sequence out of range for character");
  3839.           }
  3840.         else if (c == '\n')
  3841.           {
  3842.         if (pedantic)
  3843.           pedwarn ("ANSI C forbids newline in character constant");
  3844.         lineno++;
  3845.           }
  3846.  
  3847.         num_chars++;
  3848.         if (num_chars > maxtoken - 4)
  3849.           extend_token_buffer (token_buffer);
  3850.  
  3851.         token_buffer[num_chars] = c;
  3852.  
  3853.         /* Merge character into result; ignore excess chars.  */
  3854.         if (num_chars < max_chars + 1)
  3855.           {
  3856.         if (width < HOST_BITS_PER_INT)
  3857.           result = (result << width) | (c & ((1 << width) - 1));
  3858.         else
  3859.           result = c;
  3860.           }
  3861.       }
  3862.  
  3863.     token_buffer[num_chars + 1] = '\'';
  3864.     token_buffer[num_chars + 2] = 0;
  3865.  
  3866.     if (c != '\'')
  3867.       error ("malformatted character constant");
  3868.     else if (num_chars == 0)
  3869.       error ("empty character constant");
  3870.     else if (num_chars > max_chars)
  3871.       {
  3872.         num_chars = max_chars;
  3873.         error ("character constant too long");
  3874.       }
  3875.     else if (num_chars != 1 && ! flag_traditional)
  3876.       warning ("multi-character character constant");
  3877.  
  3878.     /* If char type is signed, sign-extend the constant.  */
  3879.     if (! wide_flag)
  3880.       {
  3881.         int num_bits = num_chars * width;
  3882.         if (TREE_UNSIGNED (char_type_node)
  3883.         || ((result >> (num_bits - 1)) & 1) == 0)
  3884.           yylval.ttype
  3885.         = build_int_2 (result & ((unsigned) ~0
  3886.                      >> (HOST_BITS_PER_INT - num_bits)),
  3887.                    0);
  3888.         else
  3889.           yylval.ttype
  3890.         = build_int_2 (result | ~((unsigned) ~0
  3891.                       >> (HOST_BITS_PER_INT - num_bits)),
  3892.                    -1);
  3893.       }
  3894.     else
  3895.       {
  3896. #ifdef MULTIBYTE_CHARS
  3897.         /* Set the initial shift state and convert the next sequence.  */
  3898.         result = 0;
  3899.         if (num_chars)
  3900.           {
  3901.         wchar_t wc;
  3902.         (void) mbtowc (NULL, NULL, 0);
  3903.         if (mbtowc (& wc, token_buffer + 1, num_chars) == num_chars)
  3904.           result = wc;
  3905.         else
  3906.           warning ("Ignoring invalide multibyte character");
  3907.           }
  3908. #endif
  3909.         yylval.ttype = build_int_2 (result, 0);
  3910.       }
  3911.  
  3912.     TREE_TYPE (yylval.ttype) = integer_type_node;
  3913.     value = CONSTANT; break;
  3914.       }
  3915.  
  3916.     case '"':
  3917.     string_constant:
  3918.       {
  3919.     c = getc (finput);
  3920.     p = token_buffer + 1;
  3921.  
  3922.     while (c != '"' && c >= 0)
  3923.       {
  3924.         if (c == '\\')
  3925.           {
  3926.         c = readescape ();
  3927.         if (c < 0)
  3928.           goto skipnewline;
  3929.         if (!wide_flag && c >= (1 << TYPE_PRECISION (char_type_node)))
  3930.           pedwarn ("escape sequence out of range for character");
  3931.           }
  3932.         else if (c == '\n')
  3933.           {
  3934.         if (pedantic)
  3935.           pedwarn ("ANSI C forbids newline in string constant");
  3936.         lineno++;
  3937.           }
  3938.  
  3939.         if (p == token_buffer + maxtoken)
  3940.           p = extend_token_buffer (p);
  3941.         *p++ = c;
  3942.  
  3943.       skipnewline:
  3944.         c = getc (finput);
  3945.       }
  3946.     *p = 0;
  3947.  
  3948.     /* We have read the entire constant.
  3949.        Construct a STRING_CST for the result.  */
  3950.  
  3951.     if (wide_flag)
  3952.       {
  3953.         /* If this is a L"..." wide-string, convert the multibyte string
  3954.            to a wide character string.  */
  3955.         char *widep = (char *) alloca ((p - token_buffer) * WCHAR_BYTES);
  3956.         int len;
  3957.  
  3958. #ifdef MULTIBYTE_CHARS
  3959.         len = mbstowcs ((wchar_t *) widep, token_buffer + 1, p - token_buffer);
  3960.         if ((unsigned) len >= (p - token_buffer))
  3961.           {
  3962.         warning ("Ignoring invalid multibyte string");
  3963.         len = 0;
  3964.           }
  3965.         bzero (widep + (len * WCHAR_BYTES), WCHAR_BYTES);
  3966. #else
  3967.         {
  3968.           union { long l; char c[sizeof (long)]; } u;
  3969.           int big_endian;
  3970.           char *wp, *cp;
  3971.  
  3972.           /* Determine whether host is little or big endian.  */
  3973.           u.l = 1;
  3974.           big_endian = u.c[sizeof (long) - 1];
  3975.           wp = widep + (big_endian ? WCHAR_BYTES - 1 : 0);
  3976.  
  3977.           bzero (widep, (p - token_buffer) * WCHAR_BYTES);
  3978.           for (cp = token_buffer + 1; cp < p; cp++)
  3979.         *wp = *cp, wp += WCHAR_BYTES;
  3980.           len = p - token_buffer - 1;
  3981.         }
  3982. #endif
  3983.         yylval.ttype = build_string ((len + 1) * WCHAR_BYTES, widep);
  3984.         TREE_TYPE (yylval.ttype) = wchar_array_type_node;
  3985.         value = STRING;
  3986.       }
  3987.     else if (objc_flag)
  3988.       {
  3989.         /* Return an Objective-C @"..." constant string object.  */
  3990.         yylval.ttype = build_objc_string (p - token_buffer,
  3991.                           token_buffer + 1);
  3992.         value = OBJC_STRING;
  3993.       }
  3994.     else
  3995.       {
  3996.         yylval.ttype = build_string (p - token_buffer, token_buffer + 1);
  3997.         TREE_TYPE (yylval.ttype) = char_array_type_node;
  3998.         value = STRING;
  3999.       }
  4000.  
  4001.     *p++ = '"';
  4002.     *p = 0;
  4003.  
  4004.     break;
  4005.       }
  4006.  
  4007.     case '+':
  4008.     case '-':
  4009.     case '&':
  4010.     case '|':
  4011.     case '<':
  4012.     case '>':
  4013.     case '*':
  4014.     case '/':
  4015.     case '%':
  4016.     case '^':
  4017.     case '!':
  4018.     case '=':
  4019.       {
  4020.     register int c1;
  4021.  
  4022.       combine:
  4023.  
  4024.     switch (c)
  4025.       {
  4026.       case '+':
  4027.         yylval.code = PLUS_EXPR; break;
  4028.       case '-':
  4029.         yylval.code = MINUS_EXPR; break;
  4030.       case '&':
  4031.         yylval.code = BIT_AND_EXPR; break;
  4032.       case '|':
  4033.         yylval.code = BIT_IOR_EXPR; break;
  4034.       case '*':
  4035.         yylval.code = MULT_EXPR; break;
  4036.       case '/':
  4037.         yylval.code = TRUNC_DIV_EXPR; break;
  4038.       case '%':
  4039.         yylval.code = TRUNC_MOD_EXPR; break;
  4040.       case '^':
  4041.         yylval.code = BIT_XOR_EXPR; break;
  4042.       case LSHIFT:
  4043.         yylval.code = LSHIFT_EXPR; break;
  4044.       case RSHIFT:
  4045.         yylval.code = RSHIFT_EXPR; break;
  4046.       case '<':
  4047.         yylval.code = LT_EXPR; break;
  4048.       case '>':
  4049.         yylval.code = GT_EXPR; break;
  4050.       }
  4051.  
  4052.     token_buffer[1] = c1 = getc (finput);
  4053.     token_buffer[2] = 0;
  4054.  
  4055.     if (c1 == '=')
  4056.       {
  4057.         switch (c)
  4058.           {
  4059.           case '<':
  4060.         value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done;
  4061.           case '>':
  4062.         value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done;
  4063.           case '!':
  4064.         value = EQCOMPARE; yylval.code = NE_EXPR; goto done;
  4065.           case '=':
  4066.         value = EQCOMPARE; yylval.code = EQ_EXPR; goto done;
  4067.           }
  4068.         value = ASSIGN; goto done;
  4069.       }
  4070.     else if (c == c1)
  4071.       switch (c)
  4072.         {
  4073.         case '+':
  4074.           value = PLUSPLUS; goto done;
  4075.         case '-':
  4076.           value = MINUSMINUS; goto done;
  4077.         case '&':
  4078.           value = ANDAND; goto done;
  4079.         case '|':
  4080.           value = OROR; goto done;
  4081.         case '<':
  4082.           c = LSHIFT;
  4083.           goto combine;
  4084.         case '>':
  4085.           c = RSHIFT;
  4086.           goto combine;
  4087.         }
  4088.     else if ((c == '-') && (c1 == '>'))
  4089.       { value = POINTSAT; goto done; }
  4090.     ungetc (c1, finput);
  4091.     token_buffer[1] = 0;
  4092.  
  4093.     if ((c == '<') || (c == '>'))
  4094.       value = ARITHCOMPARE;
  4095.     else value = c;
  4096.     goto done;
  4097.       }
  4098.  
  4099.     case 0:
  4100.       /* Don't make yyparse think this is eof.  */
  4101.       value = 1;
  4102.       break;
  4103.  
  4104.     default:
  4105.       value = c;
  4106.     }
  4107.  
  4108. done:
  4109. /*  yylloc.last_line = lineno; */
  4110.  
  4111.   return value;
  4112. }
  4113.