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