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