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