|
|
1.1 root 1: /* YACC parser for C syntax.
2: Copyright (C) 1987, 1988, 1989, 1992 Free Software Foundation, Inc.
3: Objective-C extensions by s.naroff.
4:
5: This file is part of GNU CC.
6:
7: GNU CC is free software; you can redistribute it and/or modify
8: it under the terms of the GNU General Public License as published by
9: the Free Software Foundation; either version 2, or (at your option)
10: any later version.
11:
12: GNU CC is distributed in the hope that it will be useful,
13: but WITHOUT ANY WARRANTY; without even the implied warranty of
14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: GNU General Public License for more details.
16:
17: You should have received a copy of the GNU General Public License
18: along with GNU CC; see the file COPYING. If not, write to
19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20:
21:
22: /* To whomever it may concern: I have heard that such a thing was once
23: written by AT&T, but I have never seen it. */
24:
25: %expect 36
26:
27: /* These are the 8 conflicts you should get in parse.output;
28: the state numbers may vary if minor changes in the grammar are made.
29:
30: State 41 contains 1 shift/reduce conflict. (Two ways to recover from error.)
31: State 92 contains 1 shift/reduce conflict. (Two ways to recover from error.)
32: State 99 contains 1 shift/reduce conflict. (Two ways to recover from error.)
33: State 103 contains 1 shift/reduce conflict. (Two ways to recover from error.)
34: State 119 contains 1 shift/reduce conflict. (See comment at component_decl.)
35: State 183 contains 1 shift/reduce conflict. (Two ways to recover from error.)
36: State 193 contains 1 shift/reduce conflict. (Two ways to recover from error.)
37: State 199 contains 1 shift/reduce conflict. (Two ways to recover from error.)
38: */
39:
40: %{
41: #include <stdio.h>
42: #include <errno.h>
43: #include <setjmp.h>
44:
45: #include "config.h"
46: #include "tree.h"
47: #include "input.h"
48: #include "c-lex.h"
49: #include "c-tree.h"
50: #include "flags.h"
51:
52: #include "objc-actions.h"
53:
54: #ifndef errno
55: extern int errno;
56: #endif
57:
58: void yyerror ();
59:
60: /* Like YYERROR but do call yyerror. */
61: #define YYERROR1 { yyerror ("syntax error"); YYERROR; }
62:
63: /* Cause the `yydebug' variable to be defined. */
64: #define YYDEBUG 1
65: %}
66:
67: %start program
68:
69: %union {long itype; tree ttype; enum tree_code code;
70: char *filename; int lineno; }
71:
72: /* All identifiers that are not reserved words
73: and are not declared typedefs in the current block */
74: %token IDENTIFIER
75:
76: /* All identifiers that are declared typedefs in the current block.
77: In some contexts, they are treated just like IDENTIFIER,
78: but they can also serve as typespecs in declarations. */
79: %token TYPENAME
80:
81: /* Reserved words that specify storage class.
82: yylval contains an IDENTIFIER_NODE which indicates which one. */
83: %token SCSPEC
84:
85: /* Reserved words that specify type.
86: yylval contains an IDENTIFIER_NODE which indicates which one. */
87: %token TYPESPEC
88:
89: /* Reserved words that qualify type: "const" or "volatile".
90: yylval contains an IDENTIFIER_NODE which indicates which one. */
91: %token TYPE_QUAL
92:
93: /* Character or numeric constants.
94: yylval is the node for the constant. */
95: %token CONSTANT
96:
97: /* String constants in raw form.
98: yylval is a STRING_CST node. */
99: %token STRING
100:
101: /* "...", used for functions with variable arglists. */
102: %token ELLIPSIS
103:
104: /* the reserved words */
105: %token SIZEOF ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT
106: %token BREAK CONTINUE RETURN GOTO ASM TYPEOF ALIGNOF ALIGN
107: %token ATTRIBUTE EXTENSION LABEL
108:
109: /* Add precedence rules to solve dangling else s/r conflict */
110: %nonassoc IF
111: %nonassoc ELSE
112:
113: /* Define the operator tokens and their precedences.
114: The value is an integer because, if used, it is the tree code
115: to use in the expression made from the operator. */
116:
117: %right <code> ASSIGN '='
118: %right <code> '?' ':'
119: %left <code> OROR
120: %left <code> ANDAND
121: %left <code> '|'
122: %left <code> '^'
123: %left <code> '&'
124: %left <code> EQCOMPARE
125: %left <code> ARITHCOMPARE
126: %left <code> LSHIFT RSHIFT
127: %left <code> '+' '-'
128: %left <code> '*' '/' '%'
129: %right <code> UNARY PLUSPLUS MINUSMINUS
130: %left HYPERUNARY
131: %left <code> POINTSAT '.' '(' '['
132:
133: /* the Objective-C keywords */
134: %token INTERFACE IMPLEMENTATION END SELECTOR DEFS ENCODE
135: %token CLASSNAME PUBLIC
136:
137:
138: %type <code> unop
139:
140: %type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist exprlist
141: %type <ttype> expr_no_commas cast_expr unary_expr primary string STRING
142: %type <ttype> typed_declspecs reserved_declspecs
143: %type <ttype> typed_typespecs reserved_typespecquals
144: %type <ttype> declmods typespec typespecqual_reserved
145: %type <ttype> SCSPEC TYPESPEC TYPE_QUAL nonempty_type_quals maybe_type_qual
146: %type <ttype> initdecls notype_initdecls initdcl notype_initdcl
147: %type <ttype> init initlist maybeasm
148: %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
149: %type <ttype> maybe_attribute attribute_list attrib
150:
151: %type <ttype> compstmt
152:
153: %type <ttype> declarator
154: %type <ttype> notype_declarator after_type_declarator
155: %type <ttype> parm_declarator
156:
157: %type <ttype> structsp component_decl_list component_decl_list2
158: %type <ttype> component_decl components component_declarator
159: %type <ttype> enumlist enumerator
160: %type <ttype> typename absdcl absdcl1 type_quals
161: %type <ttype> xexpr parms parm identifiers
162:
163: %type <ttype> parmlist parmlist_1 parmlist_2
164: %type <ttype> parmlist_or_identifiers parmlist_or_identifiers_1
165:
166: %type <itype> setspecs
167:
168: %type <filename> save_filename
169: %type <lineno> save_lineno
170:
171: /* the Objective-C nonterminals */
172:
173: %type <ttype> ivar_decl_list ivar_decls ivar_decl ivars ivar_declarator
174: %type <ttype> methoddecl unaryselector keywordselector selector
175: %type <ttype> keyworddecl receiver objcmessageexpr messageargs
176: %type <ttype> keywordexpr keywordarglist keywordarg
177: %type <ttype> myparms myparm optparmlist reservedwords objcselectorexpr
178: %type <ttype> selectorarg keywordnamelist keywordname objcencodeexpr
179: %type <ttype> CLASSNAME
180:
181: %{
182: /* Number of statements (loosely speaking) seen so far. */
183: static int stmt_count;
184:
185: /* Input file and line number of the end of the body of last simple_if;
186: used by the stmt-rule immediately after simple_if returns. */
187: static char *if_stmt_file;
188: static int if_stmt_line;
189:
190: /* List of types and structure classes of the current declaration. */
191: static tree current_declspecs;
192:
193: /* Stack of saved values of current_declspecs. */
194: static tree declspec_stack;
195:
196: /* 1 if we explained undeclared var errors. */
197: static int undeclared_variable_notice;
198:
199: /* Objective-C specific information */
200:
201: tree objc_interface_context;
202: tree objc_implementation_context;
203: tree objc_method_context;
204: tree objc_ivar_chain;
205: tree objc_ivar_context;
206: enum tree_code objc_inherit_code;
207: int objc_receiver_context;
208: int objc_public_flag;
209:
210: /* Tell yyparse how to print a token's value, if yydebug is set. */
211:
212: #define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL)
213: extern void yyprint ();
214: %}
215:
216: %%
217: program: /* empty */
218: { if (pedantic)
219: pedwarn ("ANSI C forbids an empty source file");
220: objc_finish (); }
221: | extdefs
222: { objc_finish (); }
223: ;
224:
225: /* the reason for the strange actions in this rule
226: is so that notype_initdecls when reached via datadef
227: can find a valid list of type and sc specs in $0. */
228:
229: extdefs:
230: {$<ttype>$ = NULL_TREE; } extdef
231: | extdefs {$<ttype>$ = NULL_TREE; } extdef
232: ;
233:
234: extdef:
235: fndef
236: | datadef
237: | objcdef
238: | ASM '(' string ')' ';'
239: { if (pedantic)
240: pedwarn ("ANSI C forbids use of `asm' keyword");
241: if (TREE_CHAIN ($3)) $3 = combine_strings ($3);
242: assemble_asm ($3); }
243: ;
244:
245: datadef:
246: setspecs notype_initdecls ';'
247: { if (pedantic)
248: error ("ANSI C forbids data definition with no type or storage class");
249: else if (!flag_traditional)
250: warning ("data definition has no type or storage class"); }
251: | declmods setspecs notype_initdecls ';'
252: {}
253: | typed_declspecs setspecs initdecls ';'
254: {}
255: | declmods ';'
256: { error ("empty declaration"); }
257: | typed_declspecs ';'
258: { shadow_tag ($1); }
259: | error ';'
260: | error '}'
261: | ';'
262: { if (pedantic)
263: pedwarn ("ANSI C does not allow extra `;' outside of a function"); }
264: ;
265:
266: fndef:
267: typed_declspecs setspecs declarator
268: { if (! start_function ($1, $3, 0))
269: YYERROR1;
270: reinit_parse_for_function (); }
271: xdecls
272: { store_parm_decls (); }
273: compstmt_or_error
274: { finish_function (0); }
275: | typed_declspecs setspecs declarator error
276: { }
277: | declmods setspecs notype_declarator
278: { if (! start_function ($1, $3, 0))
279: YYERROR1;
280: reinit_parse_for_function (); }
281: xdecls
282: { store_parm_decls (); }
283: compstmt_or_error
284: { finish_function (0); }
285: | declmods setspecs notype_declarator error
286: { }
287: | setspecs notype_declarator
288: { if (! start_function (0, $2, 0))
289: YYERROR1;
290: reinit_parse_for_function (); }
291: xdecls
292: { store_parm_decls (); }
293: compstmt_or_error
294: { finish_function (0); }
295: | setspecs notype_declarator error
296: { }
297: ;
298:
299: identifier:
300: IDENTIFIER
301: | TYPENAME
302: | CLASSNAME
303: { $$ = CLASS_NAME ($1); }
304: ;
305:
306: unop: '&'
307: { $$ = ADDR_EXPR; }
308: | '-'
309: { $$ = NEGATE_EXPR; }
310: | '+'
311: { $$ = CONVERT_EXPR; }
312: | PLUSPLUS
313: { $$ = PREINCREMENT_EXPR; }
314: | MINUSMINUS
315: { $$ = PREDECREMENT_EXPR; }
316: | '~'
317: { $$ = BIT_NOT_EXPR; }
318: | '!'
319: { $$ = TRUTH_NOT_EXPR; }
320: ;
321:
322: expr: nonnull_exprlist
323: { $$ = build_compound_expr ($1); }
324: ;
325:
326: exprlist:
327: /* empty */
328: { $$ = NULL_TREE; }
329: | nonnull_exprlist
330: ;
331:
332: nonnull_exprlist:
333: expr_no_commas
334: { $$ = build_tree_list (NULL_TREE, $1); }
335: | nonnull_exprlist ',' expr_no_commas
336: { chainon ($1, build_tree_list (NULL_TREE, $3)); }
337: ;
338:
339: unary_expr:
340: primary
341: | '*' cast_expr %prec UNARY
342: { $$ = build_indirect_ref ($2, "unary *"); }
343: /* __extension__ turns off -pedantic for following primary. */
344: | EXTENSION
345: { $<itype>1 = pedantic;
346: pedantic = 0; }
347: cast_expr %prec UNARY
348: { $$ = $3;
349: pedantic = $<itype>1; }
350: | unop cast_expr %prec UNARY
351: { $$ = build_unary_op ($1, $2, 0); }
352: /* Refer to the address of a label as a pointer. */
353: | ANDAND identifier
354: { tree label = lookup_label ($2);
355: TREE_USED (label) = 1;
356: $$ = build1 (ADDR_EXPR, ptr_type_node, label);
357: TREE_CONSTANT ($$) = 1; }
358: /* This seems to be impossible on some machines, so let's turn it off.
359: | '&' ELLIPSIS
360: { tree types = TYPE_ARG_TYPES (TREE_TYPE (current_function_decl));
361: $$ = error_mark_node;
362: if (TREE_VALUE (tree_last (types)) == void_type_node)
363: error ("`&...' used in function with fixed number of arguments");
364: else
365: {
366: if (pedantic)
367: pedwarn ("ANSI C forbids `&...'");
368: $$ = tree_last (DECL_ARGUMENTS (current_function_decl));
369: $$ = build_unary_op (ADDR_EXPR, $$, 0);
370: } }
371: */
372: | SIZEOF unary_expr %prec UNARY
373: { if (TREE_CODE ($2) == COMPONENT_REF
374: && DECL_BIT_FIELD (TREE_OPERAND ($2, 1)))
375: error ("`sizeof' applied to a bit-field");
376: $$ = c_sizeof (TREE_TYPE ($2)); }
377: | SIZEOF '(' typename ')' %prec HYPERUNARY
378: { $$ = c_sizeof (groktypename ($3)); }
379: | ALIGNOF unary_expr %prec UNARY
380: { $$ = c_alignof_expr ($2); }
381: | ALIGNOF '(' typename ')' %prec HYPERUNARY
382: { $$ = c_alignof (groktypename ($3)); }
383: ;
384:
385: cast_expr:
386: unary_expr
387: | '(' typename ')' cast_expr %prec UNARY
388: { tree type = groktypename ($2);
389: $$ = build_c_cast (type, $4); }
390: | '(' typename ')' '{' initlist maybecomma '}' %prec UNARY
391: { tree type = groktypename ($2);
392: if (pedantic)
393: pedwarn ("ANSI C forbids constructor expressions");
394: $$ = digest_init (type, build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($5)), 0, 0, 0);
395: if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (type) == 0)
396: {
397: int failure = complete_array_type (type, $$, 1);
398: if (failure)
399: abort ();
400: }
401: }
402: ;
403:
404: expr_no_commas:
405: cast_expr
406: | expr_no_commas '+' expr_no_commas
407: { $$ = parser_build_binary_op ($2, $1, $3); }
408: | expr_no_commas '-' expr_no_commas
409: { $$ = parser_build_binary_op ($2, $1, $3); }
410: | expr_no_commas '*' expr_no_commas
411: { $$ = parser_build_binary_op ($2, $1, $3); }
412: | expr_no_commas '/' expr_no_commas
413: { $$ = parser_build_binary_op ($2, $1, $3); }
414: | expr_no_commas '%' expr_no_commas
415: { $$ = parser_build_binary_op ($2, $1, $3); }
416: | expr_no_commas LSHIFT expr_no_commas
417: { $$ = parser_build_binary_op ($2, $1, $3); }
418: | expr_no_commas RSHIFT expr_no_commas
419: { $$ = parser_build_binary_op ($2, $1, $3); }
420: | expr_no_commas ARITHCOMPARE expr_no_commas
421: { $$ = parser_build_binary_op ($2, $1, $3); }
422: | expr_no_commas EQCOMPARE expr_no_commas
423: { $$ = parser_build_binary_op ($2, $1, $3); }
424: | expr_no_commas '&' expr_no_commas
425: { $$ = parser_build_binary_op ($2, $1, $3); }
426: | expr_no_commas '|' expr_no_commas
427: { $$ = parser_build_binary_op ($2, $1, $3); }
428: | expr_no_commas '^' expr_no_commas
429: { $$ = parser_build_binary_op ($2, $1, $3); }
430: | expr_no_commas ANDAND expr_no_commas
431: { $$ = parser_build_binary_op (TRUTH_ANDIF_EXPR, $1, $3); }
432: | expr_no_commas OROR expr_no_commas
433: { $$ = parser_build_binary_op (TRUTH_ORIF_EXPR, $1, $3); }
434: | expr_no_commas '?' xexpr ':' expr_no_commas
435: { $$ = build_conditional_expr ($1, $3, $5); }
436: | expr_no_commas '=' expr_no_commas
437: { $$ = build_modify_expr ($1, NOP_EXPR, $3); }
438: | expr_no_commas ASSIGN expr_no_commas
439: { $$ = build_modify_expr ($1, $2, $3); }
440: ;
441:
442: primary:
443: IDENTIFIER
444: {
445: tree context;
446:
447: $$ = lastiddecl;
448: if (!$$ || $$ == error_mark_node)
449: {
450: if (yychar == YYEMPTY)
451: yychar = YYLEX;
452: if (yychar == '(')
453: {
454: if (objc_receiver_context
455: && ! (objc_receiver_context
456: && strcmp (IDENTIFIER_POINTER ($1), "super")))
457: /* we have a message to super */
458: $$ = get_super_receiver ();
459: else if (objc_method_context
460: && is_ivar (objc_ivar_chain, $1))
461: $$ = build_ivar_reference ($1);
462: else
463: {
464: /* Ordinary implicit function declaration. */
465: $$ = implicitly_declare ($1);
466: assemble_external ($$);
467: TREE_USED ($$) = 1;
468: }
469: }
470: else if (current_function_decl == 0)
471: {
472: error ("`%s' undeclared, outside of functions",
473: IDENTIFIER_POINTER ($1));
474: $$ = error_mark_node;
475: }
476: else
477: {
478: if (objc_receiver_context
479: && ! (objc_receiver_context
480: && strcmp (IDENTIFIER_POINTER ($1), "super")))
481: /* we have a message to super */
482: $$ = get_super_receiver ();
483: else if (objc_method_context
484: && is_ivar (objc_ivar_chain, $1))
485: $$ = build_ivar_reference ($1);
486: else
487: {
488: if (IDENTIFIER_GLOBAL_VALUE ($1) != error_mark_node
489: || IDENTIFIER_ERROR_LOCUS ($1) != current_function_decl)
490: {
491: error ("`%s' undeclared (first use this function)",
492: IDENTIFIER_POINTER ($1));
493:
494: if (! undeclared_variable_notice)
495: {
496: error ("(Each undeclared identifier is reported only once");
497: error ("for each function it appears in.)");
498: undeclared_variable_notice = 1;
499: }
500: }
501: $$ = error_mark_node;
502: /* Prevent repeated error messages. */
503: IDENTIFIER_GLOBAL_VALUE ($1) = error_mark_node;
504: IDENTIFIER_ERROR_LOCUS ($1) = current_function_decl;
505: }
506: }
507: }
508: else
509: {
510: if (! TREE_USED ($$))
511: {
512: if (TREE_EXTERNAL ($$))
513: assemble_external ($$);
514: TREE_USED ($$) = 1;
515: }
516: /* we have a definition - still check if iVariable */
517:
518: if (!objc_receiver_context
519: || (objc_receiver_context
520: && strcmp (IDENTIFIER_POINTER ($1), "super")))
521: {
522: if (objc_method_context
523: && is_ivar (objc_ivar_chain, $1))
524: {
525: if (IDENTIFIER_LOCAL_VALUE ($1))
526: warning ("local declaration of `%s' hides instance variable",
527: IDENTIFIER_POINTER ($1));
528: else
529: $$ = build_ivar_reference ($1);
530: }
531: }
532: else /* we have a message to super */
533: $$ = get_super_receiver ();
534: }
535:
536: if (TREE_CODE ($$) == CONST_DECL)
537: $$ = DECL_INITIAL ($$);
538: }
539: | CONSTANT
540: | string
541: { $$ = combine_strings ($1); }
542: | '(' expr ')'
543: { char class = TREE_CODE_CLASS (TREE_CODE ($2));
544: if (class == 'e' || class == '1'
545: || class == '2' || class == '<')
546: C_SET_EXP_ORIGINAL_CODE ($2, ERROR_MARK);
547: $$ = $2; }
548: | '(' error ')'
549: { $$ = error_mark_node; }
550: | '('
551: { if (current_function_decl == 0)
552: {
553: error ("braced-group within expression allowed only inside a function");
554: YYERROR;
555: }
556: /* We must force a BLOCK for this level
557: so that, if it is not expanded later,
558: there is a way to turn off the entire subtree of blocks
559: that are contained in it. */
560: keep_next_level ();
561: push_label_level ();
562: $<ttype>$ = expand_start_stmt_expr (); }
563: compstmt ')'
564: { tree rtl_exp;
565: if (pedantic)
566: pedwarn ("ANSI C forbids braced-groups within expressions");
567: pop_label_level ();
568: rtl_exp = expand_end_stmt_expr ($<ttype>2);
569: /* The statements have side effects, so the group does. */
570: TREE_SIDE_EFFECTS (rtl_exp) = 1;
571:
572: /* Make a BIND_EXPR for the BLOCK already made. */
573: $$ = build (BIND_EXPR, TREE_TYPE (rtl_exp),
574: NULL_TREE, rtl_exp, $3);
575: }
576: | primary '(' exprlist ')' %prec '.'
577: { $$ = build_function_call ($1, $3); }
578: | primary '[' expr ']' %prec '.'
579: { $$ = build_array_ref ($1, $3); }
580: | primary '.' identifier
581: {
582: if (doing_objc_thang)
583: {
584: if (is_public ($1, $3))
585: $$ = build_component_ref ($1, $3);
586: else
587: $$ = error_mark_node;
588: }
589: else
590: $$ = build_component_ref ($1, $3);
591: }
592: | primary POINTSAT identifier
593: {
594: tree anExpr = build_indirect_ref ($1, "->");
595:
596: if (doing_objc_thang)
597: {
598: if (is_public (anExpr, $3))
599: $$ = build_component_ref (anExpr, $3);
600: else
601: $$ = error_mark_node;
602: }
603: else
604: $$ = build_component_ref (anExpr, $3);
605: }
606: | primary PLUSPLUS
607: { $$ = build_unary_op (POSTINCREMENT_EXPR, $1, 0); }
608: | primary MINUSMINUS
609: { $$ = build_unary_op (POSTDECREMENT_EXPR, $1, 0); }
610: | objcmessageexpr
611: { $$ = build_message_expr ($1); }
612: | objcselectorexpr
613: { $$ = build_selector_expr ($1); }
614: | objcencodeexpr
615: { $$ = build_encode_expr ($1); }
616: ;
617:
618: /* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it. */
619: string:
620: STRING
621: | string STRING
622: { $$ = chainon ($1, $2); }
623: ;
624:
625: xdecls:
626: /* empty */
627: | decls
628: | decls ELLIPSIS
629: /* ... is used here to indicate a varargs function. */
630: { c_mark_varargs ();
631: if (pedantic)
632: pedwarn ("ANSI C does not permit use of `varargs.h'"); }
633: ;
634:
635: /* This combination which saves a lineno before a decl
636: is the normal thing to use, rather than decl itself.
637: This is to avoid shift/reduce conflicts in contexts
638: where statement labels are allowed. */
639: lineno_decl:
640: save_filename save_lineno decl
641: { }
642: ;
643:
644: decls:
645: lineno_decl
646: | errstmt
647: | decls lineno_decl
648: | lineno_decl errstmt
649: ;
650:
651: /* records the type and storage class specs to use for processing
652: the declarators that follow.
653: Maintains a stack of outer-level values of current_declspecs,
654: for the sake of parm declarations nested in function declarators. */
655: setspecs: /* empty */
656: { $$ = suspend_momentary ();
657: pending_xref_error ();
658: declspec_stack = tree_cons (0, current_declspecs,
659: declspec_stack);
660: current_declspecs = $<ttype>0; }
661: ;
662:
663: decl:
664: typed_declspecs setspecs initdecls ';'
665: { current_declspecs = TREE_VALUE (declspec_stack);
666: declspec_stack = TREE_CHAIN (declspec_stack);
667: resume_momentary ($2); }
668: | declmods setspecs notype_initdecls ';'
669: { current_declspecs = TREE_VALUE (declspec_stack);
670: declspec_stack = TREE_CHAIN (declspec_stack);
671: resume_momentary ($2); }
672: | typed_declspecs setspecs nested_function
673: { current_declspecs = TREE_VALUE (declspec_stack);
674: declspec_stack = TREE_CHAIN (declspec_stack);
675: resume_momentary ($2); }
676: | declmods setspecs notype_nested_function
677: { current_declspecs = TREE_VALUE (declspec_stack);
678: declspec_stack = TREE_CHAIN (declspec_stack);
679: resume_momentary ($2); }
680: | typed_declspecs ';'
681: { shadow_tag ($1); }
682: | declmods ';'
683: { pedwarn ("empty declaration"); }
684: ;
685:
686: /* Declspecs which contain at least one type specifier or typedef name.
687: (Just `const' or `volatile' is not enough.)
688: A typedef'd name following these is taken as a name to be declared. */
689:
690: typed_declspecs:
691: typespec reserved_declspecs
692: { $$ = tree_cons (NULL_TREE, $1, $2); }
693: | declmods typespec reserved_declspecs
694: { $$ = chainon ($3, tree_cons (NULL_TREE, $2, $1)); }
695: ;
696:
697: reserved_declspecs: /* empty */
698: { $$ = NULL_TREE; }
699: | reserved_declspecs typespecqual_reserved
700: { $$ = tree_cons (NULL_TREE, $2, $1); }
701: | reserved_declspecs SCSPEC
702: { $$ = tree_cons (NULL_TREE, $2, $1); }
703: ;
704:
705: /* List of just storage classes and type modifiers.
706: A declaration can start with just this, but then it cannot be used
707: to redeclare a typedef-name. */
708:
709: declmods:
710: TYPE_QUAL
711: { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
712: | SCSPEC
713: { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
714: | declmods TYPE_QUAL
715: { $$ = tree_cons (NULL_TREE, $2, $1); }
716: | declmods SCSPEC
717: { $$ = tree_cons (NULL_TREE, $2, $1); }
718: ;
719:
720:
721: /* Used instead of declspecs where storage classes are not allowed
722: (that is, for typenames and structure components).
723: Don't accept a typedef-name if anything but a modifier precedes it. */
724:
725: typed_typespecs:
726: typespec reserved_typespecquals
727: { $$ = tree_cons (NULL_TREE, $1, $2); }
728: | nonempty_type_quals typespec reserved_typespecquals
729: { $$ = chainon ($3, tree_cons (NULL_TREE, $2, $1)); }
730: ;
731:
732: reserved_typespecquals: /* empty */
733: { $$ = NULL_TREE; }
734: | reserved_typespecquals typespecqual_reserved
735: { $$ = tree_cons (NULL_TREE, $2, $1); }
736: ;
737:
738: /* A typespec (but not a type qualifier).
739: Once we have seen one of these in a declaration,
740: if a typedef name appears then it is being redeclared. */
741:
742: typespec: TYPESPEC
743: | structsp
744: | TYPENAME
745: | CLASSNAME
746: { $$ = get_static_reference ($1); }
747: | TYPEOF '(' expr ')'
748: { $$ = TREE_TYPE ($3);
749: if (pedantic)
750: pedwarn ("ANSI C forbids `typeof'"); }
751: | TYPEOF '(' typename ')'
752: { $$ = groktypename ($3);
753: if (pedantic)
754: pedwarn ("ANSI C forbids `typeof'"); }
755: ;
756:
757: /* A typespec that is a reserved word, or a type qualifier. */
758:
759: typespecqual_reserved: TYPESPEC
760: | TYPE_QUAL
761: | structsp
762: ;
763:
764: initdecls:
765: initdcl
766: | initdecls ',' initdcl
767: ;
768:
769: notype_initdecls:
770: notype_initdcl
771: | notype_initdecls ',' initdcl
772: ;
773:
774: maybeasm:
775: /* empty */
776: { $$ = NULL_TREE; }
777: | ASM '(' string ')'
778: { if (TREE_CHAIN ($3)) $3 = combine_strings ($3);
779: $$ = $3;
780: if (pedantic)
781: pedwarn ("ANSI C forbids use of `asm' keyword");
782: }
783: ;
784:
785: initdcl:
786: declarator maybeasm maybe_attribute '='
787: { $<ttype>$ = start_decl ($1, current_declspecs, 1); }
788: init
789: /* Note how the declaration of the variable is in effect while its init is parsed! */
790: { decl_attributes ($<ttype>5, $3);
791: finish_decl ($<ttype>5, $6, $2); }
792: | declarator maybeasm maybe_attribute
793: { tree d = start_decl ($1, current_declspecs, 0);
794: decl_attributes (d, $3);
795: finish_decl (d, NULL_TREE, $2); }
796: ;
797:
798: notype_initdcl:
799: notype_declarator maybeasm maybe_attribute '='
800: { $<ttype>$ = start_decl ($1, current_declspecs, 1); }
801: init
802: /* Note how the declaration of the variable is in effect while its init is parsed! */
803: { decl_attributes ($<ttype>5, $3);
804: finish_decl ($<ttype>5, $6, $2); }
805: | notype_declarator maybeasm maybe_attribute
806: { tree d = start_decl ($1, current_declspecs, 0);
807: decl_attributes (d, $3);
808: finish_decl (d, NULL_TREE, $2); }
809: ;
810: /* the * rules are dummies to accept the Apollo extended syntax
811: so that the header files compile. */
812: maybe_attribute:
813: /* empty */
814: { $$ = NULL_TREE; }
815: | ATTRIBUTE '(' '(' attribute_list ')' ')'
816: { $$ = $4; }
817: ;
818:
819: attribute_list
820: : attrib
821: { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
822: | attribute_list ',' attrib
823: { $$ = tree_cons (NULL_TREE, $3, $1); }
824: ;
825:
826: attrib
827: : IDENTIFIER
828: { warning ("`%s' attribute directive ignored",
829: IDENTIFIER_POINTER ($1));
830: $$ = $1; }
831: | IDENTIFIER '(' CONSTANT ')'
832: { /* if not "aligned(n)", then issue warning */
833: if (strcmp (IDENTIFIER_POINTER ($1), "aligned") != 0
834: || TREE_CODE ($3) != INTEGER_CST)
835: {
836: warning ("`%s' attribute directive ignored",
837: IDENTIFIER_POINTER ($1));
838: $$ = $1;
839: }
840: else
841: $$ = tree_cons ($1, $3); }
842: | IDENTIFIER '(' IDENTIFIER ',' CONSTANT ',' CONSTANT ')'
843: { /* if not "format(...)", then issue warning */
844: if (strcmp (IDENTIFIER_POINTER ($1), "format") != 0
845: || TREE_CODE ($5) != INTEGER_CST
846: || TREE_CODE ($7) != INTEGER_CST)
847: {
848: warning ("`%s' attribute directive ignored",
849: IDENTIFIER_POINTER ($1));
850: $$ = $1;
851: }
852: else
853: $$ = tree_cons ($1, tree_cons ($3, tree_cons ($5, $7))); }
854: ;
855:
856: init:
857: expr_no_commas
858: | '{' '}'
859: { $$ = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE);
860: if (pedantic)
861: pedwarn ("ANSI C forbids empty initializer braces"); }
862: | '{' initlist '}'
863: { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); }
864: | '{' initlist ',' '}'
865: { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); }
866: | error
867: { $$ = NULL_TREE; }
868: ;
869:
870: /* This chain is built in reverse order,
871: and put in forward order where initlist is used. */
872: initlist:
873: init
874: { $$ = build_tree_list (NULL_TREE, $1); }
875: | initlist ',' init
876: { $$ = tree_cons (NULL_TREE, $3, $1); }
877: /* These are for labeled elements. */
878: | '[' expr_no_commas ']' init
879: { $$ = build_tree_list ($2, $4); }
880: | initlist ',' CASE expr_no_commas ':' init
881: { $$ = tree_cons ($4, $6, $1); }
882: | identifier ':' init
883: { $$ = build_tree_list ($1, $3); }
884: | initlist ',' identifier ':' init
885: { $$ = tree_cons ($3, $5, $1); }
886: ;
887:
888: nested_function:
889: declarator
890: { push_c_function_context ();
891: if (! start_function (current_declspecs, $1, 1))
892: {
893: pop_c_function_context ();
894: YYERROR1;
895: }
896: reinit_parse_for_function ();
897: store_parm_decls (); }
898: /* This used to use compstmt_or_error.
899: That caused a bug with input `f(g) int g {}',
900: where the use of YYERROR1 above caused an error
901: which then was handled by compstmt_or_error.
902: There followed a repeated execution of that same rule,
903: which called YYERROR1 again, and so on. */
904: compstmt
905: { finish_function (1);
906: pop_c_function_context (); }
907: ;
908:
909: notype_nested_function:
910: notype_declarator
911: { push_c_function_context ();
912: if (! start_function (current_declspecs, $1, 1))
913: {
914: pop_c_function_context ();
915: YYERROR1;
916: }
917: reinit_parse_for_function ();
918: store_parm_decls (); }
919: /* This used to use compstmt_or_error.
920: That caused a bug with input `f(g) int g {}',
921: where the use of YYERROR1 above caused an error
922: which then was handled by compstmt_or_error.
923: There followed a repeated execution of that same rule,
924: which called YYERROR1 again, and so on. */
925: compstmt
926: { finish_function (1);
927: pop_c_function_context (); }
928: ;
929:
930: /* Any kind of declarator (thus, all declarators allowed
931: after an explicit typespec). */
932:
933: declarator:
934: after_type_declarator
935: | notype_declarator
936: ;
937:
938: /* A declarator that is allowed only after an explicit typespec. */
939:
940: after_type_declarator:
941: '(' after_type_declarator ')'
942: { $$ = $2; }
943: | after_type_declarator '(' parmlist_or_identifiers %prec '.'
944: { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
945: /* | after_type_declarator '(' error ')' %prec '.'
946: { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
947: poplevel (0, 0, 0); } */
948: | after_type_declarator '[' expr ']' %prec '.'
949: { $$ = build_nt (ARRAY_REF, $1, $3); }
950: | after_type_declarator '[' ']' %prec '.'
951: { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
952: | '*' type_quals after_type_declarator %prec UNARY
953: { $$ = make_pointer_declarator ($2, $3); }
954: | TYPENAME
955: ;
956:
957: /* Kinds of declarator that can appear in a parameter list
958: in addition to notype_declarator. This is like after_type_declarator
959: but does not allow a typedef name in parentheses as an identifier
960: (because it would conflict with a function with that typedef as arg). */
961:
962: parm_declarator:
963: parm_declarator '(' parmlist_or_identifiers %prec '.'
964: { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
965: /* | parm_declarator '(' error ')' %prec '.'
966: { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
967: poplevel (0, 0, 0); } */
968: | parm_declarator '[' expr ']' %prec '.'
969: { $$ = build_nt (ARRAY_REF, $1, $3); }
970: | parm_declarator '[' ']' %prec '.'
971: { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
972: | '*' type_quals parm_declarator %prec UNARY
973: { $$ = make_pointer_declarator ($2, $3); }
974: | TYPENAME
975: ;
976:
977: /* A declarator allowed whether or not there has been
978: an explicit typespec. These cannot redeclare a typedef-name. */
979:
980: notype_declarator:
981: notype_declarator '(' parmlist_or_identifiers %prec '.'
982: { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
983: /* | notype_declarator '(' error ')' %prec '.'
984: { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
985: poplevel (0, 0, 0); } */
986: | '(' notype_declarator ')'
987: { $$ = $2; }
988: | '*' type_quals notype_declarator %prec UNARY
989: { $$ = make_pointer_declarator ($2, $3); }
990: | notype_declarator '[' expr ']' %prec '.'
991: { $$ = build_nt (ARRAY_REF, $1, $3); }
992: | notype_declarator '[' ']' %prec '.'
993: { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
994: | IDENTIFIER
995: ;
996:
997: structsp:
998: STRUCT identifier '{'
999: { $$ = start_struct (RECORD_TYPE, $2);
1000: /* Start scope of tag before parsing components. */
1001: }
1002: component_decl_list '}'
1003: { $$ = finish_struct ($<ttype>4, $5);
1004: /* Really define the structure. */
1005: }
1006: | STRUCT '{' component_decl_list '}'
1007: { $$ = finish_struct (start_struct (RECORD_TYPE, NULL_TREE),
1008: $3); }
1009: | STRUCT identifier
1010: { $$ = xref_tag (RECORD_TYPE, $2); }
1011: | UNION identifier '{'
1012: { $$ = start_struct (UNION_TYPE, $2); }
1013: component_decl_list '}'
1014: { $$ = finish_struct ($<ttype>4, $5); }
1015: | UNION '{' component_decl_list '}'
1016: { $$ = finish_struct (start_struct (UNION_TYPE, NULL_TREE),
1017: $3); }
1018: | UNION identifier
1019: { $$ = xref_tag (UNION_TYPE, $2); }
1020: | ENUM identifier '{'
1021: { $<itype>3 = suspend_momentary ();
1022: $$ = start_enum ($2); }
1023: enumlist maybecomma_warn '}'
1024: { $$ = finish_enum ($<ttype>4, nreverse ($5));
1025: resume_momentary ($<itype>3); }
1026: | ENUM '{'
1027: { $<itype>2 = suspend_momentary ();
1028: $$ = start_enum (NULL_TREE); }
1029: enumlist maybecomma_warn '}'
1030: { $$ = finish_enum ($<ttype>3, nreverse ($4));
1031: resume_momentary ($<itype>2); }
1032: | ENUM identifier
1033: { $$ = xref_tag (ENUMERAL_TYPE, $2); }
1034: ;
1035:
1036: maybecomma:
1037: /* empty */
1038: | ','
1039: ;
1040:
1041: maybecomma_warn:
1042: /* empty */
1043: | ','
1044: { if (pedantic) pedwarn ("comma at end of enumerator list"); }
1045: ;
1046:
1047: component_decl_list:
1048: component_decl_list2
1049: { $$ = $1; }
1050: | component_decl_list2 component_decl
1051: { $$ = chainon ($1, $2);
1052: warning ("no semicolon at end of struct or union"); }
1053: ;
1054:
1055: component_decl_list2: /* empty */
1056: { $$ = NULL_TREE; }
1057: | component_decl_list2 component_decl ';'
1058: { $$ = chainon ($1, $2); }
1059: | component_decl_list2 ';'
1060: { if (pedantic)
1061: warning ("extra semicolon in struct or union specified"); }
1062: /* foo(sizeof(struct{ @defs(ClassName)})); */
1063: | DEFS '(' CLASSNAME ')'
1064: { $$ = get_class_ivars ($3); }
1065: ;
1066:
1067: /* There is a shift-reduce conflict here, because `components' may
1068: start with a `typename'. It happens that shifting (the default resolution)
1069: does the right thing, because it treats the `typename' as part of
1070: a `typed_typespecs'.
1071:
1072: It is possible that this same technique would allow the distinction
1073: between `notype_initdecls' and `initdecls' to be eliminated.
1074: But I am being cautious and not trying it. */
1075:
1076: component_decl:
1077: typed_typespecs setspecs components
1078: { $$ = $3;
1079: current_declspecs = TREE_VALUE (declspec_stack);
1080: declspec_stack = TREE_CHAIN (declspec_stack);
1081: resume_momentary ($2); }
1082: | typed_typespecs
1083: { if (pedantic)
1084: pedwarn ("ANSI C forbids member declarations with no members");
1085: shadow_tag($1);
1086: $$ = NULL_TREE; }
1087: | nonempty_type_quals setspecs components
1088: { $$ = $3;
1089: current_declspecs = TREE_VALUE (declspec_stack);
1090: declspec_stack = TREE_CHAIN (declspec_stack);
1091: resume_momentary ($2); }
1092: | nonempty_type_quals
1093: { if (pedantic)
1094: pedwarn ("ANSI C forbids member declarations with no members");
1095: shadow_tag($1);
1096: $$ = NULL_TREE; }
1097: | error
1098: { $$ = NULL_TREE; }
1099: ;
1100:
1101: components:
1102: component_declarator
1103: | components ',' component_declarator
1104: { $$ = chainon ($1, $3); }
1105: ;
1106:
1107: component_declarator:
1108: save_filename save_lineno declarator maybe_attribute
1109: { $$ = grokfield ($1, $2, $3, current_declspecs, NULL_TREE);
1110: decl_attributes ($$, $4); }
1111: | save_filename save_lineno
1112: declarator ':' expr_no_commas maybe_attribute
1113: { $$ = grokfield ($1, $2, $3, current_declspecs, $5);
1114: decl_attributes ($$, $6); }
1115: | save_filename save_lineno ':' expr_no_commas
1116: { $$ = grokfield ($1, $2, NULL_TREE, current_declspecs, $4); }
1117: ;
1118:
1119: /* We chain the enumerators in reverse order.
1120: They are put in forward order where enumlist is used.
1121: (The order used to be significant, but no longer is so.
1122: However, we still maintain the order, just to be clean.) */
1123:
1124: enumlist:
1125: enumerator
1126: | enumlist ',' enumerator
1127: { $$ = chainon ($3, $1); }
1128: ;
1129:
1130:
1131: enumerator:
1132: identifier
1133: { $$ = build_enumerator ($1, NULL_TREE); }
1134: | identifier '=' expr_no_commas
1135: { $$ = build_enumerator ($1, $3); }
1136: ;
1137:
1138: typename:
1139: typed_typespecs absdcl
1140: { $$ = build_tree_list ($1, $2); }
1141: | nonempty_type_quals absdcl
1142: { $$ = build_tree_list ($1, $2); }
1143: ;
1144:
1145: absdcl: /* an absolute declarator */
1146: /* empty */
1147: { $$ = NULL_TREE; }
1148: | absdcl1
1149: ;
1150:
1151: nonempty_type_quals:
1152: TYPE_QUAL
1153: { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
1154: | nonempty_type_quals TYPE_QUAL
1155: { $$ = tree_cons (NULL_TREE, $2, $1); }
1156: ;
1157:
1158: type_quals:
1159: /* empty */
1160: { $$ = NULL_TREE; }
1161: | type_quals TYPE_QUAL
1162: { $$ = tree_cons (NULL_TREE, $2, $1); }
1163: ;
1164:
1165: absdcl1: /* a nonempty absolute declarator */
1166: '(' absdcl1 ')'
1167: { $$ = $2; }
1168: /* `(typedef)1' is `int'. */
1169: | '*' type_quals absdcl1 %prec UNARY
1170: { $$ = make_pointer_declarator ($2, $3); }
1171: | '*' type_quals %prec UNARY
1172: { $$ = make_pointer_declarator ($2, NULL_TREE); }
1173: | absdcl1 '(' parmlist %prec '.'
1174: { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
1175: | absdcl1 '[' expr ']' %prec '.'
1176: { $$ = build_nt (ARRAY_REF, $1, $3); }
1177: | absdcl1 '[' ']' %prec '.'
1178: { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
1179: | '(' parmlist %prec '.'
1180: { $$ = build_nt (CALL_EXPR, NULL_TREE, $2, NULL_TREE); }
1181: | '[' expr ']' %prec '.'
1182: { $$ = build_nt (ARRAY_REF, NULL_TREE, $2); }
1183: | '[' ']' %prec '.'
1184: { $$ = build_nt (ARRAY_REF, NULL_TREE, NULL_TREE); }
1185: ;
1186:
1187: /* at least one statement, the first of which parses without error. */
1188: /* stmts is used only after decls, so an invalid first statement
1189: is actually regarded as an invalid decl and part of the decls. */
1190:
1191: stmts:
1192: lineno_stmt
1193: | stmts lineno_stmt
1194: | stmts errstmt
1195: ;
1196:
1197: xstmts:
1198: /* empty */
1199: | stmts
1200: ;
1201:
1202: errstmt: error ';'
1203: ;
1204:
1205: pushlevel: /* empty */
1206: { emit_line_note (input_filename, lineno);
1207: pushlevel (0);
1208: clear_last_expr ();
1209: push_momentary ();
1210: expand_start_bindings (0);
1211: if (objc_method_context)
1212: add_objc_decls (); }
1213: ;
1214:
1215: /* Read zero or more forward-declarations for labels
1216: that nested functions can jump to. */
1217: maybe_label_decls:
1218: /* empty */
1219: | label_decls
1220: { if (pedantic)
1221: pedwarn ("ANSI C forbids label declarations"); }
1222: ;
1223:
1224: label_decls:
1225: label_decl
1226: | label_decls label_decl
1227: ;
1228:
1229: label_decl:
1230: LABEL identifiers ';'
1231: { tree link;
1232: for (link = $2; link; link = TREE_CHAIN (link))
1233: {
1234: tree label = shadow_label (TREE_VALUE (link));
1235: C_DECLARED_LABEL_FLAG (label) = 1;
1236: declare_nonlocal_label (label);
1237: }
1238: }
1239: ;
1240:
1241: /* This is the body of a function definition.
1242: It causes syntax errors to ignore to the next openbrace. */
1243:
1244: /* allow for: main () { Example *anObject = [Example new]; } */
1245:
1246: compstmt_or_error:
1247: compstmt
1248: {}
1249: | error compstmt
1250: ;
1251:
1252: compstmt: '{' '}'
1253: { $$ = convert (void_type_node, integer_zero_node); }
1254: | '{' pushlevel maybe_label_decls decls xstmts '}'
1255: { emit_line_note (input_filename, lineno);
1256: expand_end_bindings (getdecls (), 1, 0);
1257: $$ = poplevel (1, 1, 0);
1258: pop_momentary (); }
1259: | '{' pushlevel maybe_label_decls error '}'
1260: { emit_line_note (input_filename, lineno);
1261: expand_end_bindings (getdecls (), kept_level_p (), 0);
1262: $$ = poplevel (kept_level_p (), 0, 0);
1263: pop_momentary (); }
1264: | '{' pushlevel maybe_label_decls stmts '}'
1265: { emit_line_note (input_filename, lineno);
1266: expand_end_bindings (getdecls (), kept_level_p (), 0);
1267: $$ = poplevel (kept_level_p (), 0, 0);
1268: pop_momentary (); }
1269: ;
1270:
1271: /* Value is number of statements counted as of the closeparen. */
1272: simple_if:
1273: IF '(' expr ')'
1274: { emit_line_note ($<filename>-1, $<lineno>0);
1275: expand_start_cond (truthvalue_conversion ($3), 0);
1276: $<itype>1 = stmt_count;
1277: if_stmt_file = $<filename>-1;
1278: if_stmt_line = $<lineno>0;
1279: position_after_white_space (); }
1280: lineno_stmt
1281: ;
1282:
1283: save_filename:
1284: { $$ = input_filename; }
1285: ;
1286:
1287: save_lineno:
1288: { $$ = lineno; }
1289: ;
1290:
1291: lineno_stmt:
1292: save_filename save_lineno stmt
1293: { }
1294: ;
1295:
1296: stmt:
1297: compstmt
1298: { stmt_count++; }
1299: | expr ';'
1300: { stmt_count++;
1301: emit_line_note ($<filename>-1, $<lineno>0);
1302: c_expand_expr_stmt ($1);
1303: clear_momentary (); }
1304: | simple_if ELSE
1305: { expand_start_else ();
1306: $<itype>1 = stmt_count;
1307: position_after_white_space (); }
1308: lineno_stmt
1309: { expand_end_cond ();
1310: if (extra_warnings && stmt_count == $<itype>1)
1311: warning ("empty body in an else-statement"); }
1312: | simple_if %prec IF
1313: { expand_end_cond ();
1314: if (extra_warnings && stmt_count == $<itype>1)
1315: warning_with_file_and_line (if_stmt_file, if_stmt_line,
1316: "empty body in an if-statement"); }
1317: | WHILE
1318: { emit_nop ();
1319: stmt_count++;
1320: emit_line_note ($<filename>-1, $<lineno>0);
1321: expand_start_loop (1); }
1322: '(' expr ')'
1323: { emit_line_note (input_filename, lineno);
1324: expand_exit_loop_if_false (0, truthvalue_conversion ($4));
1325: position_after_white_space (); }
1326: lineno_stmt
1327: { expand_end_loop (); }
1328: | DO
1329: { emit_nop ();
1330: stmt_count++;
1331: emit_line_note ($<filename>-1, $<lineno>0);
1332: expand_start_loop_continue_elsewhere (1);
1333: position_after_white_space (); }
1334: lineno_stmt WHILE
1335: { expand_loop_continue_here (); }
1336: '(' expr ')' ';'
1337: { emit_line_note (input_filename, lineno);
1338: expand_exit_loop_if_false (0, truthvalue_conversion ($7));
1339: expand_end_loop ();
1340: clear_momentary (); }
1341: | FOR
1342: '(' xexpr ';'
1343: { emit_nop ();
1344: stmt_count++;
1345: emit_line_note ($<filename>-1, $<lineno>0);
1346: if ($3) c_expand_expr_stmt ($3);
1347: expand_start_loop_continue_elsewhere (1); }
1348: xexpr ';'
1349: { emit_line_note (input_filename, lineno);
1350: if ($6)
1351: expand_exit_loop_if_false (0, truthvalue_conversion ($6)); }
1352: xexpr ')'
1353: /* Don't let the tree nodes for $9 be discarded
1354: by clear_momentary during the parsing of the next stmt. */
1355: { push_momentary ();
1356: position_after_white_space (); }
1357: lineno_stmt
1358: { emit_line_note ($<filename>-1, $<lineno>0);
1359: expand_loop_continue_here ();
1360: if ($9)
1361: c_expand_expr_stmt ($9);
1362: pop_momentary ();
1363: expand_end_loop (); }
1364: | SWITCH '(' expr ')'
1365: { stmt_count++;
1366: emit_line_note ($<filename>-1, $<lineno>0);
1367: c_expand_start_case ($3);
1368: /* Don't let the tree nodes for $3 be discarded by
1369: clear_momentary during the parsing of the next stmt. */
1370: push_momentary ();
1371: position_after_white_space (); }
1372: lineno_stmt
1373: { expand_end_case ($3);
1374: pop_momentary (); }
1375: | CASE expr ':'
1376: { register tree value = check_case_value ($2);
1377: register tree label
1378: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
1379:
1380: stmt_count++;
1381:
1382: if (value != error_mark_node)
1383: {
1384: tree duplicate;
1385: int success = pushcase (value, label, &duplicate);
1386: if (success == 1)
1387: error ("case label not within a switch statement");
1388: else if (success == 2)
1389: {
1390: error ("duplicate case value");
1391: error_with_decl (duplicate, "this is the first entry for that value");
1392: }
1393: else if (success == 3)
1394: warning ("case value out of range");
1395: else if (success == 5)
1396: error ("case label within scope of cleanup or variable array");
1397: }
1398: position_after_white_space (); }
1399: lineno_stmt
1400: | CASE expr ELLIPSIS expr ':'
1401: { register tree value1 = check_case_value ($2);
1402: register tree value2 = check_case_value ($4);
1403: register tree label
1404: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
1405:
1406: stmt_count++;
1407:
1408: if (value1 != error_mark_node && value2 != error_mark_node)
1409: {
1410: tree duplicate;
1411: int success = pushcase_range (value1, value2, label,
1412: &duplicate);
1413: if (success == 1)
1414: error ("case label not within a switch statement");
1415: else if (success == 2)
1416: {
1417: error ("duplicate case value");
1418: error_with_decl (duplicate, "this is the first entry overlapping that value");
1419: }
1420: else if (success == 3)
1421: warning ("case value out of range");
1422: else if (success == 4)
1423: warning ("empty case range");
1424: else if (success == 5)
1425: error ("case label within scope of cleanup or variable array");
1426: }
1427: position_after_white_space (); }
1428: lineno_stmt
1429: | DEFAULT ':'
1430: {
1431: tree duplicate;
1432: register tree label
1433: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
1434: int success = pushcase (NULL_TREE, label, &duplicate);
1435: stmt_count++;
1436: if (success == 1)
1437: error ("default label not within a switch statement");
1438: else if (success == 2)
1439: {
1440: error ("multiple default labels in one switch");
1441: error_with_decl (duplicate, "this is the first default albel");
1442: }
1443: position_after_white_space (); }
1444: lineno_stmt
1445: | BREAK ';'
1446: { stmt_count++;
1447: emit_line_note ($<filename>-1, $<lineno>0);
1448: if ( ! expand_exit_something ())
1449: error ("break statement not within loop or switch"); }
1450: | CONTINUE ';'
1451: { stmt_count++;
1452: emit_line_note ($<filename>-1, $<lineno>0);
1453: if (! expand_continue_loop (0))
1454: error ("continue statement not within a loop"); }
1455: | RETURN ';'
1456: { stmt_count++;
1457: emit_line_note ($<filename>-1, $<lineno>0);
1458: c_expand_return (NULL_TREE); }
1459: | RETURN expr ';'
1460: { stmt_count++;
1461: emit_line_note ($<filename>-1, $<lineno>0);
1462: c_expand_return ($2); }
1463: | ASM maybe_type_qual '(' string ')' ';'
1464: { stmt_count++;
1465: emit_line_note ($<filename>-1, $<lineno>0);
1466: if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
1467: expand_asm ($4); }
1468: /* This is the case with just output operands. */
1469: | ASM maybe_type_qual '(' string ':' asm_operands ')' ';'
1470: { stmt_count++;
1471: emit_line_note ($<filename>-1, $<lineno>0);
1472: if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
1473: c_expand_asm_operands ($4, $6, NULL_TREE, NULL_TREE,
1474: $2 == ridpointers[(int)RID_VOLATILE],
1475: input_filename, lineno); }
1476: /* This is the case with input operands as well. */
1477: | ASM maybe_type_qual '(' string ':' asm_operands ':' asm_operands ')' ';'
1478: { stmt_count++;
1479: emit_line_note ($<filename>-1, $<lineno>0);
1480: if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
1481: c_expand_asm_operands ($4, $6, $8, NULL_TREE,
1482: $2 == ridpointers[(int)RID_VOLATILE],
1483: input_filename, lineno); }
1484: /* This is the case with clobbered registers as well. */
1485: | ASM maybe_type_qual '(' string ':' asm_operands ':'
1486: asm_operands ':' asm_clobbers ')' ';'
1487: { stmt_count++;
1488: emit_line_note ($<filename>-1, $<lineno>0);
1489: if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
1490: c_expand_asm_operands ($4, $6, $8, $10,
1491: $2 == ridpointers[(int)RID_VOLATILE],
1492: input_filename, lineno); }
1493: | GOTO identifier ';'
1494: { tree decl;
1495: stmt_count++;
1496: emit_line_note ($<filename>-1, $<lineno>0);
1497: decl = lookup_label ($2);
1498: if (decl != 0)
1499: {
1500: TREE_USED (decl) = 1;
1501: expand_goto (decl);
1502: }
1503: }
1504: | GOTO '*' expr ';'
1505: { stmt_count++;
1506: emit_line_note ($<filename>-1, $<lineno>0);
1507: expand_computed_goto ($3); }
1508: | identifier ':'
1509: { tree label = define_label (input_filename, lineno, $1);
1510: stmt_count++;
1511: emit_nop ();
1512: if (label)
1513: expand_label (label);
1514: position_after_white_space (); }
1515: lineno_stmt
1516: | ';'
1517: ;
1518:
1519: /* Either a type-qualifier or nothing. First thing in an `asm' statement. */
1520:
1521: maybe_type_qual:
1522: /* empty */
1523: { if (pedantic)
1524: pedwarn ("ANSI C forbids use of `asm' keyword");
1525: emit_line_note (input_filename, lineno); }
1526: | TYPE_QUAL
1527: { if (pedantic)
1528: pedwarn ("ANSI C forbids use of `asm' keyword");
1529: emit_line_note (input_filename, lineno); }
1530: ;
1531:
1532: xexpr:
1533: /* empty */
1534: { $$ = NULL_TREE; }
1535: | expr
1536: ;
1537:
1538: /* These are the operands other than the first string and colon
1539: in asm ("addextend %2,%1": "=dm" (x), "0" (y), "g" (*x)) */
1540: asm_operands: /* empty */
1541: { $$ = NULL_TREE; }
1542: | nonnull_asm_operands
1543: ;
1544:
1545: nonnull_asm_operands:
1546: asm_operand
1547: | nonnull_asm_operands ',' asm_operand
1548: { $$ = chainon ($1, $3); }
1549: ;
1550:
1551: asm_operand:
1552: STRING '(' expr ')'
1553: { $$ = build_tree_list ($1, $3); }
1554: ;
1555:
1556: asm_clobbers:
1557: string
1558: { $$ = tree_cons (NULL_TREE, combine_strings ($1), NULL_TREE); }
1559: | asm_clobbers ',' string
1560: { $$ = tree_cons (NULL_TREE, combine_strings ($3), $1); }
1561: ;
1562:
1563: /* This is what appears inside the parens in a function declarator.
1564: Its value is a list of ..._TYPE nodes. */
1565: parmlist:
1566: { pushlevel (0);
1567: declare_parm_level (0); }
1568: parmlist_1
1569: { $$ = $2;
1570: parmlist_tags_warning ();
1571: poplevel (0, 0, 0); }
1572: ;
1573:
1574: /* This is referred to where either a parmlist or an identifier list is ok.
1575: Its value is a list of ..._TYPE nodes or a list of identifiers. */
1576: parmlist_or_identifiers:
1577: { pushlevel (0);
1578: declare_parm_level (1); }
1579: parmlist_or_identifiers_1
1580: { $$ = $2;
1581: parmlist_tags_warning ();
1582: poplevel (0, 0, 0); }
1583: ;
1584:
1585: parmlist_or_identifiers_1:
1586: parmlist_2 ')'
1587: | identifiers ')'
1588: { $$ = tree_cons (NULL_TREE, NULL_TREE, $1); }
1589: | error ')'
1590: { $$ = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE); }
1591: ;
1592:
1593: parmlist_1:
1594: parmlist_2 ')'
1595: | error ')'
1596: { $$ = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE); }
1597: ;
1598:
1599: /* This is what appears inside the parens in a function declarator.
1600: Is value is represented in the format that grokdeclarator expects. */
1601: parmlist_2: /* empty */
1602: { $$ = get_parm_info (0); }
1603: | parms
1604: { $$ = get_parm_info (1); }
1605: | parms ',' ELLIPSIS
1606: { $$ = get_parm_info (0); }
1607: ;
1608:
1609: parms:
1610: parm
1611: { push_parm_decl ($1); }
1612: | parms ',' parm
1613: { push_parm_decl ($3); }
1614: ;
1615:
1616: /* A single parameter declaration or parameter type name,
1617: as found in a parmlist. */
1618: parm:
1619: typed_declspecs parm_declarator
1620: { $$ = build_tree_list ($1, $2) ; }
1621: | typed_declspecs notype_declarator
1622: { $$ = build_tree_list ($1, $2) ; }
1623: | typed_declspecs absdcl
1624: { $$ = build_tree_list ($1, $2); }
1625: | declmods notype_declarator
1626: { $$ = build_tree_list ($1, $2) ; }
1627: | declmods absdcl
1628: { $$ = build_tree_list ($1, $2); }
1629: ;
1630:
1631: /* A nonempty list of identifiers. */
1632: identifiers:
1633: IDENTIFIER
1634: { $$ = build_tree_list (NULL_TREE, $1); }
1635: | identifiers ',' IDENTIFIER
1636: { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
1637: ;
1638:
1639: /*
1640: * Objective-C productions.
1641: */
1642: objcdef:
1643: classdef
1644: | methoddef
1645: | END
1646: {
1647: if (objc_implementation_context)
1648: {
1649: finish_class (objc_implementation_context);
1650: objc_ivar_chain = NULL_TREE;
1651: objc_implementation_context = NULL_TREE;
1652: }
1653: else
1654: warning ("`@end' must appear in an implementation context");
1655: }
1656: ;
1657:
1658: classdef:
1659: INTERFACE identifier '{'
1660: {
1661: objc_interface_context = objc_ivar_context
1662: = start_class (INTERFACE_TYPE, $2, NULL_TREE);
1663: objc_public_flag = 0;
1664: }
1665: ivar_decl_list '}'
1666: {
1667: continue_class (objc_interface_context);
1668: }
1669: methodprotolist
1670: END
1671: {
1672: finish_class (objc_interface_context);
1673: objc_interface_context = NULL_TREE;
1674: }
1675:
1676: | INTERFACE identifier
1677: {
1678: objc_interface_context
1679: = start_class (INTERFACE_TYPE, $2, NULL_TREE);
1680: continue_class (objc_interface_context);
1681: }
1682: methodprotolist
1683: END
1684: {
1685: finish_class (objc_interface_context);
1686: objc_interface_context = NULL_TREE;
1687: }
1688:
1689: | INTERFACE identifier ':' identifier '{'
1690: {
1691: objc_interface_context = objc_ivar_context
1692: = start_class (INTERFACE_TYPE, $2, $4);
1693: objc_public_flag = 0;
1694: }
1695: ivar_decl_list '}'
1696: {
1697: continue_class (objc_interface_context);
1698: }
1699: methodprotolist
1700: END
1701: {
1702: finish_class (objc_interface_context);
1703: objc_interface_context = NULL_TREE;
1704: }
1705:
1706: | INTERFACE identifier ':' identifier
1707: {
1708: objc_interface_context
1709: = start_class (INTERFACE_TYPE, $2, $4);
1710: continue_class (objc_interface_context);
1711: }
1712: methodprotolist
1713: END
1714: {
1715: finish_class (objc_interface_context);
1716: objc_interface_context = NULL_TREE;
1717: }
1718:
1719: | IMPLEMENTATION identifier '{'
1720: {
1721: objc_implementation_context = objc_ivar_context
1722: = start_class (IMPLEMENTATION_TYPE, $2, NULL_TREE);
1723: objc_public_flag = 0;
1724: }
1725: ivar_decl_list '}'
1726: {
1727: objc_ivar_chain
1728: = continue_class (objc_implementation_context);
1729: }
1730:
1731: | IMPLEMENTATION identifier
1732: {
1733: objc_implementation_context
1734: = start_class (IMPLEMENTATION_TYPE, $2, NULL_TREE);
1735: objc_ivar_chain
1736: = continue_class (objc_implementation_context);
1737: }
1738:
1739: | IMPLEMENTATION identifier ':' identifier '{'
1740: {
1741: objc_implementation_context = objc_ivar_context
1742: = start_class (IMPLEMENTATION_TYPE, $2, $4);
1743: objc_public_flag = 0;
1744: }
1745: ivar_decl_list '}'
1746: {
1747: objc_ivar_chain
1748: = continue_class (objc_implementation_context);
1749: }
1750:
1751: | IMPLEMENTATION identifier ':' identifier
1752: {
1753: objc_implementation_context
1754: = start_class (IMPLEMENTATION_TYPE, $2, $4);
1755: objc_ivar_chain
1756: = continue_class (objc_implementation_context);
1757: }
1758:
1759: | INTERFACE identifier '(' identifier ')'
1760: {
1761: objc_interface_context
1762: = start_class (PROTOCOL_TYPE, $2, $4);
1763: continue_class (objc_interface_context);
1764: }
1765: methodprotolist
1766: END
1767: {
1768: finish_class (objc_interface_context);
1769: objc_interface_context = NULL_TREE;
1770: }
1771:
1772: | IMPLEMENTATION identifier '(' identifier ')'
1773: {
1774: objc_implementation_context
1775: = start_class (CATEGORY_TYPE, $2, $4);
1776: objc_ivar_chain
1777: = continue_class (objc_implementation_context);
1778: }
1779: ;
1780:
1781: ivar_decl_list:
1782: ivar_decls PUBLIC { objc_public_flag = 1; } ivar_decls
1783: | ivar_decls
1784: ;
1785:
1786: ivar_decls:
1787: /* empty */
1788: {
1789: $$ = NULL_TREE;
1790: }
1791: | ivar_decls ivar_decl ';'
1792: | ivar_decls ';'
1793: {
1794: if (pedantic)
1795: warning ("extra semicolon in struct or union specified");
1796: }
1797: ;
1798:
1799:
1800: /* There is a shift-reduce conflict here, because `components' may
1801: start with a `typename'. It happens that shifting (the default resolution)
1802: does the right thing, because it treats the `typename' as part of
1803: a `typed_typespecs'.
1804:
1805: It is possible that this same technique would allow the distinction
1806: between `notype_initdecls' and `initdecls' to be eliminated.
1807: But I am being cautious and not trying it. */
1808:
1809: ivar_decl:
1810: typed_typespecs setspecs ivars
1811: {
1812: $$ = $3;
1813: resume_momentary ($2);
1814: }
1815: | nonempty_type_quals setspecs ivars
1816: {
1817: $$ = $3;
1818: resume_momentary ($2);
1819: }
1820: | error
1821: { $$ = NULL_TREE; }
1822: ;
1823:
1824: ivars:
1825: /* empty */
1826: { $$ = NULL_TREE; }
1827: | ivar_declarator
1828: | ivars ',' ivar_declarator
1829: ;
1830:
1831: ivar_declarator:
1832: declarator
1833: {
1834: $$ = add_instance_variable (objc_ivar_context,
1835: objc_public_flag,
1836: $1, current_declspecs,
1837: NULL_TREE);
1838: }
1839: | declarator ':' expr_no_commas
1840: {
1841: $$ = add_instance_variable (objc_ivar_context,
1842: objc_public_flag,
1843: $1, current_declspecs, $3);
1844: }
1845: | ':' expr_no_commas
1846: {
1847: $$ = add_instance_variable (objc_ivar_context,
1848: objc_public_flag,
1849: NULL_TREE,
1850: current_declspecs, $2);
1851: }
1852: ;
1853:
1854: methoddef:
1855: '+'
1856: {
1857: if (objc_implementation_context)
1858: objc_inherit_code = CLASS_METHOD_DECL;
1859: else
1860: fatal ("method definition not in class context");
1861: }
1862: methoddecl
1863: {
1864: add_class_method (objc_implementation_context, $3);
1865: start_method_def ($3);
1866: objc_method_context = $3;
1867: }
1868: optarglist
1869: {
1870: continue_method_def ();
1871: }
1872: compstmt_or_error
1873: {
1874: finish_method_def ();
1875: objc_method_context = NULL_TREE;
1876: }
1877:
1878: | '-'
1879: {
1880: if (objc_implementation_context)
1881: objc_inherit_code = INSTANCE_METHOD_DECL;
1882: else
1883: fatal ("method definition not in class context");
1884: }
1885: methoddecl
1886: {
1887: add_instance_method (objc_implementation_context, $3);
1888: start_method_def ($3);
1889: objc_method_context = $3;
1890: }
1891: optarglist
1892: {
1893: continue_method_def ();
1894: }
1895: compstmt_or_error
1896: {
1897: finish_method_def ();
1898: objc_method_context = NULL_TREE;
1899: }
1900: ;
1901:
1902: /* the reason for the strange actions in this rule
1903: is so that notype_initdecls when reached via datadef
1904: can find a valid list of type and sc specs in $0. */
1905:
1906: methodprotolist:
1907: /* empty */
1908: | {$<ttype>$ = NULL_TREE; } methodprotolist2
1909: ;
1910:
1911: methodprotolist2: /* eliminates a shift/reduce conflict */
1912: methodproto
1913: | datadef
1914: | methodprotolist2 methodproto
1915: | methodprotolist2 {$<ttype>$ = NULL_TREE; } datadef
1916: ;
1917:
1918: semi_or_error:
1919: ';'
1920: | error
1921: ;
1922:
1923: methodproto:
1924: '+'
1925: {
1926: objc_inherit_code = CLASS_METHOD_DECL;
1927: }
1928: methoddecl
1929: {
1930: add_class_method (objc_interface_context, $3);
1931: }
1932: semi_or_error
1933:
1934: | '-'
1935: {
1936: objc_inherit_code = INSTANCE_METHOD_DECL;
1937: }
1938: methoddecl
1939: {
1940: add_instance_method (objc_interface_context, $3);
1941: }
1942: semi_or_error
1943: ;
1944:
1945: methoddecl:
1946: '(' typename ')' unaryselector
1947: {
1948: $$ = build_method_decl (objc_inherit_code, $2, $4, NULL_TREE);
1949: }
1950:
1951: | unaryselector
1952: {
1953: $$ = build_method_decl (objc_inherit_code, NULL_TREE, $1, NULL_TREE);
1954: }
1955:
1956: | '(' typename ')' keywordselector optparmlist
1957: {
1958: $$ = build_method_decl (objc_inherit_code, $2, $4, $5);
1959: }
1960:
1961: | keywordselector optparmlist
1962: {
1963: $$ = build_method_decl (objc_inherit_code, NULL_TREE, $1, $2);
1964: }
1965: ;
1966:
1967: /* "optarglist" assumes that start_method_def has already been called...
1968: if it is not, the "xdecls" will not be placed in the proper scope */
1969:
1970: optarglist:
1971: /* empty */
1972: | ';' myxdecls
1973: ;
1974:
1975: /* to get around the following situation: "int foo (int a) int b; {}" that
1976: is synthesized when parsing "- a:a b:b; id c; id d; { ... }" */
1977:
1978: myxdecls:
1979: /* empty */
1980: | mydecls
1981: ;
1982:
1983: mydecls:
1984: mydecl
1985: | errstmt
1986: | mydecls mydecl
1987: | mydecl errstmt
1988: ;
1989:
1990: mydecl:
1991: typed_declspecs setspecs myparms ';'
1992: { resume_momentary ($2); }
1993: | typed_declspecs ';'
1994: { shadow_tag ($1); }
1995: | declmods ';'
1996: { warning ("empty declaration"); }
1997: ;
1998:
1999: myparms:
2000: myparm
2001: { push_parm_decl ($1); }
2002: | myparms ',' myparm
2003: { push_parm_decl ($3); }
2004: ;
2005:
2006: /* A single parameter declaration or parameter type name,
2007: as found in a parmlist. DOES NOT ALLOW AN INITIALIZER OR ASMSPEC */
2008:
2009: myparm:
2010: parm_declarator
2011: { $$ = build_tree_list (current_declspecs, $1) ; }
2012: | notype_declarator
2013: { $$ = build_tree_list (current_declspecs, $1) ; }
2014: | absdcl
2015: { $$ = build_tree_list (current_declspecs, $1) ; }
2016: ;
2017:
2018: optparmlist:
2019: /* empty */
2020: {
2021: $$ = NULL_TREE;
2022: }
2023: | ',' ELLIPSIS
2024: {
2025: /* oh what a kludge! */
2026: $$ = (tree)1;
2027: }
2028: | ','
2029: {
2030: pushlevel (0);
2031: }
2032: parmlist_2
2033: {
2034: /* returns a tree list node generated by get_parm_info */
2035: $$ = $3;
2036: poplevel (0, 0, 0);
2037: }
2038: ;
2039:
2040: unaryselector:
2041: selector
2042: ;
2043:
2044: keywordselector:
2045: keyworddecl
2046:
2047: | keywordselector keyworddecl
2048: {
2049: $$ = chainon ($1, $2);
2050: }
2051: ;
2052:
2053: selector:
2054: IDENTIFIER
2055: | TYPENAME
2056: | reservedwords
2057: ;
2058:
2059: reservedwords:
2060: ENUM { $$ = get_identifier (token_buffer); }
2061: | STRUCT { $$ = get_identifier (token_buffer); }
2062: | UNION { $$ = get_identifier (token_buffer); }
2063: | IF { $$ = get_identifier (token_buffer); }
2064: | ELSE { $$ = get_identifier (token_buffer); }
2065: | WHILE { $$ = get_identifier (token_buffer); }
2066: | DO { $$ = get_identifier (token_buffer); }
2067: | FOR { $$ = get_identifier (token_buffer); }
2068: | SWITCH { $$ = get_identifier (token_buffer); }
2069: | CASE { $$ = get_identifier (token_buffer); }
2070: | DEFAULT { $$ = get_identifier (token_buffer); }
2071: | BREAK { $$ = get_identifier (token_buffer); }
2072: | CONTINUE { $$ = get_identifier (token_buffer); }
2073: | RETURN { $$ = get_identifier (token_buffer); }
2074: | GOTO { $$ = get_identifier (token_buffer); }
2075: | ASM { $$ = get_identifier (token_buffer); }
2076: | SIZEOF { $$ = get_identifier (token_buffer); }
2077: | TYPEOF { $$ = get_identifier (token_buffer); }
2078: | ALIGNOF { $$ = get_identifier (token_buffer); }
2079: | TYPESPEC | TYPE_QUAL
2080: ;
2081:
2082: keyworddecl:
2083: selector ':' '(' typename ')' identifier
2084: {
2085: $$ = build_keyword_decl ($1, $4, $6);
2086: }
2087:
2088: | selector ':' identifier
2089: {
2090: $$ = build_keyword_decl ($1, NULL_TREE, $3);
2091: }
2092:
2093: | ':' '(' typename ')' identifier
2094: {
2095: $$ = build_keyword_decl (NULL_TREE, $3, $5);
2096: }
2097:
2098: | ':' identifier
2099: {
2100: $$ = build_keyword_decl (NULL_TREE, NULL_TREE, $2);
2101: }
2102: ;
2103:
2104: messageargs:
2105: selector
2106: | keywordarglist
2107: ;
2108:
2109: keywordarglist:
2110: keywordarg
2111: | keywordarglist keywordarg
2112: {
2113: $$ = chainon ($1, $2);
2114: }
2115: ;
2116:
2117:
2118: keywordexpr:
2119: nonnull_exprlist
2120: {
2121: if (TREE_CHAIN ($1) == NULL_TREE)
2122: /* just return the expr., remove a level of indirection */
2123: $$ = TREE_VALUE ($1);
2124: else
2125: /* we have a comma expr., we will collapse later */
2126: $$ = $1;
2127: }
2128: ;
2129:
2130: keywordarg:
2131: selector ':' keywordexpr
2132: {
2133: $$ = build_tree_list ($1, $3);
2134: }
2135: | ':' keywordexpr
2136: {
2137: $$ = build_tree_list (NULL_TREE, $2);
2138: }
2139: ;
2140:
2141: receiver:
2142: expr
2143: | CLASSNAME
2144: {
2145: $$ = get_class_reference ($1);
2146: }
2147: ;
2148:
2149: objcmessageexpr:
2150: '['
2151: { objc_receiver_context = 1; }
2152: receiver
2153: { objc_receiver_context = 0; }
2154: messageargs ']'
2155: {
2156: $$ = build_tree_list ($3, $5);
2157: }
2158: ;
2159:
2160: selectorarg:
2161: selector
2162: | keywordnamelist
2163: ;
2164:
2165: keywordnamelist:
2166: keywordname
2167: | keywordnamelist keywordname
2168: {
2169: $$ = chainon ($1, $2);
2170: }
2171: ;
2172:
2173: keywordname:
2174: selector ':'
2175: {
2176: $$ = build_tree_list ($1, NULL_TREE);
2177: }
2178: | ':'
2179: {
2180: $$ = build_tree_list (NULL_TREE, NULL_TREE);
2181: }
2182: ;
2183:
2184: objcselectorexpr:
2185: SELECTOR '(' selectorarg ')'
2186: {
2187: $$ = $3;
2188: }
2189: ;
2190:
2191: /* extension to support C-structures in the archiver */
2192:
2193: objcencodeexpr:
2194: ENCODE '(' typename ')'
2195: {
2196: $$ = groktypename ($3);
2197: }
2198: ;
2199: %%
2200: /* If STRING is the name of an Objective C @-keyword
2201: (not including the @), return the token type for that keyword.
2202: Otherwise return 0. */
2203:
2204: int
2205: recognize_objc_keyword (string)
2206: char *string;
2207: {
2208: switch (string[0])
2209: {
2210: case 'd':
2211: if (!strcmp (string, "defs"))
2212: return DEFS;
2213: break;
2214: case 'e':
2215: if (!strcmp (string, "end"))
2216: return END;
2217: if (!strcmp (string, "encode"))
2218: return ENCODE;
2219: break;
2220: case 'i':
2221: if (!strcmp (string, "interface"))
2222: return INTERFACE;
2223: if (!strcmp (string, "implementation"))
2224: return IMPLEMENTATION;
2225: break;
2226: case 'p':
2227: if (!strcmp (string, "public"))
2228: return PUBLIC;
2229: break;
2230: case 's':
2231: if (!strcmp (string, "selector"))
2232: return SELECTOR;
2233: break;
2234: }
2235: return 0;
2236: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.