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