source: trunk/third/gcc/c-parse.in @ 8834

Revision 8834, 78.5 KB checked in by ghudson, 28 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r8833, which included commits to RCS files with non-trunk default branches.
Line 
1/* YACC parser for C syntax and for Objective C.  -*-c-*-
2   Copyright (C) 1987, 88, 89, 92, 93, 94, 1995 Free Software Foundation, Inc.
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING.  If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA.  */
20
21/* This file defines the grammar of C and that of Objective C.
22   ifobjc ... end ifobjc  conditionals contain code for Objective C only.
23   ifc ... end ifc  conditionals contain code for C only.
24   Sed commands in Makefile.in are used to convert this file into
25   c-parse.y and into objc-parse.y.  */
26
27/* To whomever it may concern: I have heard that such a thing was once
28   written by AT&T, but I have never seen it.  */
29
30ifobjc
31%expect 48
32end ifobjc
33ifc
34%expect 34
35
36/* These are the 23 conflicts you should get in parse.output;
37   the state numbers may vary if minor changes in the grammar are made.
38
39State 42 contains 1 shift/reduce conflict.  (Two ways to parse ATTRIBUTE.)
40State 44 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
41State 103 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
42State 110 contains 1 shift/reduce conflict.  (Two ways to parse ATTRIBUTE.)
43State 111 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
44State 115 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
45State 132 contains 1 shift/reduce conflict.  (See comment at component_decl.)
46State 180 contains 1 shift/reduce conflict.  (Two ways to parse ATTRIBUTE.)
47State 194 contains 2 shift/reduce conflict.  (Four ways to parse this.)
48State 202 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
49State 214 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
50State 220 contains 1 shift/reduce conflict.  (Two ways to recover from error.)
51State 304 contains 2 shift/reduce conflicts.  (Four ways to parse this.)
52State 335 contains 2 shift/reduce conflicts.  (Four ways to parse this.)
53State 347 contains 1 shift/reduce conflict.  (Two ways to parse ATTRIBUTES.)
54State 352 contains 1 shift/reduce conflict.  (Two ways to parse ATTRIBUTES.)
55State 383 contains 2 shift/reduce conflicts.  (Four ways to parse this.)
56State 434 contains 2 shift/reduce conflicts.  (Four ways to parse this.)  */
57
58end ifc
59
60%{
61#include <stdio.h>
62#include <errno.h>
63#include <setjmp.h>
64
65#include "config.h"
66#include "tree.h"
67#include "input.h"
68#include "c-lex.h"
69#include "c-tree.h"
70#include "flags.h"
71
72#ifdef MULTIBYTE_CHARS
73#include <stdlib.h>
74#include <locale.h>
75#endif
76
77ifobjc
78#include "objc-act.h"
79end ifobjc
80
81/* Since parsers are distinct for each language, put the language string
82   definition here.  */
83ifobjc
84char *language_string = "GNU Obj-C";
85end ifobjc
86ifc
87char *language_string = "GNU C";
88end ifc
89
90#ifndef errno
91extern int errno;
92#endif
93
94void yyerror ();
95
96/* Like YYERROR but do call yyerror.  */
97#define YYERROR1 { yyerror ("syntax error"); YYERROR; }
98
99/* Cause the `yydebug' variable to be defined.  */
100#define YYDEBUG 1
101%}
102
103%start program
104
105%union {long itype; tree ttype; enum tree_code code;
106        char *filename; int lineno; int ends_in_label; }
107
108/* All identifiers that are not reserved words
109   and are not declared typedefs in the current block */
110%token IDENTIFIER
111
112/* All identifiers that are declared typedefs in the current block.
113   In some contexts, they are treated just like IDENTIFIER,
114   but they can also serve as typespecs in declarations.  */
115%token TYPENAME
116
117/* Reserved words that specify storage class.
118   yylval contains an IDENTIFIER_NODE which indicates which one.  */
119%token SCSPEC
120
121/* Reserved words that specify type.
122   yylval contains an IDENTIFIER_NODE which indicates which one.  */
123%token TYPESPEC
124
125/* Reserved words that qualify type: "const" or "volatile".
126   yylval contains an IDENTIFIER_NODE which indicates which one.  */
127%token TYPE_QUAL
128
129/* Character or numeric constants.
130   yylval is the node for the constant.  */
131%token CONSTANT
132
133/* String constants in raw form.
134   yylval is a STRING_CST node.  */
135%token STRING
136
137/* "...", used for functions with variable arglists.  */
138%token ELLIPSIS
139
140/* the reserved words */
141/* SCO include files test "ASM", so use something else. */
142%token SIZEOF ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT
143%token BREAK CONTINUE RETURN GOTO ASM_KEYWORD TYPEOF ALIGNOF
144%token ATTRIBUTE EXTENSION LABEL
145%token REALPART IMAGPART
146
147/* Add precedence rules to solve dangling else s/r conflict */
148%nonassoc IF
149%nonassoc ELSE
150
151/* Define the operator tokens and their precedences.
152   The value is an integer because, if used, it is the tree code
153   to use in the expression made from the operator.  */
154
155%right <code> ASSIGN '='
156%right <code> '?' ':'
157%left <code> OROR
158%left <code> ANDAND
159%left <code> '|'
160%left <code> '^'
161%left <code> '&'
162%left <code> EQCOMPARE
163%left <code> ARITHCOMPARE
164%left <code> LSHIFT RSHIFT
165%left <code> '+' '-'
166%left <code> '*' '/' '%'
167%right <code> UNARY PLUSPLUS MINUSMINUS
168%left HYPERUNARY
169%left <code> POINTSAT '.' '(' '['
170
171/* The Objective-C keywords.  These are included in C and in
172   Objective C, so that the token codes are the same in both.  */
173%token INTERFACE IMPLEMENTATION END SELECTOR DEFS ENCODE
174%token CLASSNAME PUBLIC PRIVATE PROTECTED PROTOCOL OBJECTNAME CLASS ALIAS
175
176/* Objective-C string constants in raw form.
177   yylval is an OBJC_STRING_CST node.  */
178%token OBJC_STRING
179
180
181%type <code> unop
182
183%type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist exprlist
184%type <ttype> expr_no_commas cast_expr unary_expr primary string STRING
185%type <ttype> typed_declspecs reserved_declspecs
186%type <ttype> typed_typespecs reserved_typespecquals
187%type <ttype> declmods typespec typespecqual_reserved
188%type <ttype> SCSPEC TYPESPEC TYPE_QUAL nonempty_type_quals maybe_type_qual
189%type <ttype> initdecls notype_initdecls initdcl notype_initdcl
190%type <ttype> init maybeasm
191%type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
192%type <ttype> maybe_attribute attributes attribute attribute_list attrib
193%type <ttype> any_word
194
195%type <ttype> compstmt
196
197%type <ttype> declarator
198%type <ttype> notype_declarator after_type_declarator
199%type <ttype> parm_declarator
200
201%type <ttype> structsp component_decl_list component_decl_list2
202%type <ttype> component_decl components component_declarator
203%type <ttype> enumlist enumerator
204%type <ttype> typename absdcl absdcl1 type_quals
205%type <ttype> xexpr parms parm identifiers
206
207%type <ttype> parmlist parmlist_1 parmlist_2
208%type <ttype> parmlist_or_identifiers parmlist_or_identifiers_1
209%type <ttype> identifiers_or_typenames
210
211%type <itype> setspecs
212
213%type <ends_in_label> lineno_stmt_or_label lineno_stmt_or_labels stmt_or_label
214
215%type <filename> save_filename
216%type <lineno> save_lineno
217
218ifobjc
219/* the Objective-C nonterminals */
220
221%type <ttype> ivar_decl_list ivar_decls ivar_decl ivars ivar_declarator
222%type <ttype> methoddecl unaryselector keywordselector selector
223%type <ttype> keyworddecl receiver objcmessageexpr messageargs
224%type <ttype> keywordexpr keywordarglist keywordarg
225%type <ttype> myparms myparm optparmlist reservedwords objcselectorexpr
226%type <ttype> selectorarg keywordnamelist keywordname objcencodeexpr
227%type <ttype> objc_string protocolrefs identifier_list objcprotocolexpr
228%type <ttype> CLASSNAME OBJC_STRING OBJECTNAME
229end ifobjc
230
231%{
232/* Number of statements (loosely speaking) seen so far.  */
233static int stmt_count;
234
235/* Input file and line number of the end of the body of last simple_if;
236   used by the stmt-rule immediately after simple_if returns.  */
237static char *if_stmt_file;
238static int if_stmt_line;
239
240/* List of types and structure classes of the current declaration.  */
241static tree current_declspecs;
242static tree prefix_attributes = NULL_TREE;
243
244/* Stack of saved values of current_declspecs and prefix_attributes.  */
245static tree declspec_stack;
246
247/* 1 if we explained undeclared var errors.  */
248static int undeclared_variable_notice;
249
250ifobjc
251/* Objective-C specific information */
252
253tree objc_interface_context;
254tree objc_implementation_context;
255tree objc_method_context;
256tree objc_ivar_chain;
257tree objc_ivar_context;
258enum tree_code objc_inherit_code;
259int objc_receiver_context;
260int objc_public_flag;
261
262end ifobjc
263
264/* Tell yyparse how to print a token's value, if yydebug is set.  */
265
266#define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL)
267extern void yyprint ();
268%}
269
270%%
271program: /* empty */
272                { if (pedantic)
273                    pedwarn ("ANSI C forbids an empty source file");
274                  finish_file ();
275                }
276        | extdefs
277                {
278                  /* In case there were missing closebraces,
279                     get us back to the global binding level.  */
280                  while (! global_bindings_p ())
281                    poplevel (0, 0, 0);
282                  finish_file ();
283                }
284        ;
285
286/* the reason for the strange actions in this rule
287 is so that notype_initdecls when reached via datadef
288 can find a valid list of type and sc specs in $0. */
289
290extdefs:
291        {$<ttype>$ = NULL_TREE; } extdef
292        | extdefs {$<ttype>$ = NULL_TREE; } extdef
293        ;
294
295extdef:
296        fndef
297        | datadef
298ifobjc
299        | objcdef
300end ifobjc
301        | ASM_KEYWORD '(' expr ')' ';'
302                { STRIP_NOPS ($3);
303                  if ((TREE_CODE ($3) == ADDR_EXPR
304                       && TREE_CODE (TREE_OPERAND ($3, 0)) == STRING_CST)
305                      || TREE_CODE ($3) == STRING_CST)
306                    assemble_asm ($3);
307                  else
308                    error ("argument of `asm' is not a constant string"); }
309        ;
310
311datadef:
312          setspecs notype_initdecls ';'
313                { if (pedantic)
314                    error ("ANSI C forbids data definition with no type or storage class");
315                  else if (!flag_traditional)
316                    warning ("data definition has no type or storage class");
317
318                  current_declspecs = TREE_VALUE (declspec_stack);
319                  prefix_attributes = TREE_PURPOSE (declspec_stack);
320                  declspec_stack = TREE_CHAIN (declspec_stack);
321                  resume_momentary ($1); }
322        | declmods setspecs notype_initdecls ';'
323                { current_declspecs = TREE_VALUE (declspec_stack);
324                  prefix_attributes = TREE_PURPOSE (declspec_stack);
325                  declspec_stack = TREE_CHAIN (declspec_stack);
326                  resume_momentary ($2); }
327        | typed_declspecs setspecs initdecls ';'
328                { current_declspecs = TREE_VALUE (declspec_stack);
329                  prefix_attributes = TREE_PURPOSE (declspec_stack);
330                  declspec_stack = TREE_CHAIN (declspec_stack);
331                  resume_momentary ($2);  }
332        | declmods ';'
333          { pedwarn ("empty declaration"); }
334        | typed_declspecs ';'
335          { shadow_tag ($1); }
336        | error ';'
337        | error '}'
338        | ';'
339                { if (pedantic)
340                    pedwarn ("ANSI C does not allow extra `;' outside of a function"); }
341        ;
342
343fndef:
344          typed_declspecs setspecs declarator
345                { if (! start_function ($1, $3, prefix_attributes,
346                                        NULL_TREE, 0))
347                    YYERROR1;
348                  reinit_parse_for_function (); }
349          xdecls
350                { store_parm_decls (); }
351          compstmt_or_error
352                { finish_function (0);
353                  current_declspecs = TREE_VALUE (declspec_stack);
354                  prefix_attributes = TREE_PURPOSE (declspec_stack);
355                  declspec_stack = TREE_CHAIN (declspec_stack);
356                  resume_momentary ($2); }
357        | typed_declspecs setspecs declarator error
358                { current_declspecs = TREE_VALUE (declspec_stack);
359                  prefix_attributes = TREE_PURPOSE (declspec_stack);
360                  declspec_stack = TREE_CHAIN (declspec_stack);
361                  resume_momentary ($2); }
362        | declmods setspecs notype_declarator
363                { if (! start_function ($1, $3, prefix_attributes,
364                                        NULL_TREE, 0))
365                    YYERROR1;
366                  reinit_parse_for_function (); }
367          xdecls
368                { store_parm_decls (); }
369          compstmt_or_error
370                { finish_function (0);
371                  current_declspecs = TREE_VALUE (declspec_stack);
372                  prefix_attributes = TREE_PURPOSE (declspec_stack);
373                  declspec_stack = TREE_CHAIN (declspec_stack);
374                  resume_momentary ($2); }
375        | declmods setspecs notype_declarator error
376                { current_declspecs = TREE_VALUE (declspec_stack);
377                  prefix_attributes = TREE_PURPOSE (declspec_stack);
378                  declspec_stack = TREE_CHAIN (declspec_stack);
379                  resume_momentary ($2); }
380        | setspecs notype_declarator
381                { if (! start_function (NULL_TREE, $2,
382                                        prefix_attributes, NULL_TREE, 0))
383                    YYERROR1;
384                  reinit_parse_for_function (); }
385          xdecls
386                { store_parm_decls (); }
387          compstmt_or_error
388                { finish_function (0);
389                  current_declspecs = TREE_VALUE (declspec_stack);
390                  prefix_attributes = TREE_PURPOSE (declspec_stack);
391                  declspec_stack = TREE_CHAIN (declspec_stack);
392                  resume_momentary ($1); }
393        | setspecs notype_declarator error
394                { current_declspecs = TREE_VALUE (declspec_stack);
395                  prefix_attributes = TREE_PURPOSE (declspec_stack);
396                  declspec_stack = TREE_CHAIN (declspec_stack);
397                  resume_momentary ($1); }
398        ;
399
400identifier:
401        IDENTIFIER
402        | TYPENAME
403ifobjc
404        | OBJECTNAME
405        | CLASSNAME
406end ifobjc
407        ;
408
409unop:     '&'
410                { $$ = ADDR_EXPR; }
411        | '-'
412                { $$ = NEGATE_EXPR; }
413        | '+'
414                { $$ = CONVERT_EXPR; }
415        | PLUSPLUS
416                { $$ = PREINCREMENT_EXPR; }
417        | MINUSMINUS
418                { $$ = PREDECREMENT_EXPR; }
419        | '~'
420                { $$ = BIT_NOT_EXPR; }
421        | '!'
422                { $$ = TRUTH_NOT_EXPR; }
423        ;
424
425expr:   nonnull_exprlist
426                { $$ = build_compound_expr ($1); }
427        ;
428
429exprlist:
430          /* empty */
431                { $$ = NULL_TREE; }
432        | nonnull_exprlist
433        ;
434
435nonnull_exprlist:
436        expr_no_commas
437                { $$ = build_tree_list (NULL_TREE, $1); }
438        | nonnull_exprlist ',' expr_no_commas
439                { chainon ($1, build_tree_list (NULL_TREE, $3)); }
440        ;
441
442unary_expr:
443        primary
444        | '*' cast_expr   %prec UNARY
445                { $$ = build_indirect_ref ($2, "unary *"); }
446        /* __extension__ turns off -pedantic for following primary.  */
447        | EXTENSION
448                { $<itype>1 = pedantic;
449                  pedantic = 0; }
450          cast_expr       %prec UNARY
451                { $$ = $3;
452                  pedantic = $<itype>1; }
453        | unop cast_expr  %prec UNARY
454                { $$ = build_unary_op ($1, $2, 0);
455                  overflow_warning ($$); }
456        /* Refer to the address of a label as a pointer.  */
457        | ANDAND identifier
458                { tree label = lookup_label ($2);
459                  if (pedantic)
460                    pedwarn ("ANSI C forbids `&&'");
461                  if (label == 0)
462                    $$ = null_pointer_node;
463                  else
464                    {
465                      TREE_USED (label) = 1;
466                      $$ = build1 (ADDR_EXPR, ptr_type_node, label);
467                      TREE_CONSTANT ($$) = 1;
468                    }
469                }
470/* This seems to be impossible on some machines, so let's turn it off.
471   You can use __builtin_next_arg to find the anonymous stack args.
472        | '&' ELLIPSIS
473                { tree types = TYPE_ARG_TYPES (TREE_TYPE (current_function_decl));
474                  $$ = error_mark_node;
475                  if (TREE_VALUE (tree_last (types)) == void_type_node)
476                    error ("`&...' used in function with fixed number of arguments");
477                  else
478                    {
479                      if (pedantic)
480                        pedwarn ("ANSI C forbids `&...'");
481                      $$ = tree_last (DECL_ARGUMENTS (current_function_decl));
482                      $$ = build_unary_op (ADDR_EXPR, $$, 0);
483                    } }
484*/
485        | SIZEOF unary_expr  %prec UNARY
486                { if (TREE_CODE ($2) == COMPONENT_REF
487                      && DECL_BIT_FIELD (TREE_OPERAND ($2, 1)))
488                    error ("`sizeof' applied to a bit-field");
489                  $$ = c_sizeof (TREE_TYPE ($2)); }
490        | SIZEOF '(' typename ')'  %prec HYPERUNARY
491                { $$ = c_sizeof (groktypename ($3)); }
492        | ALIGNOF unary_expr  %prec UNARY
493                { $$ = c_alignof_expr ($2); }
494        | ALIGNOF '(' typename ')'  %prec HYPERUNARY
495                { $$ = c_alignof (groktypename ($3)); }
496        | REALPART cast_expr %prec UNARY
497                { $$ = build_unary_op (REALPART_EXPR, $2, 0); }
498        | IMAGPART cast_expr %prec UNARY
499                { $$ = build_unary_op (IMAGPART_EXPR, $2, 0); }
500        ;
501
502cast_expr:
503        unary_expr
504        | '(' typename ')' cast_expr  %prec UNARY
505                { tree type = groktypename ($2);
506                  $$ = build_c_cast (type, $4); }
507        | '(' typename ')' '{'
508                { start_init (NULL_TREE, NULL, 0);
509                  $2 = groktypename ($2);
510                  really_start_incremental_init ($2); }
511          initlist_maybe_comma '}'  %prec UNARY
512                { char *name;
513                  tree result = pop_init_level (0);
514                  tree type = $2;
515                  finish_init ();
516
517                  if (pedantic)
518                    pedwarn ("ANSI C forbids constructor expressions");
519                  if (TYPE_NAME (type) != 0)
520                    {
521                      if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
522                        name = IDENTIFIER_POINTER (TYPE_NAME (type));
523                      else
524                        name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
525                    }
526                  else
527                    name = "";
528                  $$ = result;
529                  if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (type) == 0)
530                    {
531                      int failure = complete_array_type (type, $$, 1);
532                      if (failure)
533                        abort ();
534                    }
535                }
536        ;
537
538expr_no_commas:
539          cast_expr
540        | expr_no_commas '+' expr_no_commas
541                { $$ = parser_build_binary_op ($2, $1, $3); }
542        | expr_no_commas '-' expr_no_commas
543                { $$ = parser_build_binary_op ($2, $1, $3); }
544        | expr_no_commas '*' expr_no_commas
545                { $$ = parser_build_binary_op ($2, $1, $3); }
546        | expr_no_commas '/' expr_no_commas
547                { $$ = parser_build_binary_op ($2, $1, $3); }
548        | expr_no_commas '%' expr_no_commas
549                { $$ = parser_build_binary_op ($2, $1, $3); }
550        | expr_no_commas LSHIFT expr_no_commas
551                { $$ = parser_build_binary_op ($2, $1, $3); }
552        | expr_no_commas RSHIFT expr_no_commas
553                { $$ = parser_build_binary_op ($2, $1, $3); }
554        | expr_no_commas ARITHCOMPARE expr_no_commas
555                { $$ = parser_build_binary_op ($2, $1, $3); }
556        | expr_no_commas EQCOMPARE expr_no_commas
557                { $$ = parser_build_binary_op ($2, $1, $3); }
558        | expr_no_commas '&' expr_no_commas
559                { $$ = parser_build_binary_op ($2, $1, $3); }
560        | expr_no_commas '|' expr_no_commas
561                { $$ = parser_build_binary_op ($2, $1, $3); }
562        | expr_no_commas '^' expr_no_commas
563                { $$ = parser_build_binary_op ($2, $1, $3); }
564        | expr_no_commas ANDAND expr_no_commas
565                { $$ = parser_build_binary_op (TRUTH_ANDIF_EXPR, $1, $3); }
566        | expr_no_commas OROR expr_no_commas
567                { $$ = parser_build_binary_op (TRUTH_ORIF_EXPR, $1, $3); }
568        | expr_no_commas '?' xexpr ':' expr_no_commas
569                { $$ = build_conditional_expr ($1, $3, $5); }
570        | expr_no_commas '=' expr_no_commas
571                { $$ = build_modify_expr ($1, NOP_EXPR, $3);
572                  C_SET_EXP_ORIGINAL_CODE ($$, MODIFY_EXPR); }
573        | expr_no_commas ASSIGN expr_no_commas
574                { $$ = build_modify_expr ($1, $2, $3);
575                  /* This inhibits warnings in truthvalue_conversion.  */
576                  C_SET_EXP_ORIGINAL_CODE ($$, ERROR_MARK); }
577        ;
578
579primary:
580        IDENTIFIER
581                {
582                  $$ = lastiddecl;
583                  if (!$$ || $$ == error_mark_node)
584                    {
585                      if (yychar == YYEMPTY)
586                        yychar = YYLEX;
587                      if (yychar == '(')
588                        {
589ifobjc
590                          tree decl;
591
592                          if (objc_receiver_context
593                              && ! (objc_receiver_context
594                                    && strcmp (IDENTIFIER_POINTER ($1), "super")))
595                            /* we have a message to super */
596                            $$ = get_super_receiver ();
597                          else if (objc_method_context
598                                   && (decl = is_ivar (objc_ivar_chain, $1)))
599                            {
600                              if (is_private (decl))
601                                $$ = error_mark_node;
602                              else
603                                $$ = build_ivar_reference ($1);
604                            }
605                          else
606end ifobjc
607                            {
608                              /* Ordinary implicit function declaration.  */
609                              $$ = implicitly_declare ($1);
610                              assemble_external ($$);
611                              TREE_USED ($$) = 1;
612                            }
613                        }
614                      else if (current_function_decl == 0)
615                        {
616                          error ("`%s' undeclared here (not in a function)",
617                                 IDENTIFIER_POINTER ($1));
618                          $$ = error_mark_node;
619                        }
620                      else
621                        {
622ifobjc
623                          tree decl;
624
625                          if (objc_receiver_context
626                              && ! strcmp (IDENTIFIER_POINTER ($1), "super"))
627                            /* we have a message to super */
628                            $$ = get_super_receiver ();
629                          else if (objc_method_context
630                                   && (decl = is_ivar (objc_ivar_chain, $1)))
631                            {
632                              if (is_private (decl))
633                                $$ = error_mark_node;
634                              else
635                                $$ = build_ivar_reference ($1);
636                            }
637                          else
638end ifobjc
639                            {
640                              if (IDENTIFIER_GLOBAL_VALUE ($1) != error_mark_node
641                                  || IDENTIFIER_ERROR_LOCUS ($1) != current_function_decl)
642                                {
643                                  error ("`%s' undeclared (first use this function)",
644                                         IDENTIFIER_POINTER ($1));
645
646                                  if (! undeclared_variable_notice)
647                                    {
648                                      error ("(Each undeclared identifier is reported only once");
649                                      error ("for each function it appears in.)");
650                                      undeclared_variable_notice = 1;
651                                    }
652                                }
653                              $$ = error_mark_node;
654                              /* Prevent repeated error messages.  */
655                              IDENTIFIER_GLOBAL_VALUE ($1) = error_mark_node;
656                              IDENTIFIER_ERROR_LOCUS ($1) = current_function_decl;
657                            }
658                        }
659                    }
660                  else if (TREE_TYPE ($$) == error_mark_node)
661                    $$ = error_mark_node;
662                  else if (C_DECL_ANTICIPATED ($$))
663                    {
664                      /* The first time we see a build-in function used,
665                         if it has not been declared.  */
666                      C_DECL_ANTICIPATED ($$) = 0;
667                      if (yychar == YYEMPTY)
668                        yychar = YYLEX;
669                      if (yychar == '(')
670                        {
671                          /* Omit the implicit declaration we
672                             would ordinarily do, so we don't lose
673                             the actual built in type.
674                             But print a diagnostic for the mismatch.  */
675ifobjc
676                          if (objc_method_context
677                              && is_ivar (objc_ivar_chain, $1))
678                            error ("Instance variable `%s' implicitly declared as function",
679                                   IDENTIFIER_POINTER (DECL_NAME ($$)));
680                          else
681end ifobjc
682                            if (TREE_CODE ($$) != FUNCTION_DECL)
683                              error ("`%s' implicitly declared as function",
684                                     IDENTIFIER_POINTER (DECL_NAME ($$)));
685                          else if ((TYPE_MODE (TREE_TYPE (TREE_TYPE ($$)))
686                                    != TYPE_MODE (integer_type_node))
687                                   && (TREE_TYPE (TREE_TYPE ($$))
688                                       != void_type_node))
689                            pedwarn ("type mismatch in implicit declaration for built-in function `%s'",
690                                     IDENTIFIER_POINTER (DECL_NAME ($$)));
691                          /* If it really returns void, change that to int.  */
692                          if (TREE_TYPE (TREE_TYPE ($$)) == void_type_node)
693                            TREE_TYPE ($$)
694                              = build_function_type (integer_type_node,
695                                                     TYPE_ARG_TYPES (TREE_TYPE ($$)));
696                        }
697                      else
698                        pedwarn ("built-in function `%s' used without declaration",
699                                 IDENTIFIER_POINTER (DECL_NAME ($$)));
700
701                      /* Do what we would ordinarily do when a fn is used.  */
702                      assemble_external ($$);
703                      TREE_USED ($$) = 1;
704                    }
705                  else
706                    {
707                      assemble_external ($$);
708                      TREE_USED ($$) = 1;
709ifobjc
710                      /* we have a definition - still check if iVariable */
711
712                      if (!objc_receiver_context
713                          || (objc_receiver_context
714                              && strcmp (IDENTIFIER_POINTER ($1), "super")))
715                        {
716                          tree decl;
717
718                          if (objc_method_context
719                              && (decl = is_ivar (objc_ivar_chain, $1)))
720                            {
721                              if (IDENTIFIER_LOCAL_VALUE ($1))
722                                warning ("local declaration of `%s' hides instance variable",
723                                         IDENTIFIER_POINTER ($1));
724                              else
725                                {
726                                  if (is_private (decl))
727                                    $$ = error_mark_node;
728                                  else
729                                    $$ = build_ivar_reference ($1);
730                                }
731                            }
732                        }
733                      else /* we have a message to super */
734                        $$ = get_super_receiver ();
735end ifobjc
736                    }
737
738                  if (TREE_CODE ($$) == CONST_DECL)
739                    {
740                      $$ = DECL_INITIAL ($$);
741                      /* This is to prevent an enum whose value is 0
742                         from being considered a null pointer constant.  */
743                      $$ = build1 (NOP_EXPR, TREE_TYPE ($$), $$);
744                      TREE_CONSTANT ($$) = 1;
745                    }
746                }
747        | CONSTANT
748        | string
749                { $$ = combine_strings ($1); }
750        | '(' expr ')'
751                { char class = TREE_CODE_CLASS (TREE_CODE ($2));
752                  if (class == 'e' || class == '1'
753                      || class == '2' || class == '<')
754                    C_SET_EXP_ORIGINAL_CODE ($2, ERROR_MARK);
755                  $$ = $2; }
756        | '(' error ')'
757                { $$ = error_mark_node; }
758        | '('
759                { if (current_function_decl == 0)
760                    {
761                      error ("braced-group within expression allowed only inside a function");
762                      YYERROR;
763                    }
764                  /* We must force a BLOCK for this level
765                     so that, if it is not expanded later,
766                     there is a way to turn off the entire subtree of blocks
767                     that are contained in it.  */
768                  keep_next_level ();
769                  push_iterator_stack ();
770                  push_label_level ();
771                  $<ttype>$ = expand_start_stmt_expr (); }
772          compstmt ')'
773                { tree rtl_exp;
774                  if (pedantic)
775                    pedwarn ("ANSI C forbids braced-groups within expressions");
776                  pop_iterator_stack ();
777                  pop_label_level ();
778                  rtl_exp = expand_end_stmt_expr ($<ttype>2);
779                  /* The statements have side effects, so the group does.  */
780                  TREE_SIDE_EFFECTS (rtl_exp) = 1;
781
782                  if (TREE_CODE ($3) == BLOCK)
783                    {
784                      /* Make a BIND_EXPR for the BLOCK already made.  */
785                      $$ = build (BIND_EXPR, TREE_TYPE (rtl_exp),
786                                  NULL_TREE, rtl_exp, $3);
787                      /* Remove the block from the tree at this point.
788                         It gets put back at the proper place
789                         when the BIND_EXPR is expanded.  */
790                      delete_block ($3);
791                    }
792                  else
793                    $$ = $3;
794                }
795        | primary '(' exprlist ')'   %prec '.'
796                { $$ = build_function_call ($1, $3); }
797        | primary '[' expr ']'   %prec '.'
798                { $$ = build_array_ref ($1, $3); }
799        | primary '.' identifier
800                {
801ifobjc
802                  if (doing_objc_thang)
803                    {
804                      if (is_public ($1, $3))
805                        $$ = build_component_ref ($1, $3);
806                      else
807                        $$ = error_mark_node;
808                    }
809                  else
810end ifobjc
811                    $$ = build_component_ref ($1, $3);
812                }
813        | primary POINTSAT identifier
814                {
815                  tree expr = build_indirect_ref ($1, "->");
816
817ifobjc
818                  if (doing_objc_thang)
819                    {
820                      if (is_public (expr, $3))
821                        $$ = build_component_ref (expr, $3);
822                      else
823                        $$ = error_mark_node;
824                    }
825                  else
826end ifobjc
827                    $$ = build_component_ref (expr, $3);
828                }
829        | primary PLUSPLUS
830                { $$ = build_unary_op (POSTINCREMENT_EXPR, $1, 0); }
831        | primary MINUSMINUS
832                { $$ = build_unary_op (POSTDECREMENT_EXPR, $1, 0); }
833ifobjc
834        | objcmessageexpr
835                { $$ = build_message_expr ($1); }
836        | objcselectorexpr
837                { $$ = build_selector_expr ($1); }
838        | objcprotocolexpr
839                { $$ = build_protocol_expr ($1); }
840        | objcencodeexpr
841                { $$ = build_encode_expr ($1); }
842        | objc_string
843                { $$ = build_objc_string_object ($1); }
844end ifobjc
845        ;
846
847/* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it.  */
848string:
849          STRING
850        | string STRING
851                { $$ = chainon ($1, $2); }
852        ;
853
854ifobjc
855/* Produces an OBJC_STRING_CST with perhaps more OBJC_STRING_CSTs chained
856   onto it.  */
857objc_string:
858          OBJC_STRING
859        | objc_string OBJC_STRING
860                { $$ = chainon ($1, $2); }
861        ;
862end ifobjc
863
864xdecls:
865        /* empty */
866        | datadecls
867        | datadecls ELLIPSIS
868                /* ... is used here to indicate a varargs function.  */
869                { c_mark_varargs ();
870                  if (pedantic)
871                    pedwarn ("ANSI C does not permit use of `varargs.h'"); }
872        ;
873
874/* The following are analogous to lineno_decl, decls and decl
875   except that they do not allow nested functions.
876   They are used for old-style parm decls.  */
877lineno_datadecl:
878          save_filename save_lineno datadecl
879                { }
880        ;
881
882datadecls:
883        lineno_datadecl
884        | errstmt
885        | datadecls lineno_datadecl
886        | lineno_datadecl errstmt
887        ;
888
889datadecl:
890        typed_declspecs setspecs initdecls ';'
891                { current_declspecs = TREE_VALUE (declspec_stack);
892                  prefix_attributes = TREE_PURPOSE (declspec_stack);
893                  declspec_stack = TREE_CHAIN (declspec_stack);
894                  resume_momentary ($2); }
895        | declmods setspecs notype_initdecls ';'
896                { current_declspecs = TREE_VALUE (declspec_stack);     
897                  prefix_attributes = TREE_PURPOSE (declspec_stack);
898                  declspec_stack = TREE_CHAIN (declspec_stack);
899                  resume_momentary ($2); }
900        | typed_declspecs ';'
901                { shadow_tag_warned ($1, 1);
902                  pedwarn ("empty declaration"); }
903        | declmods ';'
904                { pedwarn ("empty declaration"); }
905        ;
906
907/* This combination which saves a lineno before a decl
908   is the normal thing to use, rather than decl itself.
909   This is to avoid shift/reduce conflicts in contexts
910   where statement labels are allowed.  */
911lineno_decl:
912          save_filename save_lineno decl
913                { }
914        ;
915
916decls:
917        lineno_decl
918        | errstmt
919        | decls lineno_decl
920        | lineno_decl errstmt
921        ;
922
923/* records the type and storage class specs to use for processing
924   the declarators that follow.
925   Maintains a stack of outer-level values of current_declspecs,
926   for the sake of parm declarations nested in function declarators.  */
927setspecs: /* empty */
928                { $$ = suspend_momentary ();
929                  pending_xref_error ();
930                  declspec_stack = tree_cons (prefix_attributes,
931                                              current_declspecs,
932                                              declspec_stack);
933                  current_declspecs = $<ttype>0;
934                  prefix_attributes = NULL_TREE; }
935        ;
936
937setattrs: /* empty */
938                { prefix_attributes = chainon (prefix_attributes, $<ttype>0); }
939        ;
940
941decl:
942        typed_declspecs setspecs initdecls ';'
943                { current_declspecs = TREE_VALUE (declspec_stack);
944                  prefix_attributes = TREE_PURPOSE (declspec_stack);
945                  declspec_stack = TREE_CHAIN (declspec_stack);
946                  resume_momentary ($2); }
947        | declmods setspecs notype_initdecls ';'
948                { current_declspecs = TREE_VALUE (declspec_stack);
949                  prefix_attributes = TREE_PURPOSE (declspec_stack);
950                  declspec_stack = TREE_CHAIN (declspec_stack);
951                  resume_momentary ($2); }
952        | typed_declspecs setspecs nested_function
953                { current_declspecs = TREE_VALUE (declspec_stack);
954                  prefix_attributes = TREE_PURPOSE (declspec_stack);
955                  declspec_stack = TREE_CHAIN (declspec_stack);
956                  resume_momentary ($2); }
957        | declmods setspecs notype_nested_function
958                { current_declspecs = TREE_VALUE (declspec_stack);
959                  prefix_attributes = TREE_PURPOSE (declspec_stack);
960                  declspec_stack = TREE_CHAIN (declspec_stack);
961                  resume_momentary ($2); }
962        | typed_declspecs ';'
963                { shadow_tag ($1); }
964        | declmods ';'
965                { pedwarn ("empty declaration"); }
966        ;
967
968/* Declspecs which contain at least one type specifier or typedef name.
969   (Just `const' or `volatile' is not enough.)
970   A typedef'd name following these is taken as a name to be declared.  */
971
972typed_declspecs:
973          typespec reserved_declspecs
974                { $$ = tree_cons (NULL_TREE, $1, $2); }
975        | declmods typespec reserved_declspecs
976                { $$ = chainon ($3, tree_cons (NULL_TREE, $2, $1)); }
977        ;
978
979reserved_declspecs:  /* empty */
980                { $$ = NULL_TREE; }
981        | reserved_declspecs typespecqual_reserved
982                { $$ = tree_cons (NULL_TREE, $2, $1); }
983        | reserved_declspecs SCSPEC
984                { if (extra_warnings)
985                    warning ("`%s' is not at beginning of declaration",
986                             IDENTIFIER_POINTER ($2));
987                  $$ = tree_cons (NULL_TREE, $2, $1); }
988        ;
989
990/* List of just storage classes and type modifiers.
991   A declaration can start with just this, but then it cannot be used
992   to redeclare a typedef-name.  */
993
994declmods:
995          TYPE_QUAL
996                { $$ = tree_cons (NULL_TREE, $1, NULL_TREE);
997                  TREE_STATIC ($$) = 1; }
998        | SCSPEC
999                { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
1000        | declmods TYPE_QUAL
1001                { $$ = tree_cons (NULL_TREE, $2, $1);
1002                  TREE_STATIC ($$) = 1; }
1003        | declmods SCSPEC
1004                { if (extra_warnings && TREE_STATIC ($1))
1005                    warning ("`%s' is not at beginning of declaration",
1006                             IDENTIFIER_POINTER ($2));
1007                  $$ = tree_cons (NULL_TREE, $2, $1);
1008                  TREE_STATIC ($$) = TREE_STATIC ($1); }
1009        ;
1010
1011
1012/* Used instead of declspecs where storage classes are not allowed
1013   (that is, for typenames and structure components).
1014   Don't accept a typedef-name if anything but a modifier precedes it.  */
1015
1016typed_typespecs:
1017          typespec reserved_typespecquals
1018                { $$ = tree_cons (NULL_TREE, $1, $2); }
1019        | nonempty_type_quals typespec reserved_typespecquals
1020                { $$ = chainon ($3, tree_cons (NULL_TREE, $2, $1)); }
1021        ;
1022
1023reserved_typespecquals:  /* empty */
1024                { $$ = NULL_TREE; }
1025        | reserved_typespecquals typespecqual_reserved
1026                { $$ = tree_cons (NULL_TREE, $2, $1); }
1027        ;
1028
1029/* A typespec (but not a type qualifier).
1030   Once we have seen one of these in a declaration,
1031   if a typedef name appears then it is being redeclared.  */
1032
1033typespec: TYPESPEC
1034        | structsp
1035        | TYPENAME
1036                { /* For a typedef name, record the meaning, not the name.
1037                     In case of `foo foo, bar;'.  */
1038                  $$ = lookup_name ($1); }
1039ifobjc
1040        | CLASSNAME protocolrefs
1041                { $$ = get_static_reference ($1, $2); }
1042        | OBJECTNAME protocolrefs
1043                { $$ = get_object_reference ($2); }
1044end ifobjc
1045        | TYPEOF '(' expr ')'
1046                { $$ = TREE_TYPE ($3); }
1047        | TYPEOF '(' typename ')'
1048                { $$ = groktypename ($3); }
1049        ;
1050
1051/* A typespec that is a reserved word, or a type qualifier.  */
1052
1053typespecqual_reserved: TYPESPEC
1054        | TYPE_QUAL
1055        | structsp
1056        ;
1057
1058initdecls:
1059        initdcl
1060        | initdecls ',' initdcl
1061        ;
1062
1063notype_initdecls:
1064        notype_initdcl
1065        | notype_initdecls ',' initdcl
1066        ;
1067
1068maybeasm:
1069          /* empty */
1070                { $$ = NULL_TREE; }
1071        | ASM_KEYWORD '(' string ')'
1072                { if (TREE_CHAIN ($3)) $3 = combine_strings ($3);
1073                  $$ = $3;
1074                }
1075        ;
1076
1077initdcl:
1078          declarator maybeasm maybe_attribute '='
1079                { $<ttype>$ = start_decl ($1, current_declspecs, 1,
1080                                          $3, prefix_attributes);
1081                  start_init ($<ttype>$, $2, global_bindings_p ()); }
1082          init
1083/* Note how the declaration of the variable is in effect while its init is parsed! */
1084                { finish_init ();
1085                  finish_decl ($<ttype>5, $6, $2); }
1086        | declarator maybeasm maybe_attribute
1087                { tree d = start_decl ($1, current_declspecs, 0,
1088                                       $3, prefix_attributes);
1089                  finish_decl (d, NULL_TREE, $2);
1090                }
1091        ;
1092
1093notype_initdcl:
1094          notype_declarator maybeasm maybe_attribute '='
1095                { $<ttype>$ = start_decl ($1, current_declspecs, 1,
1096                                          $3, prefix_attributes);
1097                  start_init ($<ttype>$, $2, global_bindings_p ()); }
1098          init
1099/* Note how the declaration of the variable is in effect while its init is parsed! */
1100                { finish_init ();
1101                  decl_attributes ($<ttype>5, $3, prefix_attributes);
1102                  finish_decl ($<ttype>5, $6, $2); }
1103        | notype_declarator maybeasm maybe_attribute
1104                { tree d = start_decl ($1, current_declspecs, 0,
1105                                       $3, prefix_attributes);
1106                  finish_decl (d, NULL_TREE, $2); }
1107        ;
1108/* the * rules are dummies to accept the Apollo extended syntax
1109   so that the header files compile. */
1110maybe_attribute:
1111      /* empty */
1112                { $$ = NULL_TREE; }
1113        | attributes
1114                { $$ = $1; }
1115        ;
1116 
1117attributes:
1118      attribute
1119                { $$ = $1; }
1120        | attributes attribute
1121                { $$ = chainon ($1, $2); }
1122        ;
1123
1124attribute:
1125      ATTRIBUTE '(' '(' attribute_list ')' ')'
1126                { $$ = $4; }
1127        ;
1128
1129attribute_list:
1130      attrib
1131                { $$ = $1; }
1132        | attribute_list ',' attrib
1133                { $$ = chainon ($1, $3); }
1134        ;
1135 
1136attrib:
1137    /* empty */
1138                { $$ = NULL_TREE; }
1139        | any_word
1140                { $$ = build_tree_list ($1, NULL_TREE); }
1141        | any_word '(' IDENTIFIER ')'
1142                { $$ = build_tree_list ($1, build_tree_list (NULL_TREE, $3)); }
1143        | any_word '(' IDENTIFIER ',' nonnull_exprlist ')'
1144                { $$ = build_tree_list ($1, tree_cons (NULL_TREE, $3, $5)); }
1145        | any_word '(' exprlist ')'
1146                { $$ = build_tree_list ($1, $3); }
1147        ;
1148
1149/* This still leaves out most reserved keywords,
1150   shouldn't we include them?  */
1151
1152any_word:
1153          identifier
1154        | SCSPEC
1155        | TYPESPEC
1156        | TYPE_QUAL
1157        ;
1158
1159/* Initializers.  `init' is the entry point.  */
1160
1161init:
1162        expr_no_commas
1163        | '{'
1164                { really_start_incremental_init (NULL_TREE);
1165                  /* Note that the call to clear_momentary
1166                     is in process_init_element.  */
1167                  push_momentary (); }
1168          initlist_maybe_comma '}'
1169                { $$ = pop_init_level (0);
1170                  if ($$ == error_mark_node
1171                      && ! (yychar == STRING || yychar == CONSTANT))
1172                    pop_momentary ();
1173                  else
1174                    pop_momentary_nofree (); }
1175
1176        | error
1177                { $$ = error_mark_node; }
1178        ;
1179
1180/* `initlist_maybe_comma' is the guts of an initializer in braces.  */
1181initlist_maybe_comma:
1182          /* empty */
1183                { if (pedantic)
1184                    pedwarn ("ANSI C forbids empty initializer braces"); }
1185        | initlist1 maybecomma
1186        ;
1187
1188initlist1:
1189          initelt
1190        | initlist1 ',' initelt
1191        ;
1192
1193/* `initelt' is a single element of an initializer.
1194   It may use braces.  */
1195initelt:
1196        expr_no_commas
1197                { process_init_element ($1); }
1198        | '{'
1199                { push_init_level (0); }
1200          initlist_maybe_comma '}'
1201                { process_init_element (pop_init_level (0)); }
1202        | error
1203        /* These are for labeled elements.  The syntax for an array element
1204           initializer conflicts with the syntax for an Objective-C message,
1205           so don't include these productions in the Objective-C grammar.  */
1206ifc
1207        | '[' expr_no_commas ELLIPSIS expr_no_commas ']' '='
1208                { set_init_index ($2, $4); }
1209          initelt
1210        | '[' expr_no_commas ']' '='
1211                { set_init_index ($2, NULL_TREE); }
1212          initelt
1213        | '[' expr_no_commas ']'
1214                { set_init_index ($2, NULL_TREE); }
1215          initelt
1216end ifc
1217        | identifier ':'
1218                { set_init_label ($1); }
1219          initelt
1220        | '.' identifier '='
1221                { set_init_label ($2); }
1222          initelt
1223        ;
1224
1225nested_function:
1226          declarator
1227                { push_c_function_context ();
1228                  if (! start_function (current_declspecs, $1,
1229                                        prefix_attributes, NULL_TREE, 1))
1230                    {
1231                      pop_c_function_context ();
1232                      YYERROR1;
1233                    }
1234                  reinit_parse_for_function (); }
1235           xdecls
1236                { store_parm_decls (); }
1237/* This used to use compstmt_or_error.
1238   That caused a bug with input `f(g) int g {}',
1239   where the use of YYERROR1 above caused an error
1240   which then was handled by compstmt_or_error.
1241   There followed a repeated execution of that same rule,
1242   which called YYERROR1 again, and so on.  */
1243          compstmt
1244                { finish_function (1);
1245                  pop_c_function_context (); }
1246        ;
1247
1248notype_nested_function:
1249          notype_declarator
1250                { push_c_function_context ();
1251                  if (! start_function (current_declspecs, $1,
1252                                        prefix_attributes, NULL_TREE, 1))
1253                    {
1254                      pop_c_function_context ();
1255                      YYERROR1;
1256                    }
1257                  reinit_parse_for_function (); }
1258          xdecls
1259                { store_parm_decls (); }
1260/* This used to use compstmt_or_error.
1261   That caused a bug with input `f(g) int g {}',
1262   where the use of YYERROR1 above caused an error
1263   which then was handled by compstmt_or_error.
1264   There followed a repeated execution of that same rule,
1265   which called YYERROR1 again, and so on.  */
1266          compstmt
1267                { finish_function (1);
1268                  pop_c_function_context (); }
1269        ;
1270
1271/* Any kind of declarator (thus, all declarators allowed
1272   after an explicit typespec).  */
1273
1274declarator:
1275          after_type_declarator
1276        | notype_declarator
1277        ;
1278
1279/* A declarator that is allowed only after an explicit typespec.  */
1280
1281after_type_declarator:
1282          '(' after_type_declarator ')'
1283                { $$ = $2; }
1284        | after_type_declarator '(' parmlist_or_identifiers  %prec '.'
1285                { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
1286/*      | after_type_declarator '(' error ')'  %prec '.'
1287                { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
1288                  poplevel (0, 0, 0); }  */
1289        | after_type_declarator '[' expr ']'  %prec '.'
1290                { $$ = build_nt (ARRAY_REF, $1, $3); }
1291        | after_type_declarator '[' ']'  %prec '.'
1292                { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
1293        | '*' type_quals after_type_declarator  %prec UNARY
1294                { $$ = make_pointer_declarator ($2, $3); }
1295        | attributes setattrs after_type_declarator
1296                { $$ = $3; }
1297        | TYPENAME
1298ifobjc
1299        | OBJECTNAME
1300end ifobjc
1301        ;
1302
1303/* Kinds of declarator that can appear in a parameter list
1304   in addition to notype_declarator.  This is like after_type_declarator
1305   but does not allow a typedef name in parentheses as an identifier
1306   (because it would conflict with a function with that typedef as arg).  */
1307
1308parm_declarator:
1309          parm_declarator '(' parmlist_or_identifiers  %prec '.'
1310                { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
1311/*      | parm_declarator '(' error ')'  %prec '.'
1312                { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
1313                  poplevel (0, 0, 0); }  */
1314        | parm_declarator '[' expr ']'  %prec '.'
1315                { $$ = build_nt (ARRAY_REF, $1, $3); }
1316        | parm_declarator '[' ']'  %prec '.'
1317                { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
1318        | '*' type_quals parm_declarator  %prec UNARY
1319                { $$ = make_pointer_declarator ($2, $3); }
1320        | attributes setattrs parm_declarator
1321                { $$ = $3; }
1322        | TYPENAME
1323        ;
1324
1325/* A declarator allowed whether or not there has been
1326   an explicit typespec.  These cannot redeclare a typedef-name.  */
1327
1328notype_declarator:
1329          notype_declarator '(' parmlist_or_identifiers  %prec '.'
1330                { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
1331/*      | notype_declarator '(' error ')'  %prec '.'
1332                { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
1333                  poplevel (0, 0, 0); }  */
1334        | '(' notype_declarator ')'
1335                { $$ = $2; }
1336        | '*' type_quals notype_declarator  %prec UNARY
1337                { $$ = make_pointer_declarator ($2, $3); }
1338        | notype_declarator '[' expr ']'  %prec '.'
1339                { $$ = build_nt (ARRAY_REF, $1, $3); }
1340        | notype_declarator '[' ']'  %prec '.'
1341                { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
1342        | attributes setattrs notype_declarator
1343                { $$ = $3; }
1344        | IDENTIFIER
1345        ;
1346
1347structsp:
1348          STRUCT identifier '{'
1349                { $$ = start_struct (RECORD_TYPE, $2);
1350                  /* Start scope of tag before parsing components.  */
1351                }
1352          component_decl_list '}' maybe_attribute
1353                { $$ = finish_struct ($<ttype>4, $5, $7); }
1354        | STRUCT '{' component_decl_list '}' maybe_attribute
1355                { $$ = finish_struct (start_struct (RECORD_TYPE, NULL_TREE),
1356                                      $3, $5);
1357                }
1358        | STRUCT identifier
1359                { $$ = xref_tag (RECORD_TYPE, $2); }
1360        | UNION identifier '{'
1361                { $$ = start_struct (UNION_TYPE, $2); }
1362          component_decl_list '}' maybe_attribute
1363                { $$ = finish_struct ($<ttype>4, $5, $7); }
1364        | UNION '{' component_decl_list '}' maybe_attribute
1365                { $$ = finish_struct (start_struct (UNION_TYPE, NULL_TREE),
1366                                      $3, $5);
1367                }
1368        | UNION identifier
1369                { $$ = xref_tag (UNION_TYPE, $2); }
1370        | ENUM identifier '{'
1371                { $<itype>3 = suspend_momentary ();
1372                  $$ = start_enum ($2); }
1373          enumlist maybecomma_warn '}' maybe_attribute
1374                { $$ = finish_enum ($<ttype>4, nreverse ($5), $8);
1375                  resume_momentary ($<itype>3); }
1376        | ENUM '{'
1377                { $<itype>2 = suspend_momentary ();
1378                  $$ = start_enum (NULL_TREE); }
1379          enumlist maybecomma_warn '}' maybe_attribute
1380                { $$ = finish_enum ($<ttype>3, nreverse ($4), $7);
1381                  resume_momentary ($<itype>2); }
1382        | ENUM identifier
1383                { $$ = xref_tag (ENUMERAL_TYPE, $2); }
1384        ;
1385
1386maybecomma:
1387          /* empty */
1388        | ','
1389        ;
1390
1391maybecomma_warn:
1392          /* empty */
1393        | ','
1394                { if (pedantic) pedwarn ("comma at end of enumerator list"); }
1395        ;
1396
1397component_decl_list:
1398          component_decl_list2
1399                { $$ = $1; }
1400        | component_decl_list2 component_decl
1401                { $$ = chainon ($1, $2);
1402                  pedwarn ("no semicolon at end of struct or union"); }
1403        ;
1404
1405component_decl_list2:   /* empty */
1406                { $$ = NULL_TREE; }
1407        | component_decl_list2 component_decl ';'
1408                { $$ = chainon ($1, $2); }
1409        | component_decl_list2 ';'
1410                { if (pedantic)
1411                    pedwarn ("extra semicolon in struct or union specified"); }
1412ifobjc
1413        /* foo(sizeof(struct{ @defs(ClassName)})); */
1414        | DEFS '(' CLASSNAME ')'
1415                {
1416                  tree interface = lookup_interface ($3);
1417
1418                  if (interface)
1419                    $$ = get_class_ivars (interface);
1420                  else
1421                    {
1422                      error ("Cannot find interface declaration for `%s'",
1423                             IDENTIFIER_POINTER ($3));
1424                      $$ = NULL_TREE;
1425                    }
1426                }
1427end ifobjc
1428        ;
1429
1430/* There is a shift-reduce conflict here, because `components' may
1431   start with a `typename'.  It happens that shifting (the default resolution)
1432   does the right thing, because it treats the `typename' as part of
1433   a `typed_typespecs'.
1434
1435   It is possible that this same technique would allow the distinction
1436   between `notype_initdecls' and `initdecls' to be eliminated.
1437   But I am being cautious and not trying it.  */
1438
1439component_decl:
1440          typed_typespecs setspecs components
1441                { $$ = $3;
1442                  current_declspecs = TREE_VALUE (declspec_stack);
1443                  prefix_attributes = TREE_PURPOSE (declspec_stack);
1444                  declspec_stack = TREE_CHAIN (declspec_stack);
1445                  resume_momentary ($2); }
1446        | typed_typespecs
1447                { if (pedantic)
1448                    pedwarn ("ANSI C forbids member declarations with no members");
1449                  shadow_tag($1);
1450                  $$ = NULL_TREE; }
1451        | nonempty_type_quals setspecs components
1452                { $$ = $3;
1453                  current_declspecs = TREE_VALUE (declspec_stack);
1454                  prefix_attributes = TREE_PURPOSE (declspec_stack);
1455                  declspec_stack = TREE_CHAIN (declspec_stack);
1456                  resume_momentary ($2); }
1457        | nonempty_type_quals
1458                { if (pedantic)
1459                    pedwarn ("ANSI C forbids member declarations with no members");
1460                  shadow_tag($1);
1461                  $$ = NULL_TREE; }
1462        | error
1463                { $$ = NULL_TREE; }
1464        ;
1465
1466components:
1467          component_declarator
1468        | components ',' component_declarator
1469                { $$ = chainon ($1, $3); }
1470        ;
1471
1472component_declarator:
1473          save_filename save_lineno declarator maybe_attribute
1474                { $$ = grokfield ($1, $2, $3, current_declspecs, NULL_TREE);
1475                  decl_attributes ($$, $4, prefix_attributes); }
1476        | save_filename save_lineno
1477          declarator ':' expr_no_commas maybe_attribute
1478                { $$ = grokfield ($1, $2, $3, current_declspecs, $5);
1479                  decl_attributes ($$, $6, prefix_attributes); }
1480        | save_filename save_lineno ':' expr_no_commas maybe_attribute
1481                { $$ = grokfield ($1, $2, NULL_TREE, current_declspecs, $4);
1482                  decl_attributes ($$, $5, prefix_attributes); }
1483        ;
1484
1485/* We chain the enumerators in reverse order.
1486   They are put in forward order where enumlist is used.
1487   (The order used to be significant, but no longer is so.
1488   However, we still maintain the order, just to be clean.)  */
1489
1490enumlist:
1491          enumerator
1492        | enumlist ',' enumerator
1493                { if ($1 == error_mark_node)
1494                    $$ = $1;
1495                  else
1496                    $$ = chainon ($3, $1); }
1497        | error
1498                { $$ = error_mark_node; }
1499        ;
1500
1501
1502enumerator:
1503          identifier
1504                { $$ = build_enumerator ($1, NULL_TREE); }
1505        | identifier '=' expr_no_commas
1506                { $$ = build_enumerator ($1, $3); }
1507        ;
1508
1509typename:
1510        typed_typespecs absdcl
1511                { $$ = build_tree_list ($1, $2); }
1512        | nonempty_type_quals absdcl
1513                { $$ = build_tree_list ($1, $2); }
1514        ;
1515
1516absdcl:   /* an absolute declarator */
1517        /* empty */
1518                { $$ = NULL_TREE; }
1519        | absdcl1
1520        ;
1521
1522nonempty_type_quals:
1523          TYPE_QUAL
1524                { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
1525        | nonempty_type_quals TYPE_QUAL
1526                { $$ = tree_cons (NULL_TREE, $2, $1); }
1527        ;
1528
1529type_quals:
1530          /* empty */
1531                { $$ = NULL_TREE; }
1532        | type_quals TYPE_QUAL
1533                { $$ = tree_cons (NULL_TREE, $2, $1); }
1534        ;
1535
1536absdcl1:  /* a nonempty absolute declarator */
1537          '(' absdcl1 ')'
1538                { $$ = $2; }
1539          /* `(typedef)1' is `int'.  */
1540        | '*' type_quals absdcl1  %prec UNARY
1541                { $$ = make_pointer_declarator ($2, $3); }
1542        | '*' type_quals  %prec UNARY
1543                { $$ = make_pointer_declarator ($2, NULL_TREE); }
1544        | absdcl1 '(' parmlist  %prec '.'
1545                { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
1546        | absdcl1 '[' expr ']'  %prec '.'
1547                { $$ = build_nt (ARRAY_REF, $1, $3); }
1548        | absdcl1 '[' ']'  %prec '.'
1549                { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
1550        | '(' parmlist  %prec '.'
1551                { $$ = build_nt (CALL_EXPR, NULL_TREE, $2, NULL_TREE); }
1552        | '[' expr ']'  %prec '.'
1553                { $$ = build_nt (ARRAY_REF, NULL_TREE, $2); }
1554        | '[' ']'  %prec '.'
1555                { $$ = build_nt (ARRAY_REF, NULL_TREE, NULL_TREE); }
1556        | attributes setattrs absdcl1
1557                { $$ = $3; }
1558        ;
1559
1560/* at least one statement, the first of which parses without error.  */
1561/* stmts is used only after decls, so an invalid first statement
1562   is actually regarded as an invalid decl and part of the decls.  */
1563
1564stmts:
1565        lineno_stmt_or_labels
1566                {
1567                  if (pedantic && $1)
1568                    pedwarn ("ANSI C forbids label at end of compound statement");
1569                }
1570        ;
1571
1572lineno_stmt_or_labels:
1573          lineno_stmt_or_label
1574        | lineno_stmt_or_labels lineno_stmt_or_label
1575                { $$ = $2; }
1576        | lineno_stmt_or_labels errstmt
1577                { $$ = 0; }
1578        ;
1579
1580xstmts:
1581        /* empty */
1582        | stmts
1583        ;
1584
1585errstmt:  error ';'
1586        ;
1587
1588pushlevel:  /* empty */
1589                { emit_line_note (input_filename, lineno);
1590                  pushlevel (0);
1591                  clear_last_expr ();
1592                  push_momentary ();
1593                  expand_start_bindings (0);
1594ifobjc
1595                  if (objc_method_context)
1596                    add_objc_decls ();
1597end ifobjc
1598                }
1599        ;
1600
1601/* Read zero or more forward-declarations for labels
1602   that nested functions can jump to.  */
1603maybe_label_decls:
1604          /* empty */
1605        | label_decls
1606                { if (pedantic)
1607                    pedwarn ("ANSI C forbids label declarations"); }
1608        ;
1609
1610label_decls:
1611          label_decl
1612        | label_decls label_decl
1613        ;
1614
1615label_decl:
1616          LABEL identifiers_or_typenames ';'
1617                { tree link;
1618                  for (link = $2; link; link = TREE_CHAIN (link))
1619                    {
1620                      tree label = shadow_label (TREE_VALUE (link));
1621                      C_DECLARED_LABEL_FLAG (label) = 1;
1622                      declare_nonlocal_label (label);
1623                    }
1624                }
1625        ;
1626
1627/* This is the body of a function definition.
1628   It causes syntax errors to ignore to the next openbrace.  */
1629compstmt_or_error:
1630          compstmt
1631                {}
1632        | error compstmt
1633        ;
1634
1635compstmt: '{' '}'
1636                { $$ = convert (void_type_node, integer_zero_node); }
1637        | '{' pushlevel maybe_label_decls decls xstmts '}'
1638                { emit_line_note (input_filename, lineno);
1639                  expand_end_bindings (getdecls (), 1, 0);
1640                  $$ = poplevel (1, 1, 0);
1641                  if (yychar == CONSTANT || yychar == STRING)
1642                    pop_momentary_nofree ();
1643                  else
1644                    pop_momentary (); }
1645        | '{' pushlevel maybe_label_decls error '}'
1646                { emit_line_note (input_filename, lineno);
1647                  expand_end_bindings (getdecls (), kept_level_p (), 0);
1648                  $$ = poplevel (kept_level_p (), 0, 0);
1649                  if (yychar == CONSTANT || yychar == STRING)
1650                    pop_momentary_nofree ();
1651                  else
1652                    pop_momentary (); }
1653        | '{' pushlevel maybe_label_decls stmts '}'
1654                { emit_line_note (input_filename, lineno);
1655                  expand_end_bindings (getdecls (), kept_level_p (), 0);
1656                  $$ = poplevel (kept_level_p (), 0, 0);
1657                  if (yychar == CONSTANT || yychar == STRING)
1658                    pop_momentary_nofree ();
1659                  else
1660                    pop_momentary (); }
1661        ;
1662
1663/* Value is number of statements counted as of the closeparen.  */
1664simple_if:
1665          if_prefix lineno_labeled_stmt
1666/* Make sure expand_end_cond is run once
1667   for each call to expand_start_cond.
1668   Otherwise a crash is likely.  */
1669        | if_prefix error
1670        ;
1671
1672if_prefix:
1673          IF '(' expr ')'
1674                { emit_line_note ($<filename>-1, $<lineno>0);
1675                  expand_start_cond (truthvalue_conversion ($3), 0);
1676                  $<itype>$ = stmt_count;
1677                  if_stmt_file = $<filename>-1;
1678                  if_stmt_line = $<lineno>0;
1679                  position_after_white_space (); }
1680        ;
1681
1682/* This is a subroutine of stmt.
1683   It is used twice, once for valid DO statements
1684   and once for catching errors in parsing the end test.  */
1685do_stmt_start:
1686          DO
1687                { stmt_count++;
1688                  emit_line_note ($<filename>-1, $<lineno>0);
1689                  /* See comment in `while' alternative, above.  */
1690                  emit_nop ();
1691                  expand_start_loop_continue_elsewhere (1);
1692                  position_after_white_space (); }
1693          lineno_labeled_stmt WHILE
1694                { expand_loop_continue_here (); }
1695        ;
1696
1697save_filename:
1698                { $$ = input_filename; }
1699        ;
1700
1701save_lineno:
1702                { $$ = lineno; }
1703        ;
1704
1705lineno_labeled_stmt:
1706          save_filename save_lineno stmt
1707                { }
1708/*      | save_filename save_lineno error
1709                { }
1710*/
1711        | save_filename save_lineno label lineno_labeled_stmt
1712                { }
1713        ;
1714
1715lineno_stmt_or_label:
1716          save_filename save_lineno stmt_or_label
1717                { $$ = $3; }
1718        ;
1719
1720stmt_or_label:
1721          stmt
1722                { $$ = 0; }
1723        | label
1724                { $$ = 1; }
1725        ;
1726
1727/* Parse a single real statement, not including any labels.  */
1728stmt:
1729          compstmt
1730                { stmt_count++; }
1731        | all_iter_stmt
1732        | expr ';'
1733                { stmt_count++;
1734                  emit_line_note ($<filename>-1, $<lineno>0);
1735/* It appears that this should not be done--that a non-lvalue array
1736   shouldn't get an error if the value isn't used.
1737   Section 3.2.2.1 says that an array lvalue gets converted to a pointer
1738   if it appears as a top-level expression,
1739   but says nothing about non-lvalue arrays.  */
1740#if 0
1741                  /* Call default_conversion to get an error
1742                     on referring to a register array if pedantic.  */
1743                  if (TREE_CODE (TREE_TYPE ($1)) == ARRAY_TYPE
1744                      || TREE_CODE (TREE_TYPE ($1)) == FUNCTION_TYPE)
1745                    $1 = default_conversion ($1);
1746#endif
1747                  iterator_expand ($1);
1748                  clear_momentary (); }
1749        | simple_if ELSE
1750                { expand_start_else ();
1751                  $<itype>1 = stmt_count;
1752                  position_after_white_space (); }
1753          lineno_labeled_stmt
1754                { expand_end_cond ();
1755                  if (extra_warnings && stmt_count == $<itype>1)
1756                    warning ("empty body in an else-statement"); }
1757        | simple_if %prec IF
1758                { expand_end_cond ();
1759                  /* This warning is here instead of in simple_if, because we
1760                     do not want a warning if an empty if is followed by an
1761                     else statement.  Increment stmt_count so we don't
1762                     give a second error if this is a nested `if'.  */
1763                  if (extra_warnings && stmt_count++ == $<itype>1)
1764                    warning_with_file_and_line (if_stmt_file, if_stmt_line,
1765                                                "empty body in an if-statement"); }
1766/* Make sure expand_end_cond is run once
1767   for each call to expand_start_cond.
1768   Otherwise a crash is likely.  */
1769        | simple_if ELSE error
1770                { expand_end_cond (); }
1771        | WHILE
1772                { stmt_count++;
1773                  emit_line_note ($<filename>-1, $<lineno>0);
1774                  /* The emit_nop used to come before emit_line_note,
1775                     but that made the nop seem like part of the preceding line.
1776                     And that was confusing when the preceding line was
1777                     inside of an if statement and was not really executed.
1778                     I think it ought to work to put the nop after the line number.
1779                     We will see.  --rms, July 15, 1991.  */
1780                  emit_nop (); }
1781          '(' expr ')'
1782                { /* Don't start the loop till we have succeeded
1783                     in parsing the end test.  This is to make sure
1784                     that we end every loop we start.  */
1785                  expand_start_loop (1);
1786                  emit_line_note (input_filename, lineno);
1787                  expand_exit_loop_if_false (NULL_PTR,
1788                                             truthvalue_conversion ($4));
1789                  position_after_white_space (); }
1790          lineno_labeled_stmt
1791                { expand_end_loop (); }
1792        | do_stmt_start
1793          '(' expr ')' ';'
1794                { emit_line_note (input_filename, lineno);
1795                  expand_exit_loop_if_false (NULL_PTR,
1796                                             truthvalue_conversion ($3));
1797                  expand_end_loop ();
1798                  clear_momentary (); }
1799/* This rule is needed to make sure we end every loop we start.  */
1800        | do_stmt_start error
1801                { expand_end_loop ();
1802                  clear_momentary (); }
1803        | FOR
1804          '(' xexpr ';'
1805                { stmt_count++;
1806                  emit_line_note ($<filename>-1, $<lineno>0);
1807                  /* See comment in `while' alternative, above.  */
1808                  emit_nop ();
1809                  if ($3) c_expand_expr_stmt ($3);
1810                  /* Next step is to call expand_start_loop_continue_elsewhere,
1811                     but wait till after we parse the entire for (...).
1812                     Otherwise, invalid input might cause us to call that
1813                     fn without calling expand_end_loop.  */
1814                }
1815          xexpr ';'
1816                /* Can't emit now; wait till after expand_start_loop...  */
1817                { $<lineno>7 = lineno;
1818                  $<filename>$ = input_filename; }
1819          xexpr ')'
1820                {
1821                  /* Start the loop.  Doing this after parsing
1822                     all the expressions ensures we will end the loop.  */
1823                  expand_start_loop_continue_elsewhere (1);
1824                  /* Emit the end-test, with a line number.  */
1825                  emit_line_note ($<filename>8, $<lineno>7);
1826                  if ($6)
1827                    expand_exit_loop_if_false (NULL_PTR,
1828                                               truthvalue_conversion ($6));
1829                  /* Don't let the tree nodes for $9 be discarded by
1830                     clear_momentary during the parsing of the next stmt.  */
1831                  push_momentary ();
1832                  $<lineno>7 = lineno;
1833                  $<filename>8 = input_filename;
1834                  position_after_white_space (); }
1835          lineno_labeled_stmt
1836                { /* Emit the increment expression, with a line number.  */
1837                  emit_line_note ($<filename>8, $<lineno>7);
1838                  expand_loop_continue_here ();
1839                  if ($9)
1840                    c_expand_expr_stmt ($9);
1841                  if (yychar == CONSTANT || yychar == STRING)
1842                    pop_momentary_nofree ();
1843                  else
1844                    pop_momentary ();
1845                  expand_end_loop (); }
1846        | SWITCH '(' expr ')'
1847                { stmt_count++;
1848                  emit_line_note ($<filename>-1, $<lineno>0);
1849                  c_expand_start_case ($3);
1850                  /* Don't let the tree nodes for $3 be discarded by
1851                     clear_momentary during the parsing of the next stmt.  */
1852                  push_momentary ();
1853                  position_after_white_space (); }
1854          lineno_labeled_stmt
1855                { expand_end_case ($3);
1856                  if (yychar == CONSTANT || yychar == STRING)
1857                    pop_momentary_nofree ();
1858                  else
1859                    pop_momentary (); }
1860        | BREAK ';'
1861                { stmt_count++;
1862                  emit_line_note ($<filename>-1, $<lineno>0);
1863                  if ( ! expand_exit_something ())
1864                    error ("break statement not within loop or switch"); }
1865        | CONTINUE ';'
1866                { stmt_count++;
1867                  emit_line_note ($<filename>-1, $<lineno>0);
1868                  if (! expand_continue_loop (NULL_PTR))
1869                    error ("continue statement not within a loop"); }
1870        | RETURN ';'
1871                { stmt_count++;
1872                  emit_line_note ($<filename>-1, $<lineno>0);
1873                  c_expand_return (NULL_TREE); }
1874        | RETURN expr ';'
1875                { stmt_count++;
1876                  emit_line_note ($<filename>-1, $<lineno>0);
1877                  c_expand_return ($2); }
1878        | ASM_KEYWORD maybe_type_qual '(' expr ')' ';'
1879                { stmt_count++;
1880                  emit_line_note ($<filename>-1, $<lineno>0);
1881                  STRIP_NOPS ($4);
1882                  if ((TREE_CODE ($4) == ADDR_EXPR
1883                       && TREE_CODE (TREE_OPERAND ($4, 0)) == STRING_CST)
1884                      || TREE_CODE ($4) == STRING_CST)
1885                    expand_asm ($4);
1886                  else
1887                    error ("argument of `asm' is not a constant string"); }
1888        /* This is the case with just output operands.  */
1889        | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ')' ';'
1890                { stmt_count++;
1891                  emit_line_note ($<filename>-1, $<lineno>0);
1892                  c_expand_asm_operands ($4, $6, NULL_TREE, NULL_TREE,
1893                                         $2 == ridpointers[(int)RID_VOLATILE],
1894                                         input_filename, lineno); }
1895        /* This is the case with input operands as well.  */
1896        | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ':' asm_operands ')' ';'
1897                { stmt_count++;
1898                  emit_line_note ($<filename>-1, $<lineno>0);
1899                  c_expand_asm_operands ($4, $6, $8, NULL_TREE,
1900                                         $2 == ridpointers[(int)RID_VOLATILE],
1901                                         input_filename, lineno); }
1902        /* This is the case with clobbered registers as well.  */
1903        | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ':'
1904          asm_operands ':' asm_clobbers ')' ';'
1905                { stmt_count++;
1906                  emit_line_note ($<filename>-1, $<lineno>0);
1907                  c_expand_asm_operands ($4, $6, $8, $10,
1908                                         $2 == ridpointers[(int)RID_VOLATILE],
1909                                         input_filename, lineno); }
1910        | GOTO identifier ';'
1911                { tree decl;
1912                  stmt_count++;
1913                  emit_line_note ($<filename>-1, $<lineno>0);
1914                  decl = lookup_label ($2);
1915                  if (decl != 0)
1916                    {
1917                      TREE_USED (decl) = 1;
1918                      expand_goto (decl);
1919                    }
1920                }
1921        | GOTO '*' expr ';'
1922                { stmt_count++;
1923                  emit_line_note ($<filename>-1, $<lineno>0);
1924                  expand_computed_goto (convert (ptr_type_node, $3)); }
1925        | ';'
1926        ;
1927
1928all_iter_stmt:
1929          all_iter_stmt_simple
1930/*      | all_iter_stmt_with_decl */
1931        ;
1932
1933all_iter_stmt_simple:
1934          FOR '(' primary ')'
1935          {
1936            /* The value returned by this action is  */
1937            /*      1 if everything is OK */
1938            /*      0 in case of error or already bound iterator */
1939
1940            $<itype>$ = 0;
1941            if (TREE_CODE ($3) != VAR_DECL)
1942              error ("invalid `for (ITERATOR)' syntax");
1943            else if (! ITERATOR_P ($3))
1944              error ("`%s' is not an iterator",
1945                     IDENTIFIER_POINTER (DECL_NAME ($3)));
1946            else if (ITERATOR_BOUND_P ($3))
1947              error ("`for (%s)' inside expansion of same iterator",
1948                     IDENTIFIER_POINTER (DECL_NAME ($3)));
1949            else
1950              {
1951                $<itype>$ = 1;
1952                iterator_for_loop_start ($3);
1953              }
1954          }
1955          lineno_labeled_stmt
1956          {
1957            if ($<itype>5)
1958              iterator_for_loop_end ($3);
1959          }
1960
1961/*  This really should allow any kind of declaration,
1962    for generality.  Fix it before turning it back on.
1963
1964all_iter_stmt_with_decl:
1965          FOR '(' ITERATOR pushlevel setspecs iterator_spec ')'
1966          {
1967*/          /* The value returned by this action is  */
1968            /*      1 if everything is OK */
1969            /*      0 in case of error or already bound iterator */
1970/*
1971            iterator_for_loop_start ($6);
1972          }
1973          lineno_labeled_stmt
1974          {
1975            iterator_for_loop_end ($6);
1976            emit_line_note (input_filename, lineno);
1977            expand_end_bindings (getdecls (), 1, 0);
1978            $<ttype>$ = poplevel (1, 1, 0);
1979            if (yychar == CONSTANT || yychar == STRING)
1980              pop_momentary_nofree ();
1981            else
1982              pop_momentary ();     
1983          }
1984*/
1985
1986/* Any kind of label, including jump labels and case labels.
1987   ANSI C accepts labels only before statements, but we allow them
1988   also at the end of a compound statement.  */
1989
1990label:    CASE expr_no_commas ':'
1991                { register tree value = check_case_value ($2);
1992                  register tree label
1993                    = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
1994
1995                  stmt_count++;
1996
1997                  if (value != error_mark_node)
1998                    {
1999                      tree duplicate;
2000                      int success = pushcase (value, convert_and_check,
2001                                              label, &duplicate);
2002                      if (success == 1)
2003                        error ("case label not within a switch statement");
2004                      else if (success == 2)
2005                        {
2006                          error ("duplicate case value");
2007                          error_with_decl (duplicate, "this is the first entry for that value");
2008                        }
2009                      else if (success == 3)
2010                        warning ("case value out of range");
2011                      else if (success == 5)
2012                        error ("case label within scope of cleanup or variable array");
2013                    }
2014                  position_after_white_space (); }
2015        | CASE expr_no_commas ELLIPSIS expr_no_commas ':'
2016                { register tree value1 = check_case_value ($2);
2017                  register tree value2 = check_case_value ($4);
2018                  register tree label
2019                    = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
2020
2021                  stmt_count++;
2022
2023                  if (value1 != error_mark_node && value2 != error_mark_node)
2024                    {
2025                      tree duplicate;
2026                      int success = pushcase_range (value1, value2,
2027                                                    convert_and_check, label,
2028                                                    &duplicate);
2029                      if (success == 1)
2030                        error ("case label not within a switch statement");
2031                      else if (success == 2)
2032                        {
2033                          error ("duplicate case value");
2034                          error_with_decl (duplicate, "this is the first entry for that value");
2035                        }
2036                      else if (success == 3)
2037                        warning ("case value out of range");
2038                      else if (success == 4)
2039                        warning ("empty case range");
2040                      else if (success == 5)
2041                        error ("case label within scope of cleanup or variable array");
2042                    }
2043                  position_after_white_space (); }
2044        | DEFAULT ':'
2045                {
2046                  tree duplicate;
2047                  register tree label
2048                    = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
2049                  int success = pushcase (NULL_TREE, 0, label, &duplicate);
2050                  stmt_count++;
2051                  if (success == 1)
2052                    error ("default label not within a switch statement");
2053                  else if (success == 2)
2054                    {
2055                      error ("multiple default labels in one switch");
2056                      error_with_decl (duplicate, "this is the first default label");
2057                    }
2058                  position_after_white_space (); }
2059        | identifier ':'
2060                { tree label = define_label (input_filename, lineno, $1);
2061                  stmt_count++;
2062                  emit_nop ();
2063                  if (label)
2064                    expand_label (label);
2065                  position_after_white_space (); }
2066        ;
2067
2068/* Either a type-qualifier or nothing.  First thing in an `asm' statement.  */
2069
2070maybe_type_qual:
2071        /* empty */
2072                { emit_line_note (input_filename, lineno);
2073                  $$ = NULL_TREE; }
2074        | TYPE_QUAL
2075                { emit_line_note (input_filename, lineno); }
2076        ;
2077
2078xexpr:
2079        /* empty */
2080                { $$ = NULL_TREE; }
2081        | expr
2082        ;
2083
2084/* These are the operands other than the first string and colon
2085   in  asm ("addextend %2,%1": "=dm" (x), "0" (y), "g" (*x))  */
2086asm_operands: /* empty */
2087                { $$ = NULL_TREE; }
2088        | nonnull_asm_operands
2089        ;
2090
2091nonnull_asm_operands:
2092          asm_operand
2093        | nonnull_asm_operands ',' asm_operand
2094                { $$ = chainon ($1, $3); }
2095        ;
2096
2097asm_operand:
2098          STRING '(' expr ')'
2099                { $$ = build_tree_list ($1, $3); }
2100        ;
2101
2102asm_clobbers:
2103          string
2104                { $$ = tree_cons (NULL_TREE, combine_strings ($1), NULL_TREE); }
2105        | asm_clobbers ',' string
2106                { $$ = tree_cons (NULL_TREE, combine_strings ($3), $1); }
2107        ;
2108
2109/* This is what appears inside the parens in a function declarator.
2110   Its value is a list of ..._TYPE nodes.  */
2111parmlist:
2112                { pushlevel (0);
2113                  clear_parm_order ();
2114                  declare_parm_level (0); }
2115          parmlist_1
2116                { $$ = $2;
2117                  parmlist_tags_warning ();
2118                  poplevel (0, 0, 0); }
2119        ;
2120
2121parmlist_1:
2122          parmlist_2 ')'
2123        | parms ';'
2124                { tree parm;
2125                  if (pedantic)
2126                    pedwarn ("ANSI C forbids forward parameter declarations");
2127                  /* Mark the forward decls as such.  */
2128                  for (parm = getdecls (); parm; parm = TREE_CHAIN (parm))
2129                    TREE_ASM_WRITTEN (parm) = 1;
2130                  clear_parm_order (); }
2131          parmlist_1
2132                { $$ = $4; }
2133        | error ')'
2134                { $$ = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE); }
2135        ;
2136
2137/* This is what appears inside the parens in a function declarator.
2138   Is value is represented in the format that grokdeclarator expects.  */
2139parmlist_2:  /* empty */
2140                { $$ = get_parm_info (0); }
2141        | ELLIPSIS
2142                { $$ = get_parm_info (0);
2143                  /* Gcc used to allow this as an extension.  However, it does
2144                     not work for all targets, and thus has been disabled.
2145                     Also, since func (...) and func () are indistinguishable,
2146                     it caused problems with the code in expand_builtin which
2147                     tries to verify that BUILT_IN_NEXT_ARG is being used
2148                     correctly.  */
2149                  error ("ANSI C requires a named argument before `...'");
2150                }
2151        | parms
2152                { $$ = get_parm_info (1); }
2153        | parms ',' ELLIPSIS
2154                { $$ = get_parm_info (0); }
2155        ;
2156
2157parms:
2158        parm
2159                { push_parm_decl ($1); }
2160        | parms ',' parm
2161                { push_parm_decl ($3); }
2162        ;
2163
2164/* A single parameter declaration or parameter type name,
2165   as found in a parmlist.  */
2166parm:
2167          typed_declspecs setspecs parm_declarator maybe_attribute
2168                { $$ = build_tree_list (build_tree_list (current_declspecs,
2169                                                         $3),
2170                                        build_tree_list (prefix_attributes,
2171                                                         $4));
2172                  current_declspecs = TREE_VALUE (declspec_stack);
2173                  prefix_attributes = TREE_PURPOSE (declspec_stack);
2174                  declspec_stack = TREE_CHAIN (declspec_stack);
2175                  resume_momentary ($2); }
2176        | typed_declspecs setspecs notype_declarator maybe_attribute
2177                { $$ = build_tree_list (build_tree_list (current_declspecs,
2178                                                         $3),
2179                                        build_tree_list (prefix_attributes,
2180                                                         $4));
2181                  current_declspecs = TREE_VALUE (declspec_stack);
2182                  prefix_attributes = TREE_PURPOSE (declspec_stack);
2183                  declspec_stack = TREE_CHAIN (declspec_stack);
2184                  resume_momentary ($2); }
2185        | typed_declspecs setspecs absdcl maybe_attribute
2186                { $$ = build_tree_list (build_tree_list (current_declspecs,
2187                                                         $3),
2188                                        build_tree_list (prefix_attributes,
2189                                                         $4));
2190                  current_declspecs = TREE_VALUE (declspec_stack);
2191                  prefix_attributes = TREE_PURPOSE (declspec_stack);
2192                  declspec_stack = TREE_CHAIN (declspec_stack);
2193                  resume_momentary ($2); }
2194        | declmods setspecs notype_declarator maybe_attribute
2195                { $$ = build_tree_list (build_tree_list (current_declspecs,
2196                                                         $3),
2197                                        build_tree_list (prefix_attributes,
2198                                                         $4));
2199                  current_declspecs = TREE_VALUE (declspec_stack);
2200                  prefix_attributes = TREE_PURPOSE (declspec_stack);
2201                  declspec_stack = TREE_CHAIN (declspec_stack);
2202                  resume_momentary ($2);  }
2203
2204        | declmods setspecs absdcl maybe_attribute
2205                { $$ = build_tree_list (build_tree_list (current_declspecs,
2206                                                         $3),
2207                                        build_tree_list (prefix_attributes,
2208                                                         $4));
2209                  current_declspecs = TREE_VALUE (declspec_stack);
2210                  prefix_attributes = TREE_PURPOSE (declspec_stack);
2211                  declspec_stack = TREE_CHAIN (declspec_stack);
2212                  resume_momentary ($2);  }
2213        ;
2214
2215/* This is used in a function definition
2216   where either a parmlist or an identifier list is ok.
2217   Its value is a list of ..._TYPE nodes or a list of identifiers.  */
2218parmlist_or_identifiers:
2219                { pushlevel (0);
2220                  clear_parm_order ();
2221                  declare_parm_level (1); }
2222          parmlist_or_identifiers_1
2223                { $$ = $2;
2224                  parmlist_tags_warning ();
2225                  poplevel (0, 0, 0); }
2226        ;
2227
2228parmlist_or_identifiers_1:
2229          parmlist_1
2230        | identifiers ')'
2231                { tree t;
2232                  for (t = $1; t; t = TREE_CHAIN (t))
2233                    if (TREE_VALUE (t) == NULL_TREE)
2234                      error ("`...' in old-style identifier list");
2235                  $$ = tree_cons (NULL_TREE, NULL_TREE, $1); }
2236        ;
2237
2238/* A nonempty list of identifiers.  */
2239identifiers:
2240        IDENTIFIER
2241                { $$ = build_tree_list (NULL_TREE, $1); }
2242        | identifiers ',' IDENTIFIER
2243                { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
2244        ;
2245
2246/* A nonempty list of identifiers, including typenames.  */
2247identifiers_or_typenames:
2248        identifier
2249                { $$ = build_tree_list (NULL_TREE, $1); }
2250        | identifiers_or_typenames ',' identifier
2251                { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
2252        ;
2253
2254ifobjc
2255/* Objective-C productions.  */
2256
2257objcdef:
2258          classdef
2259        | classdecl
2260        | aliasdecl
2261        | protocoldef
2262        | methoddef
2263        | END
2264                {
2265                  if (objc_implementation_context)
2266                    {
2267                      finish_class (objc_implementation_context);
2268                      objc_ivar_chain = NULL_TREE;
2269                      objc_implementation_context = NULL_TREE;
2270                    }
2271                  else
2272                    warning ("`@end' must appear in an implementation context");
2273                }
2274        ;
2275
2276/* A nonempty list of identifiers.  */
2277identifier_list:
2278        identifier
2279                { $$ = build_tree_list (NULL_TREE, $1); }
2280        | identifier_list ',' identifier
2281                { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
2282        ;
2283
2284classdecl:
2285          CLASS identifier_list ';'
2286                {
2287                  objc_declare_class ($2);
2288                }
2289
2290aliasdecl:
2291          ALIAS identifier identifier ';'
2292                {
2293                  objc_declare_alias ($2, $3);
2294                }
2295
2296classdef:
2297          INTERFACE identifier protocolrefs '{'
2298                {
2299                  objc_interface_context = objc_ivar_context
2300                    = start_class (CLASS_INTERFACE_TYPE, $2, NULL_TREE, $3);
2301                  objc_public_flag = 0;
2302                }
2303          ivar_decl_list '}'
2304                {
2305                  continue_class (objc_interface_context);
2306                }
2307          methodprotolist
2308          END
2309                {
2310                  finish_class (objc_interface_context);
2311                  objc_interface_context = NULL_TREE;
2312                }
2313
2314        | INTERFACE identifier protocolrefs
2315                {
2316                  objc_interface_context
2317                    = start_class (CLASS_INTERFACE_TYPE, $2, NULL_TREE, $3);
2318                  continue_class (objc_interface_context);
2319                }
2320          methodprotolist
2321          END
2322                {
2323                  finish_class (objc_interface_context);
2324                  objc_interface_context = NULL_TREE;
2325                }
2326
2327        | INTERFACE identifier ':' identifier protocolrefs '{'
2328                {
2329                  objc_interface_context = objc_ivar_context
2330                    = start_class (CLASS_INTERFACE_TYPE, $2, $4, $5);
2331                  objc_public_flag = 0;
2332                }
2333          ivar_decl_list '}'
2334                {
2335                  continue_class (objc_interface_context);
2336                }
2337          methodprotolist
2338          END
2339                {
2340                  finish_class (objc_interface_context);
2341                  objc_interface_context = NULL_TREE;
2342                }
2343
2344        | INTERFACE identifier ':' identifier protocolrefs
2345                {
2346                  objc_interface_context
2347                    = start_class (CLASS_INTERFACE_TYPE, $2, $4, $5);
2348                  continue_class (objc_interface_context);
2349                }
2350          methodprotolist
2351          END
2352                {
2353                  finish_class (objc_interface_context);
2354                  objc_interface_context = NULL_TREE;
2355                }
2356
2357        | IMPLEMENTATION identifier '{'
2358                {
2359                  objc_implementation_context = objc_ivar_context
2360                    = start_class (CLASS_IMPLEMENTATION_TYPE, $2, NULL_TREE, NULL_TREE);
2361                  objc_public_flag = 0;
2362                }
2363          ivar_decl_list '}'
2364                {
2365                  objc_ivar_chain
2366                    = continue_class (objc_implementation_context);
2367                }
2368
2369        | IMPLEMENTATION identifier
2370                {
2371                  objc_implementation_context
2372                    = start_class (CLASS_IMPLEMENTATION_TYPE, $2, NULL_TREE, NULL_TREE);
2373                  objc_ivar_chain
2374                    = continue_class (objc_implementation_context);
2375                }
2376
2377        | IMPLEMENTATION identifier ':' identifier '{'
2378                {
2379                  objc_implementation_context = objc_ivar_context
2380                    = start_class (CLASS_IMPLEMENTATION_TYPE, $2, $4, NULL_TREE);
2381                  objc_public_flag = 0;
2382                }
2383          ivar_decl_list '}'
2384                {
2385                  objc_ivar_chain
2386                    = continue_class (objc_implementation_context);
2387                }
2388
2389        | IMPLEMENTATION identifier ':' identifier
2390                {
2391                  objc_implementation_context
2392                    = start_class (CLASS_IMPLEMENTATION_TYPE, $2, $4, NULL_TREE);
2393                  objc_ivar_chain
2394                    = continue_class (objc_implementation_context);
2395                }
2396
2397        | INTERFACE identifier '(' identifier ')' protocolrefs
2398                {
2399                  objc_interface_context
2400                    = start_class (CATEGORY_INTERFACE_TYPE, $2, $4, $6);
2401                  continue_class (objc_interface_context);
2402                }
2403          methodprotolist
2404          END
2405                {
2406                  finish_class (objc_interface_context);
2407                  objc_interface_context = NULL_TREE;
2408                }
2409
2410        | IMPLEMENTATION identifier '(' identifier ')'
2411                {
2412                  objc_implementation_context
2413                    = start_class (CATEGORY_IMPLEMENTATION_TYPE, $2, $4, NULL_TREE);
2414                  objc_ivar_chain
2415                    = continue_class (objc_implementation_context);
2416                }
2417        ;
2418
2419protocoldef:
2420          PROTOCOL identifier protocolrefs
2421                {
2422                  remember_protocol_qualifiers ();
2423                  objc_interface_context
2424                    = start_protocol(PROTOCOL_INTERFACE_TYPE, $2, $3);
2425                }
2426          methodprotolist END
2427                {
2428                  forget_protocol_qualifiers();
2429                  finish_protocol(objc_interface_context);
2430                  objc_interface_context = NULL_TREE;
2431                }
2432        ;
2433
2434protocolrefs:
2435          /* empty */
2436                {
2437                  $$ = NULL_TREE;
2438                }
2439        | ARITHCOMPARE identifier_list ARITHCOMPARE
2440                {
2441                  if ($1 == LT_EXPR && $3 == GT_EXPR)
2442                    $$ = $2;
2443                  else
2444                    YYERROR1;
2445                }
2446        ;
2447
2448ivar_decl_list:
2449          ivar_decl_list visibility_spec ivar_decls
2450        | ivar_decls
2451        ;
2452
2453visibility_spec:
2454          PRIVATE { objc_public_flag = 2; }
2455        | PROTECTED { objc_public_flag = 0; }
2456        | PUBLIC { objc_public_flag = 1; }
2457        ;
2458
2459ivar_decls:
2460          /* empty */
2461                {
2462                  $$ = NULL_TREE;
2463                }
2464        | ivar_decls ivar_decl ';'
2465        | ivar_decls ';'
2466                {
2467                  if (pedantic)
2468                    pedwarn ("extra semicolon in struct or union specified");
2469                }
2470        ;
2471
2472
2473/* There is a shift-reduce conflict here, because `components' may
2474   start with a `typename'.  It happens that shifting (the default resolution)
2475   does the right thing, because it treats the `typename' as part of
2476   a `typed_typespecs'.
2477
2478   It is possible that this same technique would allow the distinction
2479   between `notype_initdecls' and `initdecls' to be eliminated.
2480   But I am being cautious and not trying it.  */
2481
2482ivar_decl:
2483        typed_typespecs setspecs ivars
2484                { $$ = $3;
2485                  current_declspecs = TREE_VALUE (declspec_stack);
2486                  prefix_attributes = TREE_PURPOSE (declspec_stack);
2487                  declspec_stack = TREE_CHAIN (declspec_stack);
2488                  resume_momentary ($2); }
2489        | nonempty_type_quals setspecs ivars
2490                { $$ = $3;
2491                  current_declspecs = TREE_VALUE (declspec_stack);
2492                  prefix_attributes = TREE_PURPOSE (declspec_stack);
2493                  declspec_stack = TREE_CHAIN (declspec_stack);
2494                  resume_momentary ($2); }
2495        | error
2496                { $$ = NULL_TREE; }
2497        ;
2498
2499ivars:
2500          /* empty */
2501                { $$ = NULL_TREE; }
2502        | ivar_declarator
2503        | ivars ',' ivar_declarator
2504        ;
2505
2506ivar_declarator:
2507          declarator
2508                {
2509                  $$ = add_instance_variable (objc_ivar_context,
2510                                              objc_public_flag,
2511                                              $1, current_declspecs,
2512                                              NULL_TREE);
2513                }
2514        | declarator ':' expr_no_commas
2515                {
2516                  $$ = add_instance_variable (objc_ivar_context,
2517                                              objc_public_flag,
2518                                              $1, current_declspecs, $3);
2519                }
2520        | ':' expr_no_commas
2521                {
2522                  $$ = add_instance_variable (objc_ivar_context,
2523                                              objc_public_flag,
2524                                              NULL_TREE,
2525                                              current_declspecs, $2);
2526                }
2527        ;
2528
2529methoddef:
2530          '+'
2531                {
2532                  remember_protocol_qualifiers ();
2533                  if (objc_implementation_context)
2534                    objc_inherit_code = CLASS_METHOD_DECL;
2535                  else
2536                    fatal ("method definition not in class context");
2537                }
2538          methoddecl
2539                {
2540                  forget_protocol_qualifiers ();
2541                  add_class_method (objc_implementation_context, $3);
2542                  start_method_def ($3);
2543                  objc_method_context = $3;
2544                }
2545          optarglist
2546                {
2547                  continue_method_def ();
2548                }
2549          compstmt_or_error
2550                {
2551                  finish_method_def ();
2552                  objc_method_context = NULL_TREE;
2553                }
2554
2555        | '-'
2556                {
2557                  remember_protocol_qualifiers ();
2558                  if (objc_implementation_context)
2559                    objc_inherit_code = INSTANCE_METHOD_DECL;
2560                  else
2561                    fatal ("method definition not in class context");
2562                }
2563          methoddecl
2564                {
2565                  forget_protocol_qualifiers ();
2566                  add_instance_method (objc_implementation_context, $3);
2567                  start_method_def ($3);
2568                  objc_method_context = $3;
2569                }
2570          optarglist
2571                {
2572                  continue_method_def ();
2573                }
2574          compstmt_or_error
2575                {
2576                  finish_method_def ();
2577                  objc_method_context = NULL_TREE;
2578                }
2579        ;
2580
2581/* the reason for the strange actions in this rule
2582 is so that notype_initdecls when reached via datadef
2583 can find a valid list of type and sc specs in $0. */
2584
2585methodprotolist:
2586          /* empty  */
2587        | {$<ttype>$ = NULL_TREE; } methodprotolist2
2588        ;
2589
2590methodprotolist2:                /* eliminates a shift/reduce conflict */
2591           methodproto
2592        |  datadef
2593        | methodprotolist2 methodproto
2594        | methodprotolist2 {$<ttype>$ = NULL_TREE; } datadef
2595        ;
2596
2597semi_or_error:
2598          ';'
2599        | error
2600        ;
2601
2602methodproto:
2603          '+'
2604                {
2605                  objc_inherit_code = CLASS_METHOD_DECL;
2606                }
2607          methoddecl
2608                {
2609                  add_class_method (objc_interface_context, $3);
2610                }
2611          semi_or_error
2612
2613        | '-'
2614                {
2615                  objc_inherit_code = INSTANCE_METHOD_DECL;
2616                }
2617          methoddecl
2618                {
2619                  add_instance_method (objc_interface_context, $3);
2620                }
2621          semi_or_error
2622        ;
2623
2624methoddecl:
2625          '(' typename ')' unaryselector
2626                {
2627                  $$ = build_method_decl (objc_inherit_code, $2, $4, NULL_TREE);
2628                }
2629
2630        | unaryselector
2631                {
2632                  $$ = build_method_decl (objc_inherit_code, NULL_TREE, $1, NULL_TREE);
2633                }
2634
2635        | '(' typename ')' keywordselector optparmlist
2636                {
2637                  $$ = build_method_decl (objc_inherit_code, $2, $4, $5);
2638                }
2639
2640        | keywordselector optparmlist
2641                {
2642                  $$ = build_method_decl (objc_inherit_code, NULL_TREE, $1, $2);
2643                }
2644        ;
2645
2646/* "optarglist" assumes that start_method_def has already been called...
2647   if it is not, the "xdecls" will not be placed in the proper scope */
2648
2649optarglist:
2650          /* empty */
2651        | ';' myxdecls
2652        ;
2653
2654/* to get around the following situation: "int foo (int a) int b; {}" that
2655   is synthesized when parsing "- a:a b:b; id c; id d; { ... }" */
2656
2657myxdecls:
2658          /* empty */
2659        | mydecls
2660        ;
2661
2662mydecls:
2663        mydecl
2664        | errstmt
2665        | mydecls mydecl
2666        | mydecl errstmt
2667        ;
2668
2669mydecl:
2670        typed_declspecs setspecs myparms ';'
2671                { current_declspecs = TREE_VALUE (declspec_stack);
2672                  prefix_attributes = TREE_PURPOSE (declspec_stack);
2673                  declspec_stack = TREE_CHAIN (declspec_stack);
2674                  resume_momentary ($2); }
2675        | typed_declspecs ';'
2676                { shadow_tag ($1); }
2677        | declmods ';'
2678                { pedwarn ("empty declaration"); }
2679        ;
2680
2681myparms:
2682        myparm
2683                { push_parm_decl ($1); }
2684        | myparms ',' myparm
2685                { push_parm_decl ($3); }
2686        ;
2687
2688/* A single parameter declaration or parameter type name,
2689   as found in a parmlist. DOES NOT ALLOW AN INITIALIZER OR ASMSPEC */
2690
2691myparm:
2692          parm_declarator maybe_attribute
2693                { $$ = build_tree_list (build_tree_list (current_declspecs,
2694                                                         $1),
2695                                        build_tree_list (prefix_attributes,
2696                                                         $2)); }
2697        | notype_declarator maybe_attribute
2698                { $$ = build_tree_list (build_tree_list (current_declspecs,
2699                                                         $1),
2700                                        build_tree_list (prefix_attributes,
2701                                                         $2)); }
2702        | absdcl maybe_attribute
2703                { $$ = build_tree_list (build_tree_list (current_declspecs,
2704                                                         $1),
2705                                        build_tree_list (prefix_attributes,
2706                                                         $2)); }
2707        ;
2708
2709optparmlist:
2710          /* empty */
2711                {
2712                  $$ = NULL_TREE;
2713                }
2714        | ',' ELLIPSIS
2715                {
2716                  /* oh what a kludge! */
2717                  $$ = (tree)1;
2718                }
2719        | ','
2720                {
2721                  pushlevel (0);
2722                }
2723          parmlist_2
2724                {
2725                  /* returns a tree list node generated by get_parm_info */
2726                  $$ = $3;
2727                  poplevel (0, 0, 0);
2728                }
2729        ;
2730
2731unaryselector:
2732          selector
2733        ;
2734
2735keywordselector:
2736          keyworddecl
2737
2738        | keywordselector keyworddecl
2739                {
2740                  $$ = chainon ($1, $2);
2741                }
2742        ;
2743
2744selector:
2745          IDENTIFIER
2746        | TYPENAME
2747        | OBJECTNAME
2748        | reservedwords
2749        ;
2750
2751reservedwords:
2752          ENUM { $$ = get_identifier (token_buffer); }
2753        | STRUCT { $$ = get_identifier (token_buffer); }
2754        | UNION { $$ = get_identifier (token_buffer); }
2755        | IF { $$ = get_identifier (token_buffer); }
2756        | ELSE { $$ = get_identifier (token_buffer); }
2757        | WHILE { $$ = get_identifier (token_buffer); }
2758        | DO { $$ = get_identifier (token_buffer); }
2759        | FOR { $$ = get_identifier (token_buffer); }
2760        | SWITCH { $$ = get_identifier (token_buffer); }
2761        | CASE { $$ = get_identifier (token_buffer); }
2762        | DEFAULT { $$ = get_identifier (token_buffer); }
2763        | BREAK { $$ = get_identifier (token_buffer); }
2764        | CONTINUE { $$ = get_identifier (token_buffer); }
2765        | RETURN  { $$ = get_identifier (token_buffer); }
2766        | GOTO { $$ = get_identifier (token_buffer); }
2767        | ASM_KEYWORD { $$ = get_identifier (token_buffer); }
2768        | SIZEOF { $$ = get_identifier (token_buffer); }
2769        | TYPEOF { $$ = get_identifier (token_buffer); }
2770        | ALIGNOF { $$ = get_identifier (token_buffer); }
2771        | TYPESPEC | TYPE_QUAL
2772        ;
2773
2774keyworddecl:
2775          selector ':' '(' typename ')' identifier
2776                {
2777                  $$ = build_keyword_decl ($1, $4, $6);
2778                }
2779
2780        | selector ':' identifier
2781                {
2782                  $$ = build_keyword_decl ($1, NULL_TREE, $3);
2783                }
2784
2785        | ':' '(' typename ')' identifier
2786                {
2787                  $$ = build_keyword_decl (NULL_TREE, $3, $5);
2788                }
2789
2790        | ':' identifier
2791                {
2792                  $$ = build_keyword_decl (NULL_TREE, NULL_TREE, $2);
2793                }
2794        ;
2795
2796messageargs:
2797          selector
2798        | keywordarglist
2799        ;
2800
2801keywordarglist:
2802          keywordarg
2803        | keywordarglist keywordarg
2804                {
2805                  $$ = chainon ($1, $2);
2806                }
2807        ;
2808
2809
2810keywordexpr:
2811          nonnull_exprlist
2812                {
2813                  if (TREE_CHAIN ($1) == NULL_TREE)
2814                    /* just return the expr., remove a level of indirection */
2815                    $$ = TREE_VALUE ($1);
2816                  else
2817                    /* we have a comma expr., we will collapse later */
2818                    $$ = $1;
2819                }
2820        ;
2821
2822keywordarg:
2823          selector ':' keywordexpr
2824                {
2825                  $$ = build_tree_list ($1, $3);
2826                }
2827        | ':' keywordexpr
2828                {
2829                  $$ = build_tree_list (NULL_TREE, $2);
2830                }
2831        ;
2832
2833receiver:
2834          expr
2835        | CLASSNAME
2836                {
2837                  $$ = get_class_reference ($1);
2838                }
2839        ;
2840
2841objcmessageexpr:
2842          '['
2843                { objc_receiver_context = 1; }
2844          receiver
2845                { objc_receiver_context = 0; }
2846          messageargs ']'
2847                {
2848                  $$ = build_tree_list ($3, $5);
2849                }
2850        ;
2851
2852selectorarg:
2853          selector
2854        | keywordnamelist
2855        ;
2856
2857keywordnamelist:
2858          keywordname
2859        | keywordnamelist keywordname
2860                {
2861                  $$ = chainon ($1, $2);
2862                }
2863        ;
2864
2865keywordname:
2866          selector ':'
2867                {
2868                  $$ = build_tree_list ($1, NULL_TREE);
2869                }
2870        | ':'
2871                {
2872                  $$ = build_tree_list (NULL_TREE, NULL_TREE);
2873                }
2874        ;
2875
2876objcselectorexpr:
2877          SELECTOR '(' selectorarg ')'
2878                {
2879                  $$ = $3;
2880                }
2881        ;
2882
2883objcprotocolexpr:
2884          PROTOCOL '(' identifier ')'
2885                {
2886                  $$ = $3;
2887                }
2888        ;
2889
2890/* extension to support C-structures in the archiver */
2891
2892objcencodeexpr:
2893          ENCODE '(' typename ')'
2894                {
2895                  $$ = groktypename ($3);
2896                }
2897        ;
2898
2899end ifobjc
2900%%
Note: See TracBrowser for help on using the repository browser.