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