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