|
|
1.1 root 1: /* YACC parser for C++ syntax and for Objective-C.
2: Copyright (C) 1988, 1989, 1993 Free Software Foundation, Inc.
3: Hacked by Michael Tiemann ([email protected])
4:
5: This file is part of GNU CC.
6:
7: GNU CC is free software; you can redistribute it and/or modify
8: it under the terms of the GNU General Public License as published by
9: the Free Software Foundation; either version 2, or (at your option)
10: any later version.
11:
12: GNU CC is distributed in the hope that it will be useful,
13: but WITHOUT ANY WARRANTY; without even the implied warranty of
14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: GNU General Public License for more details.
16:
17: You should have received a copy of the GNU General Public License
18: along with GNU CC; see the file COPYING. If not, write to
19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20:
21: /* This file defines the grammar of C++ and that of Objective C.
22: %if objc ... %endif objc conditionals contain code for Objective C only.
23: %if cplus ... %endif cplus conditionals contain code for C++ only.
24: Sed commands in Makefile.in are used to convert this file into
25: cp-parse.y and into obcp-parse.y. */
26:
27:
28: /* This grammar is based on the GNU CC grammar. */
29:
30: /* Note: Bison automatically applies a default action of "$$ = $1" for
31: all derivations; this is applied before the explicit action, if one
32: is given. Keep this in mind when reading the actions. */
33:
34: /* Also note: this version contains experimental exception
35: handling features. They could break, change, disappear,
36: or otherwise exhibit volatile behavior. Don't depend on
37: me (Michael Tiemann) to protect you from any negative impact
38: this may have on your professional, personal, or spiritual life.
39:
40: NEWS FLASH: This version now supports the exception handling
41: syntax of Stroustrup's 2nd edition, if -fansi-exceptions is given.
42: THIS IS WORK IN PROGRESS!!! The type of the 'throw' and the
43: 'catch' much match EXACTLY (no inheritance support or coercions).
44: Also, throw-specifications of functions don't work.
45: Destructors aren't called correctly. Etc, etc. --Per Bothner.
46: */
47:
48: %{
49:
50: %ifobjc
51: #define OBJCPLUS
52: %endifobjc
53:
54: #if defined(GATHER_STATISTICS) || defined(SPEW_DEBUG)
55: #undef YYDEBUG
56: #define YYDEBUG 1
57: #endif
58:
59: #include "config.h"
60:
61: #include <stdio.h>
62: #include <errno.h>
63:
64: #include "tree.h"
65: #include "input.h"
66: #include "flags.h"
67: #include "cp-lex.h"
68: #include "cp-tree.h"
69:
70: /* Since parsers are distinct for each language, put the language string
71: definition here. (fnf) */
72: %ifobjc
73: char *language_string = "GNU Objective-C++";
74: %endifobjc
75: %ifcplus
76: char *language_string = "GNU C++";
77: %endifcplus
78:
79: extern tree void_list_node;
80: extern struct obstack permanent_obstack;
81:
82: #ifndef errno
83: extern int errno;
84: #endif
85:
86: extern int end_of_file;
87:
88: void yyerror ();
89:
90: /* Like YYERROR but do call yyerror. */
91: #define YYERROR1 { yyerror ("syntax error"); YYERROR; }
92:
93: static void position_after_white_space ();
94:
95: /* Contains the statement keyword (if/while/do) to include in an
96: error message if the user supplies an empty conditional expression. */
97: static char *cond_stmt_keyword;
98:
99: %ifobjc
100: #include "objc-act.h"
101:
102: /* the `decl' list operators optimization is not appropriate for Objective-C */
103: #define build_decl_list build_tree_list
104: #define decl_tree_cons tree_cons
105: %endifobjc
106:
107: /* Nonzero if we have an `extern "C"' acting as an extern specifier. */
108: int have_extern_spec;
109: int used_extern_spec;
110:
111: void yyhook ();
112:
113: /* Cons up an empty parameter list. */
114: #ifdef __GNUC__
115: __inline
116: #endif
117: static tree
118: empty_parms ()
119: {
120: tree parms;
121:
122: if (strict_prototype)
123: parms = void_list_node;
124: else
125: parms = NULL_TREE;
126: return parms;
127: }
128: %}
129:
130: %start program
131:
132: %union {long itype; tree ttype; char *strtype; enum tree_code code; }
133:
134: /* All identifiers that are not reserved words
135: and are not declared typedefs in the current block */
136: %token IDENTIFIER
137:
138: /* All identifiers that are declared typedefs in the current block.
139: In some contexts, they are treated just like IDENTIFIER,
140: but they can also serve as typespecs in declarations. */
141: %token TYPENAME
142:
143: /* Qualified identifiers that end in a TYPENAME. */
144: %token SCOPED_TYPENAME
145:
146: /* Reserved words that specify storage class.
147: yylval contains an IDENTIFIER_NODE which indicates which one. */
148: %token SCSPEC
149:
150: /* Reserved words that specify type.
151: yylval contains an IDENTIFIER_NODE which indicates which one. */
152: %token TYPESPEC
153:
154: /* Reserved words that qualify type: "const" or "volatile".
155: yylval contains an IDENTIFIER_NODE which indicates which one. */
156: %token TYPE_QUAL
157:
158: /* Character or numeric constants.
159: yylval is the node for the constant. */
160: %token CONSTANT
161:
162: /* String constants in raw form.
163: yylval is a STRING_CST node. */
164: %token STRING
165:
166: /* "...", used for functions with variable arglists. */
167: %token ELLIPSIS
168:
169: /* the reserved words */
170: /* SCO include files test "ASM", so use something else. */
171: %token SIZEOF ENUM /* STRUCT UNION */ IF ELSE WHILE DO FOR SWITCH CASE DEFAULT
172: %token BREAK CONTINUE RETURN GOTO ASM_KEYWORD GCC_ASM_KEYWORD TYPEOF ALIGNOF
173: %token HEADOF CLASSOF
174: %token ATTRIBUTE EXTENSION LABEL
175:
176: /* the reserved words... C++ extensions */
177: %token <ttype> AGGR
178: %token <itype> VISSPEC
179: %token DELETE NEW OVERLOAD THIS OPERATOR
180: %token LEFT_RIGHT TEMPLATE
181: %token TYPEID DYNAMIC_CAST
182: %token <itype> SCOPE
183:
184: %ifobjc
185: /* the Objective-C keywords */
186: %token INTERFACE IMPLEMENTATION END SELECTOR DEFS ENCODE
187: %token CLASSNAME PROTOCOL OBJECTNAME CLASS ALIAS
188: %token PRIVATE PUBLIC PROTECTED
189:
190: /* Objective-C string constants in raw form.
191: yylval is a OBJC_STRING_CST node. */
192: %token OBJC_STRING
193: %endifobjc
194:
195: /* Special token created by the lexer to separate TYPENAME
196: from an ABSDCL. This allows us to parse `foo (*pf)()'. */
197:
198: %token START_DECLARATOR
199:
200: /* Define the operator tokens and their precedences.
201: The value is an integer because, if used, it is the tree code
202: to use in the expression made from the operator. */
203:
204: %left EMPTY /* used to resolve s/r with epsilon */
205:
206: /* Add precedence rules to solve dangling else s/r conflict */
207: %nonassoc IF
208: %nonassoc ELSE
209:
210: %left IDENTIFIER TYPENAME TYPENAME_COLON SCSPEC TYPESPEC TYPE_QUAL ENUM AGGR
211:
212: %left '{' ','
213:
214: %right <code> ASSIGN '='
215: %right <code> '?' ':' RANGE
216: %left <code> OROR
217: %left <code> ANDAND
218: %left <code> '|'
219: %left <code> '^'
220: %left <code> '&'
221: %left <code> MIN_MAX
222: %left <code> EQCOMPARE
223: %left <code> ARITHCOMPARE '<' '>'
224: %left <code> LSHIFT RSHIFT
225: %left <code> '+' '-'
226: %left <code> '*' '/' '%'
227: %right <code> UNARY PLUSPLUS MINUSMINUS
228: %left HYPERUNARY
229: %left <ttype> PAREN_STAR_PAREN LEFT_RIGHT
230: %left <code> POINTSAT POINTSAT_STAR '.' DOT_STAR '(' '['
231:
232: %right SCOPE /* C++ extension */
233: %nonassoc NEW DELETE RAISE RAISES RERAISE TRY EXCEPT CATCH THROW
234: %nonassoc ANSI_TRY ANSI_THROW
235:
236: %type <code> unop
237:
238: %type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist
239: %type <ttype> optional_identifier paren_expr_or_null
240: %type <ttype> expr_no_commas cast_expr unary_expr primary string STRING
241: %type <ttype> typed_declspecs reserved_declspecs
242: %type <ttype> typed_typespecs reserved_typespecquals
243: %type <ttype> declmods typespec typespecqual_reserved
244: %type <ttype> SCSPEC TYPESPEC TYPE_QUAL nonempty_type_quals maybe_type_qual
245: %type <itype> initdecls notype_initdecls initdcl /* C++ modification */
246: %type <ttype> init initlist maybeasm
247: %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
248: %type <ttype> maybe_attribute attribute_list attrib
249: %type <ttype> abs_member_declarator after_type_member_declarator
250:
251: %type <ttype> compstmt except_stmts ansi_except_stmts implicitly_scoped_stmt
252:
253: %type <ttype> declarator notype_declarator after_type_declarator
254:
255: %type <ttype> structsp opt.component_decl_list component_decl_list
256: %type <ttype> component_decl components component_declarator
257: %type <ttype> enumlist enumerator
258: %type <ttype> typename absdcl absdcl1 type_quals abs_or_notype_decl
259: %type <ttype> xexpr see_typename parmlist parms parm bad_parm
260: %type <ttype> identifiers_or_typenames
261:
262: /* C++ extensions */
263: %type <ttype> typename_scope
264: %token <ttype> TYPENAME_COLON TYPENAME_ELLIPSIS
265: %token <ttype> PTYPENAME SCOPED_TYPENAME
266: %token <ttype> PRE_PARSED_FUNCTION_DECL EXTERN_LANG_STRING ALL
267: %token <ttype> PRE_PARSED_CLASS_DECL
268: %type <ttype> fn.def1 /* Not really! */
269: %type <ttype> fn.def2 return_id
270: %type <ttype> named_class_head named_class_head_sans_basetype
271: %type <ttype> unnamed_class_head
272: %type <ttype> class_head base_class_list
273: %type <itype> base_class_visibility_list
274: %type <ttype> base_class maybe_base_class_list base_class.1
275: %type <ttype> after_type_declarator_no_typename
276: %type <ttype> maybe_raises raise_identifier raise_identifiers ansi_raise_identifier ansi_raise_identifiers
277: %type <ttype> component_declarator0 id_scope scoped_typename scoped_base_class
278: %type <ttype> forhead.1 identifier_or_opname operator_name
279: %type <ttype> new delete object object_star aggr
280: /* %type <ttype> primary_no_id */
281: %type <ttype> nonmomentary_expr
282: %type <itype> forhead.2 initdcl0 notype_initdcl0 member_init_list
283: %type <itype> .scope try ansi_try
284: %type <ttype> template_header template_parm_list template_parm
285: %type <ttype> template_type template_arg_list template_arg
286: %type <ttype> template_instantiation template_type_name tmpl.1 tmpl.2
287: %type <ttype> template_instantiate_once template_instantiate_some
288: %type <itype> fn_tmpl_end
289: /* %type <itype> try_for_typename */
290: %type <ttype> condition partially_scoped_stmt xcond paren_cond_or_null
291: %type <strtype> .kindof_pushlevel
292:
293: /* in order to recognize aggr tags as defining and thus shadowing. */
294: %token TYPENAME_DEFN IDENTIFIER_DEFN PTYPENAME_DEFN
295: %type <ttype> named_class_head_sans_basetype_defn
296: %type <ttype> identifier_defn IDENTIFIER_DEFN TYPENAME_DEFN PTYPENAME_DEFN
297:
298: %type <strtype> .pushlevel
299:
300: %ifobjc
301: /* the Objective-C productions */
302: %type <ttype> ivar_decl_list ivar_decls ivar_decl ivars ivar_declarator
303: %type <ttype> methoddecl unaryselector keywordselector selector methodtype
304: %type <ttype> keyworddecl receiver objcmessageexpr messageargs
305: %type <ttype> keywordexpr keywordarglist keywordarg reservedword
306: %type <ttype> myparms myparm optparmlist objcselectorexpr
307: %type <ttype> selectorarg keywordnamelist keywordname objcencodeexpr
308: %type <ttype> objc_string protocolrefs identifier_list identifier_colon
309: %type <ttype> objcprotocolexpr CLASSNAME OBJC_STRING OBJECTNAME
310: %type <ttype> objc_openbracket.expr objc_closebracket
311: %endifobjc
312:
313: /* cp-spew.c depends on this being the last token. Define
314: any new tokens before this one! */
315: %token END_OF_SAVED_INPUT
316:
317: %{
318: /* List of types and structure classes of the current declaration. */
319: static tree current_declspecs;
320:
321: /* When defining an aggregate, this is the most recent one being defined. */
322: static tree current_aggr;
323:
324: %ifobjc
325: /* List of Objective-C specific information */
326:
327: static tree objc_interface_context;
328: tree objc_implementation_context;
329: tree objc_method_context;
330: tree objc_ivar_chain;
331: static tree objc_ivar_context;
332: static enum tree_code objc_inherit_code;
333: int objc_receiver_context = 0;
334: int objc_declarator_context = 0;
335: int objc_msg_context = 0;
336: static int objc_public_flag;
337:
338: extern char *token_buffer;
339:
340: tree current_objc_implementation_context (void)
341: {
342: return objc_implementation_context;
343: }
344: %endifobjc
345:
346: /* Tell yyparse how to print a token's value, if yydebug is set. */
347:
348: #define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL)
349: extern void yyprint ();
350: extern tree combine_strings PROTO((tree));
351: extern tree truthvalue_conversion PROTO((tree));
352: %}
353:
354: %%
355: program: /* empty */
356: %ifobjc
357: { objc_finish (); }
358: %endifobjc
359: | extdefs
360: {
361: /* In case there were missing closebraces,
362: get us back to the global binding level. */
363: while (! global_bindings_p ())
364: poplevel (0, 0, 0);
365: finish_file ();
366: %ifobjc
367: objc_finish ();
368: %endifobjc
369: }
370: ;
371:
372: /* the reason for the strange actions in this rule
373: is so that notype_initdecls when reached via datadef
374: can find a valid list of type and sc specs in $0. */
375:
376: extdefs:
377: { $<ttype>$ = NULL_TREE; } extdef
378: {$<ttype>$ = NULL_TREE; }
379: | extdefs extdef
380: {$<ttype>$ = NULL_TREE; }
381: ;
382:
383: .hush_warning:
384: { have_extern_spec = 1;
385: used_extern_spec = 0;
386: $<ttype>$ = NULL_TREE; }
387: ;
388: .warning_ok:
389: { have_extern_spec = 0; }
390: ;
391:
392: asm_keyword:
393: ASM_KEYWORD { if (pedantic)
394: pedwarn ("ANSI C++ forbids use of `asm' keyword"); }
395: | GCC_ASM_KEYWORD
396: ;
397:
398: extdef:
399: fndef
400: { if (pending_inlines) do_pending_inlines (); }
401: | datadef
402: { if (pending_inlines) do_pending_inlines (); }
403: %ifobjc
404: | objcdef
405: %endifobjc
406: | template_def
407: { if (pending_inlines) do_pending_inlines (); }
408: | overloaddef
409: | asm_keyword '(' string ')' ';'
410: { if (TREE_CHAIN ($3)) $3 = combine_strings ($3);
411: assemble_asm ($3); }
412: | extern_lang_string '{' extdefs '}'
413: { pop_lang_context (); }
414: | extern_lang_string '{' '}'
415: { pop_lang_context (); }
416: | extern_lang_string .hush_warning fndef .warning_ok
417: { if (pending_inlines) do_pending_inlines ();
418: pop_lang_context (); }
419: | extern_lang_string .hush_warning datadef .warning_ok
420: { if (pending_inlines) do_pending_inlines ();
421: pop_lang_context (); }
422: ;
423:
424: extern_lang_string:
425: EXTERN_LANG_STRING
426: { push_lang_context ($1); }
427: ;
428:
429: template_header:
430: TEMPLATE '<'
431: { begin_template_parm_list (); }
432: template_parm_list '>'
433: { $$ = end_template_parm_list ($4); }
434: ;
435:
436: template_parm_list:
437: template_parm
438: { $$ = process_template_parm (NULL_TREE, $1); }
439: | template_parm_list ',' template_parm
440: { $$ = process_template_parm ($1, $3); }
441: ;
442:
443: template_parm:
444: /* The following rules introduce a new reduce/reduce
445: conflict: they are valid prefixes for a `structsp',
446: which means they could match a nameless parameter.
447: By putting them before the `parm' rule, we get
448: their match before considering them nameless parameter
449: declarations. */
450: aggr identifier
451: {
452: if ($1 != class_type_node)
453: error ("template type parameter must use keyword `class'");
454: $$ = build_tree_list ($2, NULL_TREE);
455: }
456: | aggr identifier_defn ':' base_class.1
457: {
458: if ($1 != class_type_node)
459: error ("template type parameter must use keyword `class'");
460: warning ("restricted template type parameters not yet implemented");
461: $$ = build_tree_list ($2, $4);
462: }
463: | aggr TYPENAME_COLON base_class.1
464: {
465: if ($1 != class_type_node)
466: error ("template type parameter must use keyword `class'");
467: warning ("restricted template type parameters not yet implemented");
468: $$ = build_tree_list ($2, $3);
469: }
470: | parm
471: ;
472:
473: overloaddef:
474: OVERLOAD ov_identifiers ';'
475: { warning ("use of `overload' is an anachronism"); }
476: ;
477:
478: ov_identifiers: IDENTIFIER
479: { declare_overloaded ($1); }
480: | ov_identifiers ',' IDENTIFIER
481: { declare_overloaded ($3); }
482: ;
483:
484: template_def:
485: /* Class template declarations go here; they aren't normal class
486: declarations, because we can't process the bodies yet. */
487: template_header named_class_head_sans_basetype '{'
488: { yychar = '{'; goto template1; }
489: ';'
490: | template_header named_class_head_sans_basetype_defn '{'
491: { yychar = '{'; goto template1; }
492: ';'
493: | template_header named_class_head_sans_basetype ':'
494: { yychar = ':'; goto template1; }
495: ';'
496: | template_header named_class_head_sans_basetype_defn ':'
497: {
498: yychar = ':';
499: template1:
500: if (current_aggr == exception_type_node)
501: error ("template type must define an aggregate or union");
502: /* Maybe pedantic warning for union?
503: How about an enum? :-) */
504: end_template_decl ($1, $2, current_aggr);
505: reinit_parse_for_template (yychar, $1, $2);
506: yychar = YYEMPTY;
507: }
508: ';'
509: | template_header named_class_head_sans_basetype ';'
510: {
511: end_template_decl ($1, $2, current_aggr);
512: /* declare $2 as template name with $1 parm list */
513: }
514: | template_header named_class_head_sans_basetype_defn ';'
515: {
516: end_template_decl ($1, $2, current_aggr);
517: /* declare $2 as template name with $1 parm list */
518: }
519: | template_header /* notype_initdcl0 ';' */
520: notype_declarator maybe_raises maybeasm maybe_attribute
521: fn_tmpl_end
522: {
523: tree d;
524: int momentary;
525: momentary = suspend_momentary ();
526: d = start_decl ($<ttype>2, /*current_declspecs*/NULL_TREE, 0, $3);
527: cplus_decl_attributes (d, $5);
528: finish_decl (d, NULL_TREE, $4, 0);
529: end_template_decl ($1, d, 0);
530: if ($6 != ';')
531: reinit_parse_for_template ((int) $6, $1, d);
532: resume_momentary (momentary);
533: }
534: | template_header typed_declspecs /*initdcl0*/
535: declarator maybe_raises maybeasm maybe_attribute
536: fn_tmpl_end
537: {
538: tree d;
539: int momentary;
540:
541: current_declspecs = $2;
542: momentary = suspend_momentary ();
543: d = start_decl ($<ttype>3, current_declspecs,
544: 0, $<ttype>4);
545: cplus_decl_attributes (d, $6);
546: finish_decl (d, NULL_TREE, $5, 0);
547: end_exception_decls ();
548: end_template_decl ($1, d, 0);
549: if ($7 != ';')
550: {
551: reinit_parse_for_template ((int) $7, $1, d);
552: yychar = YYEMPTY;
553: }
554: note_list_got_semicolon ($<ttype>2);
555: resume_momentary (momentary);
556: }
557: | template_header declmods declarator fn_tmpl_end
558: {
559: tree d = start_decl ($<ttype>3, $<ttype>2, 0, NULL_TREE);
560: finish_decl (d, NULL_TREE, NULL_TREE, 0);
561: end_template_decl ($1, d, 0);
562: if ($4 != ';')
563: reinit_parse_for_template ((int) $4, $1, d);
564: }
565: /* Try to recover from syntax errors in templates. */
566: | template_header error '}' { end_template_decl ($1, 0, 0); }
567: | template_header error ';' { end_template_decl ($1, 0, 0); }
568: ;
569:
570: fn_tmpl_end: '{' { $$ = '{'; }
571: | ':' { $$ = ':'; }
572: | ';' { $$ = ';'; }
573: | '=' { $$ = '='; }
574: | RETURN { $$ = RETURN; }
575: ;
576:
577: datadef:
578: notype_initdecls ';'
579: { if (pedantic)
580: pedwarn ("ANSI C++ forbids data definition with no type or storage class");
581: else if (! flag_traditional && ! have_extern_spec)
582: warning ("data definition has no type or storage class"); }
583: | declmods notype_initdecls ';'
584: {}
585: /* Normal case to make fast: "int i;". */
586: | declmods declarator ';'
587: { tree d;
588: d = start_decl ($<ttype>2, $<ttype>$, 0, NULL_TREE);
589: finish_decl (d, NULL_TREE, NULL_TREE, 0);
590: }
591: | typed_declspecs initdecls ';'
592: {
593: end_exception_decls ();
594: note_list_got_semicolon ($<ttype>$);
595: }
596: /* Normal case: make this fast. */
597: | typed_declspecs declarator ';'
598: { tree d;
599: d = start_decl ($<ttype>2, $<ttype>$, 0, NULL_TREE);
600: finish_decl (d, NULL_TREE, NULL_TREE, 0);
601: end_exception_decls ();
602: note_list_got_semicolon ($<ttype>$);
603: }
604: | declmods ';'
605: { pedwarn ("empty declaration"); }
606: | typed_declspecs ';'
607: {
608: tree t = $<ttype>$;
609: shadow_tag (t);
610: if (TREE_CODE (t) == TREE_LIST
611: && TREE_PURPOSE (t) == NULL_TREE)
612: {
613: t = TREE_VALUE (t);
614: if (TREE_CODE (t) == RECORD_TYPE
615: && TYPE_SIZE (t)
616: && CLASSTYPE_USE_TEMPLATE (t) == 0)
617: CLASSTYPE_USE_TEMPLATE (t) = 2;
618: else if (TREE_CODE (t) == ENUMERAL_TYPE
619: && !TYPE_SIZE (t))
620: cp_error ("forward declaration of `%#T'", t);
621: }
622: note_list_got_semicolon ($<ttype>$);
623: }
624: | error ';'
625: | error '}'
626: | ';'
627: ;
628:
629: fndef:
630: fn.def1 base_init compstmt_or_error
631: {
632: finish_function (lineno, 1);
633: /* finish_function performs these three statements:
634:
635: expand_end_bindings (getdecls (), 1, 0);
636: poplevel (1, 1, 0);
637:
638: expand_end_bindings (0, 0, 0);
639: poplevel (0, 0, 1);
640: */
641: if ($<ttype>$) process_next_inline ($<ttype>$);
642: }
643: | fn.def1 return_init base_init compstmt_or_error
644: {
645: finish_function (lineno, 1);
646: /* finish_function performs these three statements:
647:
648: expand_end_bindings (getdecls (), 1, 0);
649: poplevel (1, 1, 0);
650:
651: expand_end_bindings (0, 0, 0);
652: poplevel (0, 0, 1);
653: */
654: if ($<ttype>$) process_next_inline ($<ttype>$);
655: }
656: | fn.def1 nodecls compstmt_or_error
657: { finish_function (lineno, 0);
658: if ($<ttype>$) process_next_inline ($<ttype>$); }
659: | fn.def1 return_init ';' nodecls compstmt_or_error
660: { finish_function (lineno, 0);
661: if ($<ttype>$) process_next_inline ($<ttype>$); }
662: | fn.def1 return_init nodecls compstmt_or_error
663: { finish_function (lineno, 0);
664: if ($<ttype>$) process_next_inline ($<ttype>$); }
665: | typed_declspecs declarator error
666: {}
667: | declmods notype_declarator error
668: {}
669: | notype_declarator error
670: {}
671: ;
672:
673: fn.def1:
674: typed_declspecs declarator maybe_raises
675: { if (! start_function ($$, $2, $3, 0))
676: YYERROR1;
677: reinit_parse_for_function ();
678: $$ = NULL_TREE; }
679: | declmods notype_declarator maybe_raises
680: { if (! start_function ($$, $2, $3, 0))
681: YYERROR1;
682: reinit_parse_for_function ();
683: $$ = NULL_TREE; }
684: | notype_declarator maybe_raises
685: { if (! start_function (NULL_TREE, $$, $2, 0))
686: YYERROR1;
687: reinit_parse_for_function ();
688: $$ = NULL_TREE; }
689: | TYPENAME '(' parmlist ')' type_quals maybe_raises
690: { if (! start_function (NULL_TREE, build_parse_node (CALL_EXPR, $$, $3, $5), $6, 0))
691: YYERROR1;
692: reinit_parse_for_function ();
693: $$ = NULL_TREE; }
694: | scoped_typename '(' parmlist ')' type_quals maybe_raises
695: { if (! start_function (NULL_TREE, build_parse_node (CALL_EXPR, $$, $3, $5), $6, 0))
696: YYERROR1;
697: reinit_parse_for_function ();
698: $$ = NULL_TREE; }
699: | TYPENAME LEFT_RIGHT type_quals maybe_raises
700: { if (! start_function (NULL_TREE, build_parse_node (CALL_EXPR, $$, empty_parms (), $3), $4, 0))
701: YYERROR1;
702: reinit_parse_for_function ();
703: $$ = NULL_TREE; }
704: | scoped_typename LEFT_RIGHT type_quals maybe_raises
705: { if (! start_function (NULL_TREE, build_parse_node (CALL_EXPR, $$, empty_parms (), $3), $4, 0))
706: YYERROR1;
707: reinit_parse_for_function ();
708: $$ = NULL_TREE; }
709: | PRE_PARSED_FUNCTION_DECL
710: { start_function (NULL_TREE, TREE_VALUE ($$), NULL_TREE, 1);
711: reinit_parse_for_function (); }
712: ;
713:
714: /* more C++ complexity */
715: fn.def2:
716: typed_declspecs '(' parmlist ')' type_quals maybe_raises
717: {
718: tree decl = build_parse_node (CALL_EXPR, TREE_VALUE ($$), $3, $5);
719: $$ = start_method (TREE_CHAIN ($$), decl, $6);
720: if (! $$)
721: YYERROR1;
722: if (yychar == YYEMPTY)
723: yychar = YYLEX;
724: reinit_parse_for_method (yychar, $$); }
725: | typed_declspecs LEFT_RIGHT type_quals maybe_raises
726: {
727: tree decl = build_parse_node (CALL_EXPR, TREE_VALUE ($$), empty_parms (), $3);
728: $$ = start_method (TREE_CHAIN ($$), decl, $4);
729: if (! $$)
730: YYERROR1;
731: if (yychar == YYEMPTY)
732: yychar = YYLEX;
733: reinit_parse_for_method (yychar, $$); }
734: | typed_declspecs declarator maybe_raises
735: { $$ = start_method ($$, $2, $3);
736: if (! $$)
737: YYERROR1;
738: if (yychar == YYEMPTY)
739: yychar = YYLEX;
740: reinit_parse_for_method (yychar, $$); }
741: | declmods '(' parmlist ')' type_quals maybe_raises
742: {
743: tree decl = build_parse_node (CALL_EXPR, TREE_VALUE ($$), $3, $5);
744: $$ = start_method (TREE_CHAIN ($$), decl, $6);
745: if (! $$)
746: YYERROR1;
747: if (yychar == YYEMPTY)
748: yychar = YYLEX;
749: reinit_parse_for_method (yychar, $$); }
750: | declmods LEFT_RIGHT type_quals maybe_raises
751: {
752: tree decl = build_parse_node (CALL_EXPR, TREE_VALUE ($$), empty_parms (), $3);
753: $$ = start_method (TREE_CHAIN ($$), decl, $4);
754: if (! $$)
755: YYERROR1;
756: if (yychar == YYEMPTY)
757: yychar = YYLEX;
758: reinit_parse_for_method (yychar, $$); }
759: | declmods declarator maybe_raises
760: { $$ = start_method ($$, $2, $3);
761: if (! $$)
762: YYERROR1;
763: if (yychar == YYEMPTY)
764: yychar = YYLEX;
765: reinit_parse_for_method (yychar, $$); }
766: | notype_declarator maybe_raises
767: { $$ = start_method (NULL_TREE, $$, $2);
768: if (! $$)
769: YYERROR1;
770: if (yychar == YYEMPTY)
771: yychar = YYLEX;
772: reinit_parse_for_method (yychar, $$); }
773: ;
774:
775: return_id: RETURN IDENTIFIER
776: {
777: if (! current_function_parms_stored)
778: store_parm_decls ();
779: $$ = $2;
780: }
781: ;
782:
783: return_init: return_id
784: { store_return_init ($<ttype>$, NULL_TREE); }
785: | return_id '=' init
786: { store_return_init ($<ttype>$, $3); }
787: | return_id '(' nonnull_exprlist ')'
788: { store_return_init ($<ttype>$, $3); }
789: | return_id LEFT_RIGHT
790: { store_return_init ($<ttype>$, NULL_TREE); }
791: ;
792:
793: base_init:
794: ':' .set_base_init member_init_list
795: {
796: if ($3 == 0)
797: error ("no base initializers given following ':'");
798: setup_vtbl_ptr ();
799: /* Always keep the BLOCK node associated with the outermost
800: pair of curley braces of a function. These are needed
801: for correct operation of dwarfout.c. */
802: keep_next_level ();
803: }
804: ;
805:
806: .set_base_init:
807: /* empty */
808: {
809: if (! current_function_parms_stored)
810: store_parm_decls ();
811:
812: /* Flag that we are processing base and member initializers. */
813: current_vtable_decl = error_mark_node;
814:
815: if (DECL_CONSTRUCTOR_P (current_function_decl))
816: {
817: /* Make a contour for the initializer list. */
818: pushlevel (0);
819: clear_last_expr ();
820: expand_start_bindings (0);
821: }
822: else if (current_class_type == NULL_TREE)
823: error ("base initializers not allowed for non-member functions");
824: else if (! DECL_CONSTRUCTOR_P (current_function_decl))
825: error ("only constructors take base initializers");
826: }
827: ;
828:
829: member_init_list:
830: /* empty */
831: { $$ = 0; }
832: | member_init
833: { $$ = 1; }
834: | member_init_list ',' member_init
835: | member_init_list error
836: ;
837:
838: member_init: '(' nonnull_exprlist ')'
839: {
840: if (current_class_name && !flag_traditional)
841: pedwarn ("ANSI C++ forbids old style base class initialization",
842: IDENTIFIER_POINTER (current_class_name));
843: expand_member_init (C_C_D, NULL_TREE, $2);
844: }
845: | LEFT_RIGHT
846: {
847: if (current_class_name && !flag_traditional)
848: pedwarn ("ANSI C++ forbids old style base class initialization",
849: IDENTIFIER_POINTER (current_class_name));
850: expand_member_init (C_C_D, NULL_TREE, void_type_node);
851: }
852: | identifier '(' nonnull_exprlist ')'
853: {
854: expand_member_init (C_C_D, $<ttype>$, $3);
855: }
856: | identifier LEFT_RIGHT
857: { expand_member_init (C_C_D, $<ttype>$, void_type_node); }
858: | template_type_name '(' nonnull_exprlist ')'
859: { expand_member_init (C_C_D, $<ttype>$, $3); }
860: | template_type_name LEFT_RIGHT
861: { expand_member_init (C_C_D, $<ttype>$, void_type_node); }
862: | scoped_typename '(' nonnull_exprlist ')'
863: { expand_member_init (C_C_D, $<ttype>$, $3); }
864: | scoped_typename LEFT_RIGHT
865: { expand_member_init (C_C_D, $<ttype>$, void_type_node); }
866: | id_scope identifier '(' nonnull_exprlist ')'
867: {
868: do_member_init ($<ttype>$, $2, $4);
869: }
870: | id_scope identifier LEFT_RIGHT
871: {
872: do_member_init ($<ttype>$, $2, void_type_node);
873: }
874: ;
875:
876: identifier:
877: IDENTIFIER
878: | TYPENAME
879: | PTYPENAME
880: %ifobjc
881: | OBJECTNAME
882: | CLASSNAME
883: %endifobjc
884: ;
885:
886: identifier_defn:
887: IDENTIFIER_DEFN
888: | TYPENAME_DEFN
889: | PTYPENAME_DEFN
890: ;
891:
892: identifier_or_opname:
893: IDENTIFIER
894: | TYPENAME
895: | PTYPENAME
896: %ifobjc
897: | OBJECTNAME
898: | CLASSNAME
899: %endifobjc
900: /* | '~' TYPENAME
901: { $$ = build_parse_node (BIT_NOT_EXPR, $2); }*/
902: /* get rid of the next line, replace it with the above */
903: | '~' identifier { $$ = build_parse_node (BIT_NOT_EXPR,$2);}
904: | operator_name
905: ;
906:
907: template_type:
908: template_type_name tmpl.1 template_instantiation
909: {
910: extern tree template_type_seen_before_scope;
911:
912: if ($3)
913: $$ = $3;
914: else if ($$ != error_mark_node)
915: $$ = IDENTIFIER_TYPE_VALUE ($$);
916: /* This is a kludge: In order to detect nested types inside
917: * template classes, we have to tell the lexer that it should
918: * try to replace a following SCOPE token with the correct
919: * SCOPED_TYPENAME for the nested type. This SCOPED_TYPENAME
920: * token will be handled in the rule "scoped_typename".
921: * - [email protected] */
922: if (yychar == SCOPE)
923: {
924: /* We set template_type_seen_before_scope to be
925: an error_mark_node so we can avoid meaningless
926: and unhelpful syntax errors later. */
927: if ($$ != error_mark_node)
928: template_type_seen_before_scope = TYPE_IDENTIFIER ($$);
929: else
930: template_type_seen_before_scope = error_mark_node;
931: yychar = YYLEX;
932: }
933: }
934: ;
935:
936: template_type_name:
937: PTYPENAME '<' template_arg_list '>'
938: { $$ = lookup_template_class ($$, $3, NULL_TREE); }
939: | TYPENAME '<' template_arg_list '>'
940: { $$ = lookup_template_class ($$, $3, NULL_TREE); }
941: ;
942:
943: tmpl.1:
944: /* Expansion of template may be required, unless we're followed by
945: a class definition. */
946: '{' { yyungetc ('{', 1); $$ = 0; }
947: | ':' { yyungetc (':', 1); $$ = 0; }
948: | /* empty */ %prec EMPTY
949: { $$ = instantiate_class_template ($<ttype>0, 1); }
950: ;
951:
952: tmpl.2:
953: /* Always do expansion if it hasn't been done already. */
954: { $$ = instantiate_class_template ($<ttype>0, 1); }
955: ;
956:
957: template_arg_list:
958: template_arg
959: { $$ = build_tree_list (NULL_TREE, $$); }
960: | template_arg_list ',' template_arg
961: { $$ = chainon ($$, build_tree_list (NULL_TREE, $3)); }
962: ;
963:
964: template_arg:
965: typename
966: { $$ = groktypename ($$); }
967: | expr_no_commas %prec UNARY
968: ;
969:
970: template_instantiate_once:
971: PRE_PARSED_CLASS_DECL maybe_base_class_list
972: {
973: tree t, decl, id, tmpl;
974:
975: id = TREE_VALUE ($1);
976: tmpl = TREE_PURPOSE (IDENTIFIER_TEMPLATE (id));
977: t = xref_tag (DECL_TEMPLATE_INFO (tmpl)->aggr, id, $2);
978: set_current_level_tags_transparency (1);
979: my_friendly_assert (TREE_CODE (t) == RECORD_TYPE
980: || TREE_CODE (t) == UNION_TYPE, 257);
981: $<ttype>$ = t;
982:
983: /* Now, put a copy of the decl in global scope, to avoid
984: recursive expansion. */
985: decl = IDENTIFIER_LOCAL_VALUE (id);
986: if (!decl)
987: decl = IDENTIFIER_CLASS_VALUE (id);
988: /* Now, put a copy of the decl in global scope, to avoid
989: recursive expansion. */
990: if (decl)
991: {
992: /* Need to copy it to clear the chain pointer,
993: and need to get it into permanent storage. */
994: my_friendly_assert (TREE_CODE (decl) == TYPE_DECL, 258);
995: push_obstacks (&permanent_obstack, &permanent_obstack);
996: decl = copy_node (decl);
997: if (DECL_LANG_SPECIFIC (decl))
998: copy_lang_decl (decl);
999: pop_obstacks ();
1000: pushdecl_top_level (decl);
1001: }
1002: }
1003: left_curly opt.component_decl_list '}'
1004: {
1005: $$ = finish_struct ($<ttype>3, $5, 0);
1006:
1007: pop_obstacks ();
1008: end_template_instantiation ($1, $<ttype>3);
1009:
1010: /* Now go after the methods & class data. */
1011: instantiate_member_templates ($1);
1012:
1013: pop_tinst_level();
1014:
1015: CLASSTYPE_GOT_SEMICOLON ($$) = 1;
1016: }
1017: ;
1018:
1019: template_instantiation:
1020: /* empty */
1021: { $$ = NULL_TREE; }
1022: | template_instantiate_once
1023: { $$ = $1; }
1024: ;
1025:
1026: template_instantiate_some:
1027: /* empty */
1028: { $$ = NULL_TREE; /* never used from here... */}
1029: | template_instantiate_once template_instantiate_some
1030: { $$ = $1; /*???*/ }
1031: ;
1032:
1033: unop: '-'
1034: { $$ = NEGATE_EXPR; }
1035: | '+'
1036: { $$ = CONVERT_EXPR; }
1037: | PLUSPLUS
1038: { $$ = PREINCREMENT_EXPR; }
1039: | MINUSMINUS
1040: { $$ = PREDECREMENT_EXPR; }
1041: | '!'
1042: { $$ = TRUTH_NOT_EXPR; }
1043: ;
1044:
1045: expr: nonnull_exprlist
1046: { $$ = build_x_compound_expr ($$); }
1047: /* Ugly, but faster. */
1048: | expr_no_commas
1049: ;
1050:
1051: paren_expr_or_null:
1052: LEFT_RIGHT
1053: { error ("ANSI C++ forbids an empty condition for `%s'",
1054: cond_stmt_keyword);
1055: $$ = integer_zero_node; }
1056: | '(' expr ')'
1057: { $$ = $2; }
1058: ;
1059:
1060: paren_cond_or_null:
1061: LEFT_RIGHT
1062: { error ("ANSI C++ forbids an empty condition for `%s'",
1063: cond_stmt_keyword);
1064: $$ = integer_zero_node; }
1065: | '(' condition ')'
1066: { $$ = $2; }
1067: ;
1068:
1069: xcond:
1070: /* empty */
1071: { $$ = NULL_TREE; }
1072: | condition
1073: | error
1074: { $$ = NULL_TREE; }
1075: ;
1076:
1077: condition:
1078: typed_typespecs declarator maybe_raises maybeasm maybe_attribute '='
1079: { {
1080: tree d;
1081: for (d = getdecls (); d; d = TREE_CHAIN (d))
1082: if (TREE_CODE (d) == TYPE_DECL) {
1083: tree s = TREE_TYPE (d);
1084: if (TREE_CODE (s) == RECORD_TYPE)
1085: cp_error ("definition of class `%T' in condition", s);
1086: else if (TREE_CODE (s) == ENUMERAL_TYPE)
1087: cp_error ("definition of enum `%T' in condition", s);
1088: }
1089: }
1090: current_declspecs = $1;
1091: $<itype>6 = suspend_momentary ();
1092: $<ttype>$ = start_decl ($<ttype>2, current_declspecs, 1, $3);
1093: cplus_decl_attributes ($<ttype>$, $5);
1094: }
1095: init
1096: {
1097: finish_decl ($<ttype>7, $8, $5, 0);
1098: resume_momentary ($<itype>6);
1099: $$ = $<ttype>7;
1100: if (TREE_CODE (TREE_TYPE ($$)) == ARRAY_TYPE)
1101: cp_error ("definition of array `%#D' in condition", $$);
1102: }
1103: | expr
1104: ;
1105:
1106: /* Used for the blocks controlled by a condition, to add any DECLs in
1107: the condition to the controlled block. */
1108: .kindof_pushlevel: /* empty */
1109: { tree d = getdecls ();
1110: emit_line_note (input_filename, lineno);
1111: pushlevel (0);
1112: clear_last_expr ();
1113: push_momentary ();
1114: expand_start_bindings (0);
1115: if (d) pushdecl (d);
1116: }
1117: ;
1118:
1119: /* Like implicitly_scoped_stmt, but uses .kindof_pushlevel */
1120: partially_scoped_stmt:
1121: '{' .kindof_pushlevel '}'
1122: { pop_implicit_try_blocks (NULL_TREE);
1123: expand_end_bindings (getdecls (), kept_level_p (), 1);
1124: $$ = poplevel (kept_level_p (), 1, 0);
1125: pop_momentary ();
1126: finish_stmt (); }
1127: | '{' .kindof_pushlevel maybe_label_decls stmts '}'
1128: { pop_implicit_try_blocks (NULL_TREE);
1129: expand_end_bindings (getdecls (), kept_level_p (), 1);
1130: $$ = poplevel (kept_level_p (), 1, 0);
1131: pop_momentary ();
1132: finish_stmt (); }
1133: | '{' .kindof_pushlevel maybe_label_decls error '}'
1134: { pop_implicit_try_blocks (NULL_TREE);
1135: expand_end_bindings (getdecls (), kept_level_p (), 1);
1136: $$ = poplevel (kept_level_p (), 0, 0);
1137: pop_momentary ();
1138: finish_stmt (); }
1139: | .kindof_pushlevel simple_stmt
1140: { pop_implicit_try_blocks (NULL_TREE);
1141: expand_end_bindings (getdecls (), kept_level_p (), 1);
1142: $$ = poplevel (kept_level_p (), 1, 0);
1143: pop_momentary (); }
1144: ;
1145:
1146: already_scoped_stmt:
1147: '{' '}'
1148: { finish_stmt (); }
1149: | '{' maybe_label_decls stmts '}'
1150: { finish_stmt (); }
1151: | '{' maybe_label_decls error '}'
1152: { finish_stmt (); }
1153: | simple_stmt
1154: ;
1155:
1156: nonnull_exprlist:
1157: expr_no_commas
1158: { $$ = build_tree_list (NULL_TREE, $$); }
1159: | nonnull_exprlist ',' expr_no_commas
1160: { chainon ($$, build_tree_list (NULL_TREE, $3)); }
1161: | nonnull_exprlist ',' error
1162: { chainon ($$, build_tree_list (NULL_TREE, error_mark_node)); }
1163: ;
1164:
1165: unary_expr:
1166: primary %prec UNARY
1167: {
1168: if (TREE_CODE ($$) == TYPE_EXPR)
1169: $$ = build_component_type_expr (C_C_D, $$, NULL_TREE, 1);
1170: }
1171: /* __extension__ turns off -pedantic for following primary. */
1172: | EXTENSION
1173: { $<itype>1 = pedantic;
1174: pedantic = 0; }
1175: cast_expr %prec UNARY
1176: { $$ = $3;
1177: pedantic = $<itype>1; }
1178: | '*' cast_expr %prec UNARY
1179: { $$ = build_x_indirect_ref ($2, "unary *"); }
1180: | '&' cast_expr %prec UNARY
1181: { $$ = build_x_unary_op (ADDR_EXPR, $2); }
1182: | '~' cast_expr %prec UNARY
1183: { $$ = build_x_unary_op (BIT_NOT_EXPR, $2); }
1184: | unop cast_expr %prec UNARY
1185: { $$ = build_x_unary_op ((enum tree_code) $$, $2);
1186: if ($1 == NEGATE_EXPR && TREE_CODE ($2) == INTEGER_CST)
1187: TREE_NEGATED_INT ($$) = 1;
1188: overflow_warning ($$);
1189: }
1190: /* Refer to the address of a label as a pointer. */
1191: | ANDAND identifier
1192: { tree label = lookup_label ($2);
1193: if (label == NULL_TREE)
1194: $$ = null_pointer_node;
1195: else
1196: {
1197: TREE_USED (label) = 1;
1198: $$ = build1 (ADDR_EXPR, ptr_type_node, label);
1199: TREE_CONSTANT ($$) = 1;
1200: }
1201: }
1202: | SIZEOF unary_expr %prec UNARY
1203: { if (TREE_CODE ($2) == COMPONENT_REF
1204: && DECL_BIT_FIELD (TREE_OPERAND ($2, 1)))
1205: error ("sizeof applied to a bit-field");
1206: /* ANSI says arrays and functions are converted inside comma.
1207: But we can't really convert them in build_compound_expr
1208: because that would break commas in lvalues.
1209: So do the conversion here if operand was a comma. */
1210: if (TREE_CODE ($2) == COMPOUND_EXPR
1211: && (TREE_CODE (TREE_TYPE ($2)) == ARRAY_TYPE
1212: || TREE_CODE (TREE_TYPE ($2)) == FUNCTION_TYPE))
1213: $2 = default_conversion ($2);
1214: else if (TREE_CODE ($2) == TREE_LIST)
1215: {
1216: tree t = TREE_VALUE ($2);
1217: if (t != NULL_TREE
1218: && TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1219: pedwarn ("ANSI C++ forbids using sizeof() on a function");
1220: }
1221: $$ = c_sizeof (TREE_TYPE ($2)); }
1222: | SIZEOF '(' typename ')' %prec HYPERUNARY
1223: { $$ = c_sizeof (groktypename ($3)); }
1224: | ALIGNOF unary_expr %prec UNARY
1225: { $$ = grok_alignof ($2); }
1226: | ALIGNOF '(' typename ')' %prec HYPERUNARY
1227: { $$ = c_alignof (groktypename ($3)); }
1228:
1229: | .scope new typename %prec '='
1230: { $$ = build_new ($2, $3, NULL_TREE, $$ != NULL_TREE); }
1231: | .scope new '(' nonnull_exprlist ')' typename %prec '='
1232: { $$ = build_new ($4, $6, NULL_TREE, $$ != NULL_TREE); }
1233: | .scope new typespec '(' nonnull_exprlist ')'
1234: { $$ = build_new ($2, $3, $5, $$ != NULL_TREE); }
1235: | .scope new typespec '(' typespec ')'
1236: { cp_error ("`%T' is not a valid expression", $5);
1237: $$ = error_mark_node; }
1238: | .scope new '(' nonnull_exprlist ')' typespec '(' nonnull_exprlist ')'
1239: { $$ = build_new ($4, $6, $8, $$ != NULL_TREE); }
1240: | .scope new typespec LEFT_RIGHT
1241: { $$ = build_new ($2, $3, NULL_TREE, $$ != NULL_TREE); }
1242: | .scope new '(' nonnull_exprlist ')' typespec LEFT_RIGHT
1243: { $$ = build_new ($4, $6, NULL_TREE, $$ != NULL_TREE); }
1244: | .scope new typename '=' init %prec '='
1245: { $$ = build_new ($2, $3, $5, $$ != NULL_TREE); }
1246: | .scope new '(' nonnull_exprlist ')' typename '=' init %prec '='
1247: { $$ = build_new ($4, $6, $8, $$ != NULL_TREE); }
1248:
1249: /* I am not going to add placement syntax to the below complex rules
1250: because Ken says the syntax is illegal. (mrs) */
1251: /* I'm not sure why this is disallowed. But since it is, and it
1252: doesn't seem difficult to catch it, let's give a message, so
1253: the programmer can fix it. --Ken Raeburn */
1254: | .scope new '(' typed_typespecs absdcl ')' '[' nonmomentary_expr ']'
1255: {
1256: tree absdcl, typename;
1257:
1258: illegal_new_array:
1259: absdcl = build_parse_node (ARRAY_REF, $5, $8);
1260: typename = build_decl_list ($4, absdcl);
1261: pedwarn ("ANSI C++ forbids array dimensions with parenthesized type");
1262: $$ = build_new ($2, typename, NULL_TREE, $$ != NULL_TREE);
1263: }
1264: | .scope new '(' nonempty_type_quals absdcl ')' '[' nonmomentary_expr ']'
1265: { goto illegal_new_array; }
1266:
1267: | .scope new '(' typed_typespecs absdcl ')'
1268: { $$ = build_new ($2, build_decl_list ($4, $5), NULL_TREE, $$ != NULL_TREE); }
1269: | .scope new '(' nonnull_exprlist ')' '(' typed_typespecs absdcl ')'
1270: { $$ = build_new ($4, build_decl_list ($7, $8), NULL_TREE, $$ != NULL_TREE); }
1271: | .scope new '(' nonempty_type_quals absdcl ')'
1272: { $$ = build_new ($2, build_decl_list ($4, $5), NULL_TREE, $$ != NULL_TREE); }
1273: | .scope new '(' nonnull_exprlist ')' '(' nonempty_type_quals absdcl ')'
1274: { $$ = build_new ($4, build_decl_list ($7, $8), NULL_TREE, $$ != NULL_TREE); }
1275: /* Unswallow a ':' which is probably meant for ?: expression. */
1276: | .scope new TYPENAME_COLON
1277: { yyungetc (':', 1); $$ = build_new ($2, $3, NULL_TREE, $$ != NULL_TREE); }
1278: | .scope new '(' nonnull_exprlist ')' TYPENAME_COLON
1279: { yyungetc (':', 1); $$ = build_new ($4, $6, NULL_TREE, $$ != NULL_TREE); }
1280:
1281: | delete cast_expr %prec UNARY
1282: { $$ = delete_sanity ($2, NULL_TREE, 0); }
1283: | delete '[' ']' cast_expr %prec UNARY
1284: { $$ = delete_sanity ($4, NULL_TREE, 1);
1285: if (yychar == YYEMPTY)
1286: yychar = YYLEX; }
1287: %ifcplus
1288: | delete '[' expr ']' cast_expr %prec UNARY
1289: { $$ = delete_sanity ($5, $3, 2);
1290: if (yychar == YYEMPTY)
1291: yychar = YYLEX; }
1292: %endifcplus
1293: %ifobjc
1294: | delete objc_openbracket.expr objc_closebracket cast_expr %prec UNARY
1295: { $$ = delete_sanity ($4, $2, 2);
1296: if (yychar == YYEMPTY)
1297: yychar = YYLEX; }
1298: %endifobjc
1299: ;
1300:
1301: cast_expr:
1302: unary_expr
1303: | '(' typename ')' expr_no_commas %prec UNARY
1304: { tree type = groktypename ($2);
1305: $$ = build_c_cast (type, $4); }
1306: | '(' typename ')' '{' initlist maybecomma '}' %prec UNARY
1307: { tree type = groktypename ($2);
1308: tree init = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($5));
1309: if (pedantic)
1310: pedwarn ("ANSI C++ forbids constructor-expressions");
1311: /* Indicate that this was a GNU C constructor expression. */
1312: TREE_HAS_CONSTRUCTOR (init) = 1;
1313: $$ = digest_init (type, init, (tree *) 0);
1314: if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (type) == 0)
1315: {
1316: int failure = complete_array_type (type, $$, 1);
1317: if (failure)
1318: my_friendly_abort (78);
1319: }
1320: }
1321: | HEADOF '(' expr ')'
1322: { $$ = build_headof ($3); }
1323: | CLASSOF '(' expr ')'
1324: { $$ = build_classof ($3); }
1325: | CLASSOF '(' TYPENAME ')'
1326: { if (is_aggr_typedef ($3, 1))
1327: {
1328: tree type = IDENTIFIER_TYPE_VALUE ($3);
1329: $$ = CLASSTYPE_DOSSIER (type);
1330: }
1331: else
1332: $$ = error_mark_node;
1333: }
1334: ;
1335:
1336: expr_no_commas:
1337: cast_expr
1338: | expr_no_commas '+' expr_no_commas
1339: { $$ = build_x_binary_op ($2, $$, $3); }
1340: | expr_no_commas '-' expr_no_commas
1341: { $$ = build_x_binary_op ($2, $$, $3); }
1342: | expr_no_commas '*' expr_no_commas
1343: { $$ = build_x_binary_op ($2, $$, $3); }
1344: | expr_no_commas '/' expr_no_commas
1345: { $$ = build_x_binary_op ($2, $$, $3); }
1346: | expr_no_commas '%' expr_no_commas
1347: { $$ = build_x_binary_op ($2, $$, $3); }
1348: | expr_no_commas LSHIFT expr_no_commas
1349: { $$ = build_x_binary_op ($2, $$, $3); }
1350: | expr_no_commas RSHIFT expr_no_commas
1351: { $$ = build_x_binary_op ($2, $$, $3); }
1352: | expr_no_commas ARITHCOMPARE expr_no_commas
1353: { $$ = build_x_binary_op ($2, $$, $3); }
1354: | expr_no_commas '<' expr_no_commas
1355: { $$ = build_x_binary_op (LT_EXPR, $$, $3); }
1356: | expr_no_commas '>' expr_no_commas
1357: { $$ = build_x_binary_op (GT_EXPR, $$, $3); }
1358: | expr_no_commas EQCOMPARE expr_no_commas
1359: { $$ = build_x_binary_op ($2, $$, $3); }
1360: | expr_no_commas MIN_MAX expr_no_commas
1361: { $$ = build_x_binary_op ($2, $$, $3); }
1362: | expr_no_commas '&' expr_no_commas
1363: { $$ = build_x_binary_op ($2, $$, $3); }
1364: | expr_no_commas '|' expr_no_commas
1365: { $$ = build_x_binary_op ($2, $$, $3); }
1366: | expr_no_commas '^' expr_no_commas
1367: { $$ = build_x_binary_op ($2, $$, $3); }
1368: | expr_no_commas ANDAND expr_no_commas
1369: { $$ = build_x_binary_op (TRUTH_ANDIF_EXPR, $$, $3); }
1370: | expr_no_commas OROR expr_no_commas
1371: { $$ = build_x_binary_op (TRUTH_ORIF_EXPR, $$, $3); }
1372: | expr_no_commas '?' xexpr ':' expr_no_commas
1373: { $$ = build_x_conditional_expr ($$, $3, $5); }
1374: | expr_no_commas '=' expr_no_commas
1375: { $$ = build_modify_expr ($$, NOP_EXPR, $3); }
1376: | expr_no_commas ASSIGN expr_no_commas
1377: { register tree rval;
1378: if (rval = build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL, $$, $3,
1379: make_node ($2)))
1380: $$ = rval;
1381: else
1382: $$ = build_modify_expr ($$, $2, $3); }
1383: | primary DOT_STAR expr_no_commas %prec UNARY
1384: { $$ = build_m_component_ref ($$, $3); }
1385: /* Handle general members. */
1386: | object_star expr_no_commas %prec UNARY
1387: { $$ = build_x_binary_op (MEMBER_REF, $$, $2); }
1388: /* These extensions are not defined. The second arg to build_m_component_ref
1389: is old, build_m_component_ref now does an implicit
1390: build_indirect_ref (x, NULL_PTR) on the second argument.
1391: | object '&' expr_no_commas %prec UNARY
1392: { $$ = build_m_component_ref ($$, build_x_unary_op (ADDR_EXPR, $3)); }
1393: | object unop expr_no_commas %prec UNARY
1394: { $$ = build_m_component_ref ($$, build_x_unary_op ($2, $3)); }
1395: | object '(' typename ')' expr_no_commas %prec UNARY
1396: { tree type = groktypename ($3);
1397: $$ = build_m_component_ref ($$, build_c_cast (type, $5)); }
1398: | object primary_no_id %prec UNARY
1399: { $$ = build_m_component_ref ($$, $2); }
1400: */
1401: ;
1402:
1403: primary:
1404: IDENTIFIER
1405: { $$ = do_identifier ($$); }
1406: | operator_name
1407: {
1408: tree op = $$;
1409: if (TREE_CODE (op) != IDENTIFIER_NODE)
1410: $$ = op;
1411: else
1412: {
1413: $$ = lookup_name (op, 0);
1414: if ($$ == NULL_TREE)
1415: {
1416: if (op != ansi_opname[ERROR_MARK])
1417: error ("operator %s not defined",
1418: operator_name_string (op));
1419: $$ = error_mark_node;
1420: }
1421: }
1422: }
1423: | CONSTANT
1424: | string
1425: { $$ = combine_strings ($$); }
1426: | '(' expr ')'
1427: { $$ = $2; }
1428: | '(' error ')'
1429: { $$ = error_mark_node; }
1430: | '('
1431: { if (current_function_decl == 0)
1432: {
1433: error ("braced-group within expression allowed only inside a function");
1434: YYERROR;
1435: }
1436: keep_next_level ();
1437: $<ttype>$ = expand_start_stmt_expr (); }
1438: compstmt ')'
1439: { tree rtl_exp;
1440: if (pedantic)
1441: pedwarn ("ANSI C++ forbids braced-groups within expressions");
1442: rtl_exp = expand_end_stmt_expr ($<ttype>2);
1443: /* The statements have side effects, so the group does. */
1444: TREE_SIDE_EFFECTS (rtl_exp) = 1;
1445: /* Make a BIND_EXPR for the BLOCK already made. */
1446: $$ = build (BIND_EXPR, TREE_TYPE (rtl_exp),
1447: NULL_TREE, rtl_exp, $3);
1448: /* Remove the block from the tree at this point.
1449: It gets put back at the proper place
1450: when the BIND_EXPR is expanded. */
1451: delete_block ($3);
1452: }
1453: | primary '(' nonnull_exprlist ')'
1454: { /* [eichin:19911016.1902EST] */
1455: $<ttype>$ = build_x_function_call ($1, $3, current_class_decl);
1456: /* here we instantiate_class_template as needed... */
1457: do_pending_templates ();
1458: } template_instantiate_some {
1459: if (TREE_CODE ($<ttype>5) == CALL_EXPR
1460: && TREE_TYPE ($<ttype>5) != void_type_node)
1461: $$ = require_complete_type ($<ttype>5);
1462: else
1463: $$ = $<ttype>5;
1464: }
1465: | primary LEFT_RIGHT
1466: {
1467: $$ = build_x_function_call ($$, NULL_TREE, current_class_decl);
1468: if (TREE_CODE ($$) == CALL_EXPR
1469: && TREE_TYPE ($$) != void_type_node)
1470: $$ = require_complete_type ($$);
1471: }
1472: | primary '[' expr ']'
1473: { do_array:
1474: $$ = grok_array_decl ($$, $3); }
1475: | object identifier_or_opname %prec UNARY
1476: { $$ = build_component_ref ($$, $2, NULL_TREE, 1); }
1477: | object id_scope identifier_or_opname %prec UNARY
1478: { $$ = build_object_ref ($$, $2, $3); }
1479: | primary PLUSPLUS
1480: { /* If we get an OFFSET_REF, turn it into what it really
1481: means (e.g., a COMPONENT_REF). This way if we've got,
1482: say, a reference to a static member that's being operated
1483: on, we don't end up trying to find a member operator for
1484: the class it's in. */
1485: if (TREE_CODE ($$) == OFFSET_REF)
1486: $$ = resolve_offset_ref ($$);
1487: $$ = build_x_unary_op (POSTINCREMENT_EXPR, $$); }
1488: | primary MINUSMINUS
1489: { if (TREE_CODE ($$) == OFFSET_REF)
1490: $$ = resolve_offset_ref ($$);
1491: $$ = build_x_unary_op (POSTDECREMENT_EXPR, $$); }
1492: /* C++ extensions */
1493: | THIS
1494: { if (current_class_decl)
1495: {
1496: #ifdef WARNING_ABOUT_CCD
1497: TREE_USED (current_class_decl) = 1;
1498: #endif
1499: $$ = current_class_decl;
1500: }
1501: else if (current_function_decl
1502: && DECL_STATIC_FUNCTION_P (current_function_decl))
1503: {
1504: error ("`this' is unavailable for static member functions");
1505: $$ = error_mark_node;
1506: }
1507: else
1508: {
1509: if (current_function_decl)
1510: error ("invalid use of `this' in non-member function");
1511: else
1512: error ("invalid use of `this' at top level");
1513: $$ = error_mark_node;
1514: }
1515: }
1516: | TYPE_QUAL '(' nonnull_exprlist ')'
1517: {
1518: tree type;
1519: tree id = $$;
1520:
1521: /* This is a C cast in C++'s `functional' notation. */
1522: if ($3 == error_mark_node)
1523: {
1524: $$ = error_mark_node;
1525: break;
1526: }
1527: #if 0
1528: if ($3 == NULL_TREE)
1529: {
1530: error ("cannot cast null list to type `%s'",
1531: IDENTIFIER_POINTER (TYPE_NAME (id)));
1532: $$ = error_mark_node;
1533: break;
1534: }
1535: #endif
1536: #if 0
1537: /* type is not set! (mrs) */
1538: if (type == error_mark_node)
1539: $$ = error_mark_node;
1540: else
1541: #endif
1542: {
1543: if (id == ridpointers[(int) RID_CONST])
1544: type = build_type_variant (integer_type_node, 1, 0);
1545: else if (id == ridpointers[(int) RID_VOLATILE])
1546: type = build_type_variant (integer_type_node, 0, 1);
1547: #if 0
1548: /* should not be able to get here (mrs) */
1549: else if (id == ridpointers[(int) RID_FRIEND])
1550: {
1551: error ("cannot cast expression to `friend' type");
1552: $$ = error_mark_node;
1553: break;
1554: }
1555: #endif
1556: else my_friendly_abort (79);
1557: $$ = build_c_cast (type, build_compound_expr ($3));
1558: }
1559: }
1560: | typespec '(' nonnull_exprlist ')'
1561: { $$ = build_functional_cast ($$, $3); }
1562: | typespec LEFT_RIGHT
1563: { $$ = build_functional_cast ($$, NULL_TREE); }
1564: /* Stroustrup RTTI */
1565: | DYNAMIC_CAST '<' typename '>' '(' expr ')'
1566: { tree type = groktypename ($3);
1567: $$ = build_dynamic_cast (type, $6); }
1568: | TYPEID '(' expr ')'
1569: { $$ = build_typeid ($3); }
1570: | TYPEID '(' typename ')'
1571: { tree type = groktypename ($3);
1572: $$ = get_typeid (type); }
1573: | SCOPE typespec '(' nonnull_exprlist ')'
1574: { $$ = build_functional_cast ($2, $4); }
1575: | SCOPE typespec LEFT_RIGHT
1576: { $$ = build_functional_cast ($2, NULL_TREE); }
1577: | SCOPE IDENTIFIER
1578: {
1579: do_scoped_id:
1580: $$ = IDENTIFIER_GLOBAL_VALUE ($2);
1581: if (yychar == YYEMPTY)
1582: yychar = YYLEX;
1583: if (! $$)
1584: {
1585: if (yychar == '(' || yychar == LEFT_RIGHT)
1586: $$ = implicitly_declare ($2);
1587: else
1588: {
1589: if (IDENTIFIER_GLOBAL_VALUE ($2) != error_mark_node)
1590: error ("undeclared variable `%s' (first use here)",
1591: IDENTIFIER_POINTER ($2));
1592: $$ = error_mark_node;
1593: /* Prevent repeated error messages. */
1594: IDENTIFIER_GLOBAL_VALUE ($2) = error_mark_node;
1595: }
1596: }
1597: else
1598: {
1599: if (TREE_CODE ($$) == ADDR_EXPR)
1600: assemble_external (TREE_OPERAND ($$, 0));
1601: else
1602: assemble_external ($$);
1603: TREE_USED ($$) = 1;
1604: }
1605: if (TREE_CODE ($$) == CONST_DECL)
1606: {
1607: /* XXX CHS - should we set TREE_USED of the constant? */
1608: $$ = DECL_INITIAL ($$);
1609: /* This is to prevent an enum whose value is 0
1610: from being considered a null pointer constant. */
1611: $$ = build1 (NOP_EXPR, TREE_TYPE ($$), $$);
1612: TREE_CONSTANT ($$) = 1;
1613: }
1614:
1615: }
1616: /* p->int::~int() is valid -- 12.4 */
1617: | object '~' TYPESPEC LEFT_RIGHT
1618: {
1619: if (TREE_CODE (TREE_TYPE ($1))
1620: != TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($3))))
1621: cp_error ("`%E' is not of type `%T'", $1, $3);
1622: $$ = void_zero_node;
1623: }
1624: | object TYPESPEC SCOPE '~' TYPESPEC LEFT_RIGHT
1625: {
1626: if ($2 != $5)
1627: cp_error ("destructor specifier `%T::~%T()' must have matching names", $2, $5);
1628: if (TREE_CODE (TREE_TYPE ($1))
1629: != TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($2))))
1630: cp_error ("`%E' is not of type `%T'", $1, $2);
1631: $$ = void_zero_node;
1632: }
1633: | SCOPE operator_name
1634: {
1635: if (TREE_CODE ($2) == IDENTIFIER_NODE)
1636: goto do_scoped_id;
1637: do_scoped_operator:
1638: $$ = $2;
1639: }
1640: | id_scope identifier_or_opname %prec HYPERUNARY
1641: { $$ = build_offset_ref ($$, $2); }
1642: | id_scope identifier_or_opname '(' nonnull_exprlist ')'
1643: { $$ = build_member_call ($$, $2, $4); }
1644: | id_scope identifier_or_opname LEFT_RIGHT
1645: { $$ = build_member_call ($$, $2, NULL_TREE); }
1646: | object identifier_or_opname '(' nonnull_exprlist ')'
1647: {
1648: #if 0
1649: /* This is a future direction of this code, but because
1650: build_x_function_call cannot always undo what is done
1651: in build_component_ref entirely yet, we cannot do this. */
1652: $$ = build_x_function_call (build_component_ref ($$, $2, NULL_TREE, 1), $4, $$);
1653: if (TREE_CODE ($$) == CALL_EXPR
1654: && TREE_TYPE ($$) != void_type_node)
1655: $$ = require_complete_type ($$);
1656: #else
1657: $$ = build_method_call ($$, $2, $4, NULL_TREE,
1658: (LOOKUP_NORMAL|LOOKUP_AGGR));
1659: #endif
1660: }
1661: | object identifier_or_opname LEFT_RIGHT
1662: {
1663: #if 0
1664: /* This is a future direction of this code, but because
1665: build_x_function_call cannot always undo what is done
1666: in build_component_ref entirely yet, we cannot do this. */
1667: $$ = build_x_function_call (build_component_ref ($$, $2, NULL_TREE, 1), NULL_TREE, $$);
1668: if (TREE_CODE ($$) == CALL_EXPR
1669: && TREE_TYPE ($$) != void_type_node)
1670: $$ = require_complete_type ($$);
1671: #else
1672: $$ = build_method_call ($$, $2, NULL_TREE, NULL_TREE,
1673: (LOOKUP_NORMAL|LOOKUP_AGGR));
1674: #endif
1675: }
1676: | object id_scope identifier_or_opname '(' nonnull_exprlist ')'
1677: { $$ = build_scoped_method_call ($$, $2, $3, $5); }
1678: | object id_scope identifier_or_opname LEFT_RIGHT
1679: { $$ = build_scoped_method_call ($$, $2, $3, NULL_TREE); }
1680:
1681: %ifobjc
1682: /* Objective-C expressions */
1683: | objcmessageexpr
1684: { $$ = build_message_expr ($1); }
1685: | objcselectorexpr
1686: { $$ = build_selector_expr ($1); }
1687: | objcprotocolexpr
1688: { $$ = build_protocol_expr ($1); }
1689: | objcencodeexpr
1690: { $$ = build_encode_expr ($1); }
1691: | objc_string
1692: { $$ = build_objc_string_object ($1); }
1693: %endifobjc
1694: ;
1695:
1696: /* Not needed for now.
1697:
1698: primary_no_id:
1699: '(' expr ')'
1700: { $$ = $2; }
1701: | '(' error ')'
1702: { $$ = error_mark_node; }
1703: | '('
1704: { if (current_function_decl == 0)
1705: {
1706: error ("braced-group within expression allowed only inside a function");
1707: YYERROR;
1708: }
1709: $<ttype>$ = expand_start_stmt_expr (); }
1710: compstmt ')'
1711: { if (pedantic)
1712: pedwarn ("ANSI C++ forbids braced-groups within expressions");
1713: $$ = expand_end_stmt_expr ($<ttype>2); }
1714: | primary_no_id '(' nonnull_exprlist ')'
1715: { $$ = build_x_function_call ($$, $3, current_class_decl); }
1716: | primary_no_id LEFT_RIGHT
1717: { $$ = build_x_function_call ($$, NULL_TREE, current_class_decl); }
1718: | primary_no_id '[' expr ']'
1719: { goto do_array; }
1720: | primary_no_id PLUSPLUS
1721: { $$ = build_x_unary_op (POSTINCREMENT_EXPR, $$); }
1722: | primary_no_id MINUSMINUS
1723: { $$ = build_x_unary_op (POSTDECREMENT_EXPR, $$); }
1724: | SCOPE IDENTIFIER
1725: { goto do_scoped_id; }
1726: | SCOPE operator_name
1727: { if (TREE_CODE ($2) == IDENTIFIER_NODE)
1728: goto do_scoped_id;
1729: goto do_scoped_operator;
1730: }
1731: ;
1732: */
1733:
1734: new: NEW
1735: { $$ = NULL_TREE; }
1736: | NEW '{' nonnull_exprlist '}'
1737: {
1738: $$ = $3;
1739: pedwarn ("old style placement syntax, use () instead");
1740: }
1741: ;
1742:
1743: .scope:
1744: /* empty */
1745: { $$ = 0; }
1746: | SCOPE
1747: { $$ = 1; }
1748: ;
1749:
1750: delete: DELETE
1751: { $$ = NULL_TREE; }
1752: | SCOPE delete
1753: { if ($2)
1754: error ("extra `::' before `delete' ignored");
1755: $$ = error_mark_node;
1756: }
1757: ;
1758:
1759: /* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it. */
1760: string:
1761: STRING
1762: | string STRING
1763: { $$ = chainon ($$, $2); }
1764: ;
1765:
1766: %ifobjc
1767: /* Produces an OBJC_STRING_CST with perhaps more OBJC_STRING_CSTs chained
1768: onto it. */
1769: objc_string:
1770: OBJC_STRING
1771: | objc_string OBJC_STRING
1772: { $$ = chainon ($1, $2); }
1773: ;
1774: %endifobjc
1775:
1776: nodecls:
1777: /* empty */
1778: {
1779: if (! current_function_parms_stored)
1780: store_parm_decls ();
1781: setup_vtbl_ptr ();
1782: /* Always keep the BLOCK node associated with the outermost
1783: pair of curley braces of a function. These are needed
1784: for correct operation of dwarfout.c. */
1785: keep_next_level ();
1786: }
1787: ;
1788:
1789: object: primary '.'
1790: | primary POINTSAT
1791: {
1792: $$ = build_x_arrow ($$);
1793: }
1794: ;
1795:
1796: object_star: primary POINTSAT_STAR
1797: ;
1798:
1799: decl:
1800: typed_declspecs initdecls ';'
1801: {
1802: resume_momentary ($2);
1803: note_list_got_semicolon ($<ttype>$);
1804: }
1805: /* Normal case: make this fast. */
1806: | typed_declspecs declarator ';'
1807: { tree d;
1808: int yes = suspend_momentary ();
1809: d = start_decl ($<ttype>2, $<ttype>$, 0, NULL_TREE);
1810: finish_decl (d, NULL_TREE, NULL_TREE, 0);
1811: resume_momentary (yes);
1812: note_list_got_semicolon ($<ttype>$);
1813: }
1814: | declmods notype_initdecls ';'
1815: { resume_momentary ((int) $<itype>2); }
1816: /* Normal case: make this fast. */
1817: | declmods declarator ';'
1818: { tree d;
1819: int yes = suspend_momentary ();
1820: d = start_decl ($<ttype>2, $<ttype>$, 0, NULL_TREE);
1821: finish_decl (d, NULL_TREE, NULL_TREE, 0);
1822: resume_momentary (yes);
1823: }
1824: | typed_declspecs ';'
1825: {
1826: shadow_tag ($<ttype>$);
1827: note_list_got_semicolon ($<ttype>$);
1828: }
1829: | declmods ';'
1830: { warning ("empty declaration"); }
1831: ;
1832:
1833: /* Any kind of declarator (thus, all declarators allowed
1834: after an explicit typespec). */
1835:
1836: declarator:
1837: after_type_declarator
1838: | notype_declarator
1839: | START_DECLARATOR after_type_declarator
1840: { $$ = $2; }
1841: | START_DECLARATOR notype_declarator
1842: { $$ = $2; }
1843: ;
1844:
1845: /* Declspecs which contain at least one type specifier or typedef name.
1846: (Just `const' or `volatile' is not enough.)
1847: A typedef'd name following these is taken as a name to be declared. */
1848:
1849: typed_declspecs:
1850: typespec %prec HYPERUNARY
1851: { if ($$) $$ = list_hash_lookup_or_cons ($$); }
1852: | declmods typespec
1853: { $$ = hash_tree_chain ($2, $$); }
1854: | typespec reserved_declspecs %prec HYPERUNARY
1855: { $$ = hash_tree_chain ($$, $2); }
1856: | declmods typespec reserved_declspecs
1857: { $$ = hash_tree_chain ($2, hash_chainon ($3, $$)); }
1858: ;
1859:
1860: reserved_declspecs: /* empty
1861: { $$ = NULL_TREE; } */
1862: typespecqual_reserved
1863: { $$ = build_decl_list (NULL_TREE, $$); }
1864: | SCSPEC
1865: { if (extra_warnings)
1866: warning ("`%s' is not at beginning of declaration",
1867: IDENTIFIER_POINTER ($$));
1868: $$ = build_decl_list (NULL_TREE, $$); }
1869: | reserved_declspecs typespecqual_reserved
1870: { $$ = decl_tree_cons (NULL_TREE, $2, $$); }
1871: | reserved_declspecs SCSPEC
1872: { if (extra_warnings)
1873: warning ("`%s' is not at beginning of declaration",
1874: IDENTIFIER_POINTER ($2));
1875: $$ = decl_tree_cons (NULL_TREE, $2, $$); }
1876: ;
1877:
1878: /* List of just storage classes and type modifiers.
1879: A declaration can start with just this, but then it cannot be used
1880: to redeclare a typedef-name. */
1881:
1882: declmods:
1883: TYPE_QUAL
1884: { $$ = IDENTIFIER_AS_LIST ($$);
1885: TREE_STATIC ($$) = 1; }
1886: | SCSPEC
1887: { $$ = IDENTIFIER_AS_LIST ($$); }
1888: | declmods TYPE_QUAL
1889: { $$ = hash_tree_chain ($2, $$);
1890: TREE_STATIC ($$) = 1; }
1891: | declmods SCSPEC
1892: { if (extra_warnings && TREE_STATIC ($$))
1893: warning ("`%s' is not at beginning of declaration",
1894: IDENTIFIER_POINTER ($2));
1895: $$ = hash_tree_chain ($2, $$);
1896: TREE_STATIC ($$) = TREE_STATIC ($1); }
1897: ;
1898:
1899:
1900: /* Used instead of declspecs where storage classes are not allowed
1901: (that is, for typenames and structure components).
1902:
1903: C++ can takes storage classes for structure components.
1904: Don't accept a typedef-name if anything but a modifier precedes it. */
1905:
1906: typed_typespecs:
1907: typespec %prec EMPTY
1908: { $$ = get_decl_list ($$); }
1909: | nonempty_type_quals typespec
1910: { $$ = decl_tree_cons (NULL_TREE, $2, $$); }
1911: | typespec reserved_typespecquals
1912: { $$ = decl_tree_cons (NULL_TREE, $$, $2); }
1913: | nonempty_type_quals typespec reserved_typespecquals
1914: { $$ = decl_tree_cons (NULL_TREE, $2, hash_chainon ($3, $$)); }
1915: ;
1916:
1917: reserved_typespecquals:
1918: typespecqual_reserved
1919: { $$ = get_decl_list ($$); }
1920: | reserved_typespecquals typespecqual_reserved
1921: { $$ = decl_tree_cons (NULL_TREE, $2, $$); }
1922: ;
1923:
1924: /* A typespec (but not a type qualifier).
1925: Once we have seen one of these in a declaration,
1926: if a typedef name appears then it is being redeclared. */
1927:
1928: typespec: structsp
1929: | TYPESPEC %prec EMPTY
1930: | TYPENAME %prec EMPTY
1931: %ifobjc
1932: | CLASSNAME protocolrefs
1933: { $$ = get_static_reference ($1, $2); }
1934: | OBJECTNAME protocolrefs
1935: { $$ = get_object_reference ($2); }
1936: %endifobjc
1937: | scoped_typename
1938: | TYPEOF '(' expr ')'
1939: { $$ = TREE_TYPE ($3);
1940: if (pedantic)
1941: pedwarn ("ANSI C++ forbids `typeof'"); }
1942: | TYPEOF '(' typename ')'
1943: { $$ = groktypename ($3);
1944: if (pedantic)
1945: pedwarn ("ANSI C++ forbids `typeof'"); }
1946: | template_type
1947: ;
1948:
1949: /* A typespec that is a reserved word, or a type qualifier. */
1950:
1951: typespecqual_reserved: TYPESPEC
1952: | TYPE_QUAL
1953: | structsp
1954: ;
1955:
1956: initdecls:
1957: initdcl0
1958: | initdecls ',' initdcl
1959: ;
1960:
1961: notype_initdecls:
1962: notype_initdcl0
1963: | notype_initdecls ',' initdcl
1964: ;
1965:
1966: maybeasm:
1967: /* empty */
1968: { $$ = NULL_TREE; }
1969: | asm_keyword '(' string ')'
1970: { if (TREE_CHAIN ($3)) $3 = combine_strings ($3); $$ = $3; }
1971: ;
1972:
1973: initdcl0:
1974: declarator maybe_raises maybeasm maybe_attribute '='
1975: { current_declspecs = $<ttype>0;
1976: $<itype>5 = suspend_momentary ();
1977: $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1, $2);
1978: cplus_decl_attributes ($<ttype>$, $4); }
1979: init
1980: /* Note how the declaration of the variable is in effect while its init is parsed! */
1981: { finish_decl ($<ttype>6, $7, $3, 0);
1982: $$ = $<itype>5; }
1983: | declarator maybe_raises maybeasm maybe_attribute
1984: { tree d;
1985: current_declspecs = $<ttype>0;
1986: $$ = suspend_momentary ();
1987: d = start_decl ($<ttype>1, current_declspecs, 0, $2);
1988: cplus_decl_attributes (d, $4);
1989: finish_decl (d, NULL_TREE, $3, 0); }
1990: ;
1991:
1992: initdcl:
1993: declarator maybe_raises maybeasm maybe_attribute '='
1994: { $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1, $2);
1995: cplus_decl_attributes ($<ttype>$, $4); }
1996: init
1997: /* Note how the declaration of the variable is in effect while its init is parsed! */
1998: { finish_decl ($<ttype>6, $7, $3, 0); }
1999: | declarator maybe_raises maybeasm maybe_attribute
2000: { tree d = start_decl ($<ttype>1, current_declspecs, 0, $2);
2001: cplus_decl_attributes ($<ttype>$, $4);
2002: finish_decl (d, NULL_TREE, $3, 0); }
2003: ;
2004:
2005: notype_initdcl0:
2006: notype_declarator maybe_raises maybeasm maybe_attribute '='
2007: { current_declspecs = $<ttype>0;
2008: $<itype>5 = suspend_momentary ();
2009: $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1, $2);
2010: cplus_decl_attributes ($<ttype>$, $4); }
2011: init
2012: /* Note how the declaration of the variable is in effect while its init is parsed! */
2013: { finish_decl ($<ttype>6, $7, $3, 0);
2014: $$ = $<itype>5; }
2015: | notype_declarator maybe_raises maybeasm maybe_attribute
2016: { tree d;
2017: current_declspecs = $<ttype>0;
2018: $$ = suspend_momentary ();
2019: d = start_decl ($<ttype>1, current_declspecs, 0, $2);
2020: cplus_decl_attributes (d, $4);
2021: finish_decl (d, NULL_TREE, $3, 0); }
2022: ;
2023:
2024: /* the * rules are dummies to accept the Apollo extended syntax
2025: so that the header files compile. */
2026: maybe_attribute:
2027: /* empty */
2028: { $$ = NULL_TREE; }
2029: | ATTRIBUTE '(' '(' attribute_list ')' ')'
2030: { $$ = $4; }
2031: ;
2032:
2033: attribute_list
2034: : attrib
2035: { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
2036: | attribute_list ',' attrib
2037: { $$ = tree_cons (NULL_TREE, $3, $1); }
2038: ;
2039:
2040: attrib
2041: : IDENTIFIER
2042: { if (strcmp (IDENTIFIER_POINTER ($1), "packed")
2043: && strcmp (IDENTIFIER_POINTER ($1), "noreturn"))
2044: warning ("`%s' attribute directive ignored",
2045: IDENTIFIER_POINTER ($1));
2046: $$ = $1; }
2047: | IDENTIFIER '(' CONSTANT ')'
2048: { /* if not "aligned(n)", then issue warning */
2049: if (strcmp (IDENTIFIER_POINTER ($1), "aligned") != 0
2050: || TREE_CODE ($3) != INTEGER_CST)
2051: {
2052: warning ("`%s' attribute directive ignored",
2053: IDENTIFIER_POINTER ($1));
2054: $$ = $1;
2055: }
2056: else
2057: $$ = tree_cons ($1, $3, NULL_TREE); }
2058: | IDENTIFIER '(' IDENTIFIER ',' CONSTANT ',' CONSTANT ')'
2059: { /* if not "format(...)", then issue warning */
2060: if (strcmp (IDENTIFIER_POINTER ($1), "format") != 0
2061: || TREE_CODE ($5) != INTEGER_CST
2062: || TREE_CODE ($7) != INTEGER_CST)
2063: {
2064: warning ("`%s' attribute directive ignored",
2065: IDENTIFIER_POINTER ($1));
2066: $$ = $1;
2067: }
2068: else
2069: $$ = tree_cons ($1, tree_cons ($3, tree_cons ($5, $7, NULL_TREE), NULL_TREE), NULL_TREE); }
2070: ;
2071:
2072: /* A nonempty list of identifiers, including typenames. */
2073: identifiers_or_typenames:
2074: identifier
2075: { $$ = build_tree_list (NULL_TREE, $1); }
2076: | identifiers_or_typenames ',' identifier
2077: { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
2078: ;
2079:
2080: init:
2081: expr_no_commas %prec '='
2082: | '{' '}'
2083: { $$ = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE);
2084: TREE_HAS_CONSTRUCTOR ($$) = 1;
2085: if (pedantic)
2086: pedwarn ("ANSI C++ forbids empty initializer braces"); }
2087: | '{' initlist '}'
2088: { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2));
2089: TREE_HAS_CONSTRUCTOR ($$) = 1; }
2090: | '{' initlist ',' '}'
2091: { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2));
2092: TREE_HAS_CONSTRUCTOR ($$) = 1; }
2093: | error
2094: { $$ = NULL_TREE; }
2095: ;
2096:
2097: /* This chain is built in reverse order,
2098: and put in forward order where initlist is used. */
2099: initlist:
2100: init
2101: { $$ = build_tree_list (NULL_TREE, $$); }
2102: | initlist ',' init
2103: { $$ = tree_cons (NULL_TREE, $3, $$); }
2104: %ifcplus
2105: /* These are for labeled elements. */
2106: | '[' expr_no_commas ']' init
2107: { $$ = build_tree_list ($2, $4); }
2108: %endifcplus
2109: | initlist ',' CASE expr_no_commas ':' init
2110: { $$ = tree_cons ($4, $6, $$); }
2111: | identifier ':' init
2112: { $$ = build_tree_list ($$, $3); }
2113: | initlist ',' identifier ':' init
2114: { $$ = tree_cons ($3, $5, $$); }
2115: ;
2116:
2117: structsp:
2118: ENUM identifier '{'
2119: { $<itype>3 = suspend_momentary ();
2120: $$ = start_enum ($2); }
2121: enumlist maybecomma_warn '}'
2122: { $$ = finish_enum ($<ttype>4, $5);
2123: resume_momentary ((int) $<itype>3);
2124: check_for_missing_semicolon ($<ttype>4); }
2125: | ENUM identifier '{' '}'
2126: { $$ = finish_enum (start_enum ($2), NULL_TREE);
2127: check_for_missing_semicolon ($$); }
2128: | ENUM '{'
2129: { $<itype>2 = suspend_momentary ();
2130: $$ = start_enum (make_anon_name ()); }
2131: enumlist maybecomma_warn '}'
2132: { $$ = finish_enum ($<ttype>3, $4);
2133: resume_momentary ((int) $<itype>1);
2134: check_for_missing_semicolon ($<ttype>3); }
2135: | ENUM '{' '}'
2136: { $$ = finish_enum (start_enum (make_anon_name()), NULL_TREE);
2137: check_for_missing_semicolon ($$); }
2138: | ENUM identifier
2139: { $$ = xref_tag (enum_type_node, $2, NULL_TREE); }
2140:
2141: /* C++ extensions, merged with C to avoid shift/reduce conflicts */
2142: | class_head left_curly opt.component_decl_list '}'
2143: {
2144: int semi;
2145: tree id;
2146:
2147: #if 0
2148: /* Need to rework class nesting in the
2149: presence of nested classes, etc. */
2150: shadow_tag (CLASSTYPE_AS_LIST ($$)); */
2151: #endif
2152: if (yychar == YYEMPTY)
2153: yychar = YYLEX;
2154: semi = yychar == ';';
2155: /* finish_struct nukes this anyway; if
2156: finish_exception does too, then it can go. */
2157: if (semi)
2158: note_got_semicolon ($$);
2159:
2160: if (TREE_CODE ($$) == ENUMERAL_TYPE)
2161: /* $$ = $1 from default rule. */;
2162: else if (CLASSTYPE_DECLARED_EXCEPTION ($$))
2163: {
2164: if (! semi)
2165: $$ = finish_exception ($$, $3);
2166: else
2167: warning ("empty exception declaration\n");
2168: }
2169: else
2170: {
2171: $$ = finish_struct ($$, $3, semi);
2172: if (semi) note_got_semicolon ($$);
2173: }
2174:
2175: pop_obstacks ();
2176:
2177: id = TYPE_IDENTIFIER ($$);
2178: if (id && IDENTIFIER_TEMPLATE (id))
2179: {
2180: tree decl;
2181:
2182: /* I don't know if the copying of this TYPE_DECL is
2183: * really needed. However, it's such a small per-
2184: * formance penalty that the extra safety is a bargain.
2185: * - [email protected]
2186: */
2187: push_obstacks (&permanent_obstack, &permanent_obstack);
2188: decl = copy_node (lookup_name (id, 0));
2189: if (DECL_LANG_SPECIFIC (decl))
2190: copy_lang_decl (decl);
2191: pop_obstacks ();
2192: undo_template_name_overload (id, 0);
2193: pushdecl_top_level (decl);
2194: }
2195: if (! semi)
2196: check_for_missing_semicolon ($$); }
2197: | class_head %prec EMPTY
2198: {
2199: #if 0
2200: /* It's no longer clear what the following error is supposed to
2201: accomplish. If it turns out to be needed, add a comment why. */
2202: if (TYPE_BINFO_BASETYPES ($$) && !TYPE_SIZE ($$))
2203: {
2204: error ("incomplete definition of type `%s'",
2205: TYPE_NAME_STRING ($$));
2206: $$ = error_mark_node;
2207: }
2208: #endif
2209: }
2210: ;
2211:
2212: maybecomma:
2213: /* empty */
2214: | ','
2215: ;
2216:
2217: maybecomma_warn:
2218: /* empty */
2219: | ','
2220: { if (pedantic) pedwarn ("comma at end of enumerator list"); }
2221: ;
2222:
2223: aggr: AGGR
2224: | aggr SCSPEC
2225: { error ("storage class specifier `%s' not allowed after struct or class", IDENTIFIER_POINTER ($2)); }
2226: | aggr TYPESPEC
2227: { error ("type specifier `%s' not allowed after struct or class", IDENTIFIER_POINTER ($2)); }
2228: | aggr TYPE_QUAL
2229: { error ("type qualifier `%s' not allowed after struct or class", IDENTIFIER_POINTER ($2)); }
2230: | aggr AGGR
2231: { error ("no body nor ';' separates two class, struct or union declarations"); }
2232: ;
2233:
2234: named_class_head_sans_basetype:
2235: aggr identifier
2236: { aggr1: current_aggr = $$; $$ = $2; }
2237: | aggr template_type_name %prec EMPTY
2238: { current_aggr = $$; $$ = $2; }
2239: | aggr TYPENAME_COLON
2240: { yyungetc (':', 1); goto aggr1; }
2241: | aggr template_type_name '{'
2242: { yyungetc ('{', 1);
2243: aggr2:
2244: current_aggr = $$;
2245: $$ = $2;
2246: overload_template_name ($$, 0); }
2247: | aggr template_type_name ':'
2248: { yyungetc (':', 1); goto aggr2; }
2249: ;
2250:
2251: named_class_head_sans_basetype_defn:
2252: aggr identifier_defn
2253: { current_aggr = $$; $$ = $2; }
2254: ;
2255:
2256: named_class_head:
2257: named_class_head_sans_basetype
2258: {
2259: $<ttype>$ = xref_tag (current_aggr, $1, NULL_TREE);
2260: }
2261: maybe_base_class_list %prec EMPTY
2262: {
2263: if ($3)
2264: $$ = xref_tag (current_aggr, $1, $3);
2265: else
2266: $$ = $<ttype>2;
2267: }
2268: |
2269: named_class_head_sans_basetype_defn
2270: {
2271: $<ttype>$ = xref_defn_tag (current_aggr, $1, NULL_TREE);
2272: }
2273: maybe_base_class_list %prec EMPTY
2274: {
2275: if ($3)
2276: $$ = xref_defn_tag (current_aggr, $1, $3);
2277: else
2278: $$ = $<ttype>2;
2279: }
2280: ;
2281:
2282: unnamed_class_head: aggr '{'
2283: { $$ = xref_tag ($$, make_anon_name (), NULL_TREE);
2284: yyungetc ('{', 1); }
2285: ;
2286:
2287: class_head: unnamed_class_head | named_class_head ;
2288:
2289: maybe_base_class_list:
2290: /* empty */
2291: { $$ = NULL_TREE; }
2292: | ':' %prec EMPTY
2293: { yyungetc(':', 1); $$ = NULL_TREE; }
2294: | ':' base_class_list %prec EMPTY
2295: { $$ = $2; }
2296: ;
2297:
2298: base_class_list:
2299: base_class
2300: | base_class_list ',' base_class
2301: { $$ = chainon ($$, $3); }
2302: ;
2303:
2304: base_class:
2305: base_class.1
2306: { if (! is_aggr_typedef ($$, 1))
2307: $$ = NULL_TREE;
2308: else $$ = build_tree_list ((tree)visibility_default, $$); }
2309: | scoped_base_class
2310: { if (! is_aggr_typedef ($$, 1))
2311: $$ = NULL_TREE;
2312: else $$ = build_tree_list ((tree)visibility_default, $$); }
2313: | base_class_visibility_list base_class.1
2314: { if (! is_aggr_typedef ($2, 1))
2315: $$ = NULL_TREE;
2316: else $$ = build_tree_list ((tree) $$, $2); }
2317: | base_class_visibility_list scoped_base_class
2318: { if (! is_aggr_typedef ($2, 1))
2319: $$ = NULL_TREE;
2320: else $$ = build_tree_list ((tree) $$, $2); }
2321: ;
2322:
2323: scoped_base_class:
2324: base_class.1 SCOPED_TYPENAME
2325: {
2326: /* Kludge!!! See rule "template_type" and the code
2327: * dealing with "template_type_seen_before_scope" in
2328: * yylex(). */
2329: $$ = $2;
2330: }
2331: ;
2332: base_class.1:
2333: template_type_name tmpl.2 template_instantiation
2334: {
2335: extern tree template_type_seen_before_scope;
2336: tree id = $3 ? TYPE_IDENTIFIER ($3) : $1;
2337:
2338: /* Check the rule template_type to get this... */
2339: if (yychar == YYEMPTY)
2340: yychar = YYLEX;
2341: if (yychar == SCOPE) {
2342: template_type_seen_before_scope = id;
2343: yychar = YYLEX;
2344: }
2345: }
2346: | identifier
2347: ;
2348:
2349: base_class_visibility_list:
2350: VISSPEC
2351: | SCSPEC
2352: { if ($<ttype>$ != ridpointers[(int)RID_VIRTUAL])
2353: sorry ("non-virtual visibility");
2354: $$ = visibility_default_virtual; }
2355: | base_class_visibility_list VISSPEC
2356: { int err = 0;
2357: if ($2 == visibility_protected)
2358: {
2359: warning ("`protected' visibility not implemented");
2360: $2 = visibility_public;
2361: err++;
2362: }
2363: else if ($2 == visibility_public)
2364: {
2365: if ($1 == visibility_private)
2366: {
2367: mixed:
2368: error ("base class cannot be public and private");
2369: }
2370: else if ($1 == visibility_default_virtual)
2371: $$ = visibility_public_virtual;
2372: }
2373: else /* $2 == visibility_private */
2374: {
2375: if ($1 == visibility_public)
2376: goto mixed;
2377: else if ($1 == visibility_default_virtual)
2378: $$ = visibility_private_virtual;
2379: }
2380: }
2381: | base_class_visibility_list SCSPEC
2382: { if ($2 != ridpointers[(int)RID_VIRTUAL])
2383: sorry ("non-virtual visibility");
2384: if ($$ == visibility_public)
2385: $$ = visibility_public_virtual;
2386: else if ($$ == visibility_private)
2387: $$ = visibility_private_virtual; }
2388: ;
2389:
2390: left_curly: '{'
2391: { tree t;
2392: push_obstacks_nochange ();
2393: end_temporary_allocation ();
2394:
2395: if (! IS_AGGR_TYPE ($<ttype>0))
2396: {
2397: $<ttype>0 = make_lang_type (RECORD_TYPE);
2398: TYPE_NAME ($<ttype>0) = get_identifier ("erroneous type");
2399: }
2400: if (TYPE_SIZE ($<ttype>0))
2401: duplicate_tag_error ($<ttype>0);
2402: if (TYPE_SIZE ($<ttype>0) || TYPE_BEING_DEFINED ($<ttype>0))
2403: {
2404: t = make_lang_type (TREE_CODE ($<ttype>0));
2405: pushtag (TYPE_IDENTIFIER ($<ttype>0), t);
2406: $<ttype>0 = t;
2407: }
2408: pushclass ($<ttype>0, 0);
2409: TYPE_BEING_DEFINED ($<ttype>0) = 1;
2410: t = TYPE_IDENTIFIER ($<ttype>0);
2411: if (t && IDENTIFIER_TEMPLATE (t))
2412: overload_template_name (t, 1);
2413: }
2414: ;
2415:
2416: opt.component_decl_list:
2417: /* empty */
2418: { $$ = NULL_TREE; }
2419: | component_decl_list
2420: { $$ = build_tree_list ((tree)visibility_default, $$); }
2421: | opt.component_decl_list VISSPEC ':' component_decl_list
2422: { $$ = chainon ($$, build_tree_list ((tree) $2, $4)); }
2423: | opt.component_decl_list VISSPEC ':'
2424: %ifobjc
2425: | DEFS '(' CLASSNAME ')'
2426: {
2427: tree interface = lookup_interface ($3);
2428: if (interface)
2429: $$ = get_class_ivars (interface);
2430: else
2431: {
2432: error ("Cannot find interface declaration for `%s'",
2433: IDENTIFIER_POINTER ($3));
2434: $$ = error_mark_node;
2435: }
2436: }
2437: ;
2438: %endifobjc
2439:
2440: /* Note: we no longer warn about the semicolon after a component_decl_list.
2441: ARM $9.2 says that the semicolon is optional, and therefore allowed. */
2442: component_decl_list:
2443: component_decl
2444: { if ($$ == void_type_node) $$ = NULL_TREE; }
2445: | component_decl_list component_decl
2446: { /* In pushdecl, we created a reverse list of names
2447: in this binding level. Make sure that the chain
2448: of what we're trying to add isn't the item itself
2449: (which can happen with what pushdecl's doing). */
2450: if ($2 != NULL_TREE && $2 != void_type_node)
2451: {
2452: if (TREE_CHAIN ($2) != $$)
2453: $$ = chainon ($$, $2);
2454: else
2455: $$ = $2;
2456: }
2457: }
2458: | component_decl_list ';'
2459: ;
2460:
2461: component_decl:
2462: typed_declspecs components ';'
2463: { do_components:
2464: $$ = grok_x_components ($$, $2);
2465: end_exception_decls ();
2466: }
2467: | typed_declspecs '(' parmlist ')' ';'
2468: { $$ = groktypefield ($$, $3); }
2469: | typed_declspecs '(' parmlist ')' '}'
2470: { error ("missing ';' before right brace");
2471: yyungetc ('}', 0);
2472: $$ = groktypefield ($$, $3); }
2473: | typed_declspecs LEFT_RIGHT ';'
2474: { $$ = groktypefield ($$, empty_parms ()); }
2475: | typed_declspecs LEFT_RIGHT '}'
2476: { error ("missing ';' before right brace");
2477: yyungetc ('}', 0);
2478: $$ = groktypefield ($$, empty_parms ()); }
2479: | declmods components ';'
2480: { goto do_components; }
2481: /* Normal case: make this fast. */
2482: | declmods declarator ';'
2483: { $$ = grokfield ($<ttype>2, $<ttype>$,
2484: NULL_TREE, NULL_TREE, NULL_TREE); }
2485: | declmods components '}'
2486: { error ("missing ';' before right brace");
2487: yyungetc ('}', 0);
2488: goto do_components; }
2489: | declmods '(' parmlist ')' ';'
2490: { $$ = groktypefield ($$, $3); }
2491: | declmods '(' parmlist ')' '}'
2492: { error ("missing ';' before right brace");
2493: yyungetc ('}', 0);
2494: $$ = groktypefield ($$, $3); }
2495: | declmods LEFT_RIGHT ';'
2496: { $$ = groktypefield ($$, empty_parms ()); }
2497: | declmods LEFT_RIGHT '}'
2498: { error ("missing ';' before right brace");
2499: yyungetc ('}', 0);
2500: $$ = groktypefield ($$, empty_parms ()); }
2501: | ':' expr_no_commas ';'
2502: { $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); }
2503: | ':' expr_no_commas '}'
2504: { error ("missing ';' before right brace");
2505: yyungetc ('}', 0);
2506: $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); }
2507: | error
2508: { $$ = NULL_TREE; }
2509:
2510: /* C++: handle constructors, destructors and inline functions */
2511: /* note that INLINE is like a TYPESPEC */
2512: | fn.def2 ':' /* base_init compstmt */
2513: { $$ = finish_method ($$); }
2514: | fn.def2 '{' /* nodecls compstmt */
2515: { $$ = finish_method ($$); }
2516: | notype_declarator maybe_raises ';'
2517: { $$ = grokfield ($$, NULL_TREE, $2, NULL_TREE, NULL_TREE); }
2518: | notype_declarator maybe_raises '}'
2519: { error ("missing ';' before right brace");
2520: yyungetc ('}', 0);
2521: $$ = grokfield ($$, NULL_TREE, $2, NULL_TREE, NULL_TREE); }
2522: ;
2523:
2524: components:
2525: /* empty: possibly anonymous */
2526: { $$ = NULL_TREE; }
2527: | component_declarator0
2528: | components ',' component_declarator
2529: {
2530: /* In this context, void_type_node encodes
2531: friends. They have been recorded elsewhere. */
2532: if ($$ == void_type_node)
2533: $$ = $3;
2534: else
2535: $$ = chainon ($$, $3);
2536: }
2537: ;
2538:
2539: component_declarator0:
2540: declarator maybe_raises maybeasm maybe_attribute
2541: { current_declspecs = $<ttype>0;
2542: $$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3);
2543: cplus_decl_attributes ($$, $4); }
2544: | declarator maybe_raises maybeasm maybe_attribute '=' init
2545: { current_declspecs = $<ttype>0;
2546: $$ = grokfield ($$, current_declspecs, $2, $6, $3);
2547: cplus_decl_attributes ($$, $4); }
2548: | IDENTIFIER ':' expr_no_commas maybe_attribute
2549: { current_declspecs = $<ttype>0;
2550: $$ = grokbitfield ($$, current_declspecs, $3);
2551: cplus_decl_attributes ($$, $4); }
2552: | TYPENAME ':' expr_no_commas maybe_attribute
2553: { current_declspecs = $<ttype>0;
2554: $$ = grokbitfield ($$, current_declspecs, $3);
2555: cplus_decl_attributes ($$, $4); }
2556: | ':' expr_no_commas maybe_attribute
2557: { current_declspecs = $<ttype>0;
2558: $$ = grokbitfield (NULL_TREE, NULL_TREE, $2);
2559: cplus_decl_attributes ($$, $3); }
2560: ;
2561:
2562: component_declarator:
2563: declarator maybe_raises maybeasm maybe_attribute
2564: { $$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3);
2565: cplus_decl_attributes ($$, $4); }
2566: | declarator maybe_raises maybeasm maybe_attribute '=' init
2567: { $$ = grokfield ($$, current_declspecs, $2, $6, $3);
2568: cplus_decl_attributes ($$, $4); }
2569: | IDENTIFIER ':' expr_no_commas maybe_attribute
2570: { $$ = grokbitfield ($$, current_declspecs, $3);
2571: cplus_decl_attributes ($$, $4); }
2572: | TYPENAME ':' expr_no_commas maybe_attribute
2573: { $$ = grokbitfield ($$, current_declspecs, $3);
2574: cplus_decl_attributes ($$, $4); }
2575: | ':' expr_no_commas maybe_attribute
2576: { $$ = grokbitfield (NULL_TREE, NULL_TREE, $2);
2577: cplus_decl_attributes ($$, $3); }
2578: ;
2579:
2580: /* We chain the enumerators in reverse order.
2581: Because of the way enums are built, the order is
2582: insignificant. Take advantage of this fact. */
2583:
2584: enumlist:
2585: enumerator
2586: | enumlist ',' enumerator
2587: { TREE_CHAIN ($3) = $$; $$ = $3; }
2588: ;
2589:
2590: enumerator:
2591: identifier
2592: { $$ = build_enumerator ($$, NULL_TREE); }
2593: | identifier '=' expr_no_commas
2594: { $$ = build_enumerator ($$, $3); }
2595: ;
2596:
2597: /* ANSI type-id (8.1) */
2598: typename:
2599: typed_typespecs absdcl
2600: { $$ = build_decl_list ($$, $2); }
2601: | nonempty_type_quals absdcl
2602: { $$ = build_decl_list ($$, $2); }
2603: ;
2604:
2605: /* ANSI abstract-declarator (8.1) */
2606: absdcl: /* an abstract declarator */
2607: /* empty */ %prec EMPTY
2608: { $$ = NULL_TREE; }
2609: | absdcl1 %prec EMPTY
2610: | START_DECLARATOR absdcl1 %prec EMPTY
2611: { $$ = $2; }
2612: ;
2613:
2614: nonempty_type_quals:
2615: TYPE_QUAL
2616: { $$ = IDENTIFIER_AS_LIST ($$); }
2617: | nonempty_type_quals TYPE_QUAL
2618: { $$ = decl_tree_cons (NULL_TREE, $2, $$); }
2619: ;
2620:
2621: type_quals:
2622: /* empty */
2623: { $$ = NULL_TREE; }
2624: | type_quals TYPE_QUAL
2625: { $$ = decl_tree_cons (NULL_TREE, $2, $$); }
2626: ;
2627:
2628: /* These rules must follow the rules for function declarations
2629: and component declarations. That way, longer rules are preferred. */
2630:
2631: /* An expression which will not live on the momentary obstack. */
2632: nonmomentary_expr:
2633: { $<itype>$ = suspend_momentary (); } expr
2634: { resume_momentary ((int) $<itype>1); $$ = $2; }
2635:
2636: %ifobjc
2637: /* This rule needs to be before after_type_declarator so that we resolve
2638: the reduce/reduce conflict in state 111 correctly. We need to resolve it
2639: the same way that vanilla C++ resolves the reduce/reduce conflict in state
2640: 105. That is we must assume that we are processing a typespec rather than
2641: an after_type_declarator when we see a TYPENAME and aren't sure. For the
2642: OBJECTNAME case this means we must read any protocolrefs, and then resume
2643: processing the typespec. */
2644: protocolrefs:
2645: /* empty */
2646: {
2647: $$ = NULL_TREE;
2648: }
2649: | '<' identifier_list '>'
2650: {
2651: $$ = $2;
2652: }
2653: ;
2654: %endifobjc
2655:
2656: /* A declarator that is allowed only after an explicit typespec. */
2657: /* may all be followed by prec '.' */
2658: after_type_declarator:
2659: after_type_declarator '(' nonnull_exprlist ')' type_quals %prec '.'
2660: { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
2661: | after_type_declarator '(' parmlist ')' type_quals %prec '.'
2662: { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
2663: | after_type_declarator LEFT_RIGHT type_quals %prec '.'
2664: { $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $3); }
2665: | after_type_declarator '(' error ')' type_quals %prec '.'
2666: { $$ = build_parse_node (CALL_EXPR, $$, NULL_TREE, NULL_TREE); }
2667: | after_type_declarator '[' nonmomentary_expr ']'
2668: { $$ = build_parse_node (ARRAY_REF, $$, $3); }
2669: | after_type_declarator '[' ']'
2670: { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); }
2671: | '(' after_type_declarator_no_typename ')'
2672: { $$ = $2; }
2673: | '(' '*' type_quals after_type_declarator ')'
2674: { $$ = make_pointer_declarator ($3, $4); }
2675: | PAREN_STAR_PAREN
2676: { see_typename (); }
2677: | after_type_member_declarator
2678: | '(' '&' type_quals after_type_declarator ')'
2679: { $$ = make_reference_declarator ($3, $4); }
2680: | '*' type_quals after_type_declarator %prec UNARY
2681: { $$ = make_pointer_declarator ($2, $3); }
2682: | '&' type_quals after_type_declarator %prec UNARY
2683: { $$ = make_reference_declarator ($2, $3); }
2684: | TYPENAME
2685: %ifobjc
2686: | OBJECTNAME
2687: %endifobjc
2688: ;
2689:
2690: after_type_declarator_no_typename:
2691: after_type_declarator_no_typename '(' nonnull_exprlist ')' type_quals %prec '.'
2692: { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
2693: | after_type_declarator_no_typename '(' parmlist ')' type_quals %prec '.'
2694: { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
2695: | after_type_declarator_no_typename LEFT_RIGHT type_quals %prec '.'
2696: { $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $3); }
2697: | after_type_declarator_no_typename '(' error ')' type_quals %prec '.'
2698: { $$ = build_parse_node (CALL_EXPR, $$, NULL_TREE, NULL_TREE); }
2699: | after_type_declarator_no_typename '[' nonmomentary_expr ']'
2700: { $$ = build_parse_node (ARRAY_REF, $$, $3); }
2701: | after_type_declarator_no_typename '[' ']'
2702: { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); }
2703: | '(' after_type_declarator_no_typename ')'
2704: { $$ = $2; }
2705: | PAREN_STAR_PAREN
2706: { see_typename (); }
2707: | after_type_member_declarator
2708: | '*' type_quals after_type_declarator %prec UNARY
2709: { $$ = make_pointer_declarator ($2, $3); }
2710: | '&' type_quals after_type_declarator %prec UNARY
2711: { $$ = make_reference_declarator ($2, $3); }
2712: ;
2713:
2714: /* A declarator allowed whether or not there has been
2715: an explicit typespec. These cannot redeclare a typedef-name. */
2716:
2717: notype_declarator:
2718: notype_declarator '(' nonnull_exprlist ')' type_quals %prec '.'
2719: { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
2720: | notype_declarator '(' parmlist ')' type_quals %prec '.'
2721: { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
2722: | notype_declarator LEFT_RIGHT type_quals %prec '.'
2723: { $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $3); }
2724: | notype_declarator '(' error ')' type_quals %prec '.'
2725: { $$ = build_parse_node (CALL_EXPR, $$, NULL_TREE, NULL_TREE); }
2726: | '(' notype_declarator ')'
2727: { $$ = $2; }
2728: | '*' type_quals notype_declarator %prec UNARY
2729: { $$ = make_pointer_declarator ($2, $3); }
2730: | '&' type_quals notype_declarator %prec UNARY
2731: { $$ = make_reference_declarator ($2, $3); }
2732: | notype_declarator '[' nonmomentary_expr ']'
2733: { $$ = build_parse_node (ARRAY_REF, $$, $3); }
2734: | notype_declarator '[' ']'
2735: { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); }
2736: | IDENTIFIER
2737: { see_typename (); }
2738:
2739: /* C++ extensions. */
2740: | operator_name
2741: { see_typename (); }
2742:
2743: | '~' TYPENAME
2744: {
2745: destructor_name:
2746: see_typename ();
2747: $$ = build_parse_node (BIT_NOT_EXPR, $2);
2748: }
2749: | '~' IDENTIFIER
2750: { goto destructor_name; }
2751: | '~' PTYPENAME
2752: { goto destructor_name; }
2753: | id_scope see_typename notype_declarator %prec '('
2754: { see_typename ();
2755: if (TREE_CODE ($$) != SCOPE_REF)
2756: $$ = build_push_scope ($$, $3);
2757: else if (TREE_OPERAND ($$, 1) == NULL_TREE)
2758: TREE_OPERAND ($$, 1) = $3;
2759: else
2760: $$ = build_parse_node (SCOPE_REF, $$, $3);
2761: }
2762: | id_scope see_typename TYPENAME %prec '('
2763: { $$ = build_push_scope ($$, $3); }
2764: | id_scope see_typename TYPENAME '(' nonnull_exprlist ')' type_quals %prec '.'
2765: { $$ = build_push_scope ($$, build_parse_node (CALL_EXPR, $3, $5, $7)); }
2766: | id_scope see_typename TYPENAME '(' parmlist ')' type_quals %prec '.'
2767: { $$ = build_push_scope ($$, build_parse_node (CALL_EXPR, $3, $5, $7)); }
2768: | id_scope see_typename TYPENAME LEFT_RIGHT type_quals %prec '.'
2769: { $$ = build_push_scope ($$, build_parse_node (CALL_EXPR, $3, empty_parms (), $5)); }
2770: | id_scope see_typename TYPENAME '(' error ')' type_quals %prec '.'
2771: { $$ = build_push_scope ($$, build_parse_node (CALL_EXPR, $3, NULL_TREE, NULL_TREE)); }
2772: /* For constructor templates. */
2773: | id_scope see_typename PTYPENAME %prec '('
2774: { $$ = build_push_scope ($$, $3); }
2775: | id_scope see_typename PTYPENAME '(' nonnull_exprlist ')' type_quals %prec '.'
2776: { $$ = build_push_scope ($$, build_parse_node (CALL_EXPR, $3, $5, $7)); }
2777: | id_scope see_typename PTYPENAME '(' parmlist ')' type_quals %prec '.'
2778: { $$ = build_push_scope ($$, build_parse_node (CALL_EXPR, $3, $5, $7)); }
2779: | id_scope see_typename PTYPENAME LEFT_RIGHT type_quals %prec '.'
2780: { $$ = build_push_scope ($$, build_parse_node (CALL_EXPR, $3, empty_parms (), $5)); }
2781: | id_scope see_typename PTYPENAME '(' error ')' type_quals %prec '.'
2782: { $$ = build_push_scope ($$, build_parse_node (CALL_EXPR, $3, NULL_TREE, NULL_TREE)); }
2783: | SCOPE see_typename notype_declarator
2784: { $$ = build_parse_node (SCOPE_REF, NULL_TREE, $3); }
2785: ;
2786:
2787: id_scope: typename_scope
2788: { tree t;
2789: do_id_scope:
2790:
2791: t = resolve_scope_to_name (NULL_TREE, $$);
2792: if (t == NULL_TREE)
2793: {
2794: cp_error ("`%T' is not a valid scope", $$);
2795: $$ = error_mark_node;
2796: }
2797: else
2798: $$ = t;
2799: }
2800: | IDENTIFIER SCOPE
2801: { goto do_id_scope; }
2802: | template_type SCOPE /* try_for_typename %prec EMPTY */
2803: {
2804: if ($$ == error_mark_node)
2805: /* leave it alone */;
2806: else
2807: {
2808: $$ = resolve_scope_to_name (NULL_TREE, TYPE_IDENTIFIER ($$));
2809: if ($$ == NULL_TREE)
2810: {
2811: error ("undefined explicitly scoped type");
2812: $$ = error_mark_node;
2813: }
2814: }
2815: /* if ($3) popclass (1); */
2816: }
2817: ;
2818:
2819: typename_scope:
2820: TYPENAME SCOPE;
2821:
2822: scoped_typename: SCOPED_TYPENAME
2823: | template_type SCOPED_TYPENAME
2824: {
2825: /* Kludge!!! See rule "template_type" and the code
2826: * dealing with "template_type_seen_before_scope" in
2827: * yylex(). */
2828: $$ = $2;
2829: }
2830: /* | template_type SCOPE try_for_typename TYPENAME
2831: {
2832: if ($$ == error_mark_node)
2833: ;
2834: else
2835: {
2836: $$ = build_parse_node (SCOPE_REF,
2837: TYPE_IDENTIFIER ($$),
2838: $4);
2839: }
2840: if ($3) popclass (1);
2841: } */
2842: ;
2843:
2844: absdcl1: /* a nonempty abstract declarator */
2845: '(' absdcl1 ')'
2846: { see_typename ();
2847: $$ = $2; }
2848: /* `(typedef)1' is `int'. */
2849: | '*' type_quals absdcl1 %prec EMPTY
2850: { $$ = make_pointer_declarator ($2, $3); }
2851: | '*' type_quals %prec EMPTY
2852: { $$ = make_pointer_declarator ($2, NULL_TREE); }
2853: | PAREN_STAR_PAREN
2854: { see_typename (); }
2855: | '(' abs_member_declarator ')'
2856: { $$ = $2; }
2857: | '&' type_quals absdcl1 %prec EMPTY
2858: { $$ = make_reference_declarator ($2, $3); }
2859: | '&' type_quals %prec EMPTY
2860: { $$ = make_reference_declarator ($2, NULL_TREE); }
2861: | absdcl1 '(' parmlist ')' type_quals %prec '.'
2862: { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
2863: | absdcl1 LEFT_RIGHT type_quals %prec '.'
2864: { $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $3); }
2865: | absdcl1 '[' nonmomentary_expr ']' %prec '.'
2866: { $$ = build_parse_node (ARRAY_REF, $$, $3); }
2867: | absdcl1 '[' ']' %prec '.'
2868: { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); }
2869: | '(' parmlist ')' type_quals %prec '.'
2870: { $$ = build_parse_node (CALL_EXPR, NULL_TREE, $2, $4); }
2871: | LEFT_RIGHT type_quals %prec '.'
2872: { $$ = build_parse_node (CALL_EXPR, NULL_TREE, empty_parms (), $2); }
2873: | '[' nonmomentary_expr ']' %prec '.'
2874: { $$ = build_parse_node (ARRAY_REF, NULL_TREE, $2); }
2875: | '[' ']' %prec '.'
2876: { $$ = build_parse_node (ARRAY_REF, NULL_TREE, NULL_TREE); }
2877: ;
2878:
2879: abs_member_declarator:
2880: id_scope see_typename '*' type_quals
2881: { tree t;
2882: t = $$;
2883: while (TREE_OPERAND (t, 1))
2884: t = TREE_OPERAND (t, 1);
2885: TREE_OPERAND (t, 1) = build_parse_node (INDIRECT_REF, 0);
2886: }
2887: | id_scope see_typename '*' type_quals absdcl1
2888: { tree t;
2889: t = $$;
2890: while (TREE_OPERAND (t, 1))
2891: t = TREE_OPERAND (t, 1);
2892: TREE_OPERAND (t, 1) = build_parse_node (INDIRECT_REF, $5);
2893: }
2894: | id_scope see_typename '&' type_quals
2895: { tree t;
2896: t = $$;
2897: while (TREE_OPERAND (t, 1))
2898: t = TREE_OPERAND (t, 1);
2899: TREE_OPERAND (t, 1) = build_parse_node (ADDR_EXPR, 0);
2900: }
2901: | id_scope see_typename '&' type_quals absdcl1
2902: { tree t;
2903: t = $$;
2904: while (TREE_OPERAND (t, 1))
2905: t = TREE_OPERAND (t, 1);
2906: TREE_OPERAND (t, 1) = build_parse_node (ADDR_EXPR, $5);
2907: }
2908: ;
2909:
2910: after_type_member_declarator:
2911: id_scope see_typename '*' type_quals after_type_declarator
2912: { tree t;
2913: t = $$;
2914: while (TREE_OPERAND (t, 1))
2915: t = TREE_OPERAND (t, 1);
2916: TREE_OPERAND (t, 1) = build_parse_node (INDIRECT_REF, $5);
2917: }
2918: | id_scope see_typename '&' type_quals after_type_declarator
2919: { tree t;
2920: t = $$;
2921: while (TREE_OPERAND (t, 1))
2922: t = TREE_OPERAND (t, 1);
2923: TREE_OPERAND (t, 1) = build_parse_node (ADDR_EXPR, $5);
2924: }
2925: ;
2926:
2927: /* For C++, decls and stmts can be intermixed, so we don't need to
2928: have a special rule that won't start parsing the stmt section
2929: until we have a stmt that parses without errors. */
2930:
2931: stmts:
2932: stmt
2933: | errstmt
2934: | stmts stmt
2935: | stmts errstmt
2936: ;
2937:
2938: errstmt: error ';'
2939: ;
2940:
2941: /* build the LET_STMT node before parsing its contents,
2942: so that any LET_STMTs within the context can have their display pointers
2943: set up to point at this one. */
2944:
2945: .pushlevel: /* empty */
2946: { emit_line_note (input_filename, lineno);
2947: pushlevel (0);
2948: clear_last_expr ();
2949: push_momentary ();
2950: expand_start_bindings (0);
2951: %ifobjc
2952: if (objc_method_context)
2953: add_objc_decls();
2954: %endifobjc
2955: }
2956: ;
2957:
2958: /* Read zero or more forward-declarations for labels
2959: that nested functions can jump to. */
2960: maybe_label_decls:
2961: /* empty */
2962: | label_decls
2963: { if (pedantic)
2964: pedwarn ("ANSI C++ forbids label declarations"); }
2965: ;
2966:
2967: label_decls:
2968: label_decl
2969: | label_decls label_decl
2970: ;
2971:
2972: label_decl:
2973: LABEL identifiers_or_typenames ';'
2974: { tree link;
2975: for (link = $2; link; link = TREE_CHAIN (link))
2976: {
2977: tree label = shadow_label (TREE_VALUE (link));
2978: C_DECLARED_LABEL_FLAG (label) = 1;
2979: declare_nonlocal_label (label);
2980: }
2981: }
2982: ;
2983:
2984: /* This is the body of a function definition.
2985: It causes syntax errors to ignore to the next openbrace. */
2986: compstmt_or_error:
2987: compstmt
2988: {}
2989: | error compstmt
2990: ;
2991:
2992: compstmt: '{' .pushlevel '}'
2993: { pop_implicit_try_blocks (NULL_TREE);
2994: expand_end_bindings (getdecls (), kept_level_p(), 1);
2995: $$ = poplevel (kept_level_p (), 1, 0);
2996: pop_momentary (); }
2997: | '{' .pushlevel maybe_label_decls stmts '}'
2998: { pop_implicit_try_blocks (NULL_TREE);
2999: expand_end_bindings (getdecls (), kept_level_p(), 1);
3000: $$ = poplevel (kept_level_p (), 1, 0);
3001: pop_momentary (); }
3002: | '{' .pushlevel maybe_label_decls error '}'
3003: { pop_implicit_try_blocks (NULL_TREE);
3004: expand_end_bindings (getdecls (), kept_level_p(), 1);
3005: $$ = poplevel (kept_level_p (), 0, 0);
3006: pop_momentary (); }
3007: ;
3008:
3009: simple_if:
3010: IF
3011: { cond_stmt_keyword = "if"; }
3012: .pushlevel paren_cond_or_null
3013: { emit_line_note (input_filename, lineno);
3014: expand_start_cond (truthvalue_conversion ($4), 0); }
3015: partially_scoped_stmt
3016: ;
3017:
3018: implicitly_scoped_stmt:
3019: compstmt
3020: { finish_stmt (); }
3021: | .pushlevel simple_stmt
3022: { pop_implicit_try_blocks (NULL_TREE);
3023: expand_end_bindings (getdecls (), getdecls() != NULL_TREE, 1);
3024: $$ = poplevel (kept_level_p (), 1, 0);
3025: pop_momentary (); }
3026: ;
3027:
3028: stmt:
3029: compstmt
3030: { finish_stmt (); }
3031: | simple_stmt
3032: ;
3033:
3034: simple_stmt:
3035: decl
3036: { finish_stmt (); }
3037: | expr ';'
3038: {
3039: tree expr = $1;
3040: emit_line_note (input_filename, lineno);
3041: /* Do default conversion if safe and possibly important,
3042: in case within ({...}). */
3043: if ((TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE
3044: && lvalue_p (expr))
3045: || TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE)
3046: expr = default_conversion (expr);
3047: cplus_expand_expr_stmt (expr);
3048: clear_momentary ();
3049: finish_stmt (); }
3050: | simple_if ELSE
3051: { expand_start_else (); }
3052: partially_scoped_stmt
3053: { expand_end_cond ();
3054: pop_implicit_try_blocks (NULL_TREE);
3055: expand_end_bindings (getdecls (), kept_level_p (), 1);
3056: poplevel (kept_level_p (), 1, 0);
3057: pop_momentary ();
3058: finish_stmt (); }
3059: | simple_if %prec IF
3060: { expand_end_cond ();
3061: pop_implicit_try_blocks (NULL_TREE);
3062: expand_end_bindings (getdecls (), kept_level_p (), 1);
3063: poplevel (kept_level_p (), 1, 0);
3064: pop_momentary ();
3065: finish_stmt (); }
3066: | WHILE
3067: { emit_nop ();
3068: emit_line_note (input_filename, lineno);
3069: expand_start_loop (1);
3070: cond_stmt_keyword = "while"; }
3071: .pushlevel paren_cond_or_null
3072: { expand_exit_loop_if_false (0, truthvalue_conversion ($4)); }
3073: already_scoped_stmt
3074: { pop_implicit_try_blocks (NULL_TREE);
3075: expand_end_bindings (getdecls (), kept_level_p (), 1);
3076: poplevel (kept_level_p (), 1, 0);
3077: pop_momentary ();
3078: expand_end_loop ();
3079: finish_stmt (); }
3080: | DO
3081: { emit_nop ();
3082: emit_line_note (input_filename, lineno);
3083: expand_start_loop_continue_elsewhere (1); }
3084: implicitly_scoped_stmt WHILE
3085: { expand_loop_continue_here ();
3086: cond_stmt_keyword = "do"; }
3087: paren_expr_or_null ';'
3088: { emit_line_note (input_filename, lineno);
3089: expand_exit_loop_if_false (0, truthvalue_conversion ($6));
3090: expand_end_loop ();
3091: clear_momentary ();
3092: finish_stmt (); }
3093: | forhead.1
3094: { emit_nop ();
3095: emit_line_note (input_filename, lineno);
3096: if ($1) cplus_expand_expr_stmt ($1);
3097: expand_start_loop_continue_elsewhere (1); }
3098: .pushlevel xcond ';'
3099: { emit_line_note (input_filename, lineno);
3100: if ($4) expand_exit_loop_if_false (0, truthvalue_conversion ($4)); }
3101: xexpr ')'
3102: /* Don't let the tree nodes for $7 be discarded
3103: by clear_momentary during the parsing of the next stmt. */
3104: { push_momentary (); }
3105: already_scoped_stmt
3106: { emit_line_note (input_filename, lineno);
3107: expand_loop_continue_here ();
3108: if ($7) cplus_expand_expr_stmt ($7);
3109: pop_momentary ();
3110: pop_implicit_try_blocks (NULL_TREE);
3111: expand_end_bindings (getdecls (), kept_level_p (), 1);
3112: poplevel (kept_level_p (), 1, 0);
3113: pop_momentary ();
3114: expand_end_loop ();
3115: finish_stmt (); }
3116: | forhead.2
3117: { emit_nop ();
3118: emit_line_note (input_filename, lineno);
3119: expand_start_loop_continue_elsewhere (1); }
3120: .pushlevel xcond ';'
3121: { emit_line_note (input_filename, lineno);
3122: if ($4) expand_exit_loop_if_false (0, truthvalue_conversion ($4)); }
3123: xexpr ')'
3124: /* Don't let the tree nodes for $7 be discarded
3125: by clear_momentary during the parsing of the next stmt. */
3126: { push_momentary ();
3127: $<itype>8 = lineno; }
3128: already_scoped_stmt
3129: { emit_line_note (input_filename, (int) $<itype>8);
3130: expand_loop_continue_here ();
3131: if ($7) cplus_expand_expr_stmt ($7);
3132: pop_momentary ();
3133: pop_implicit_try_blocks (NULL_TREE);
3134: expand_end_bindings (getdecls (), kept_level_p (), 1);
3135: poplevel (kept_level_p (), 1, 0);
3136: pop_momentary ();
3137: expand_end_loop ();
3138: finish_stmt ();
3139: }
3140: | SWITCH .pushlevel '(' condition ')'
3141: { emit_line_note (input_filename, lineno);
3142: c_expand_start_case ($4);
3143: /* Don't let the tree nodes for $4 be discarded by
3144: clear_momentary during the parsing of the next stmt. */
3145: push_momentary (); }
3146: partially_scoped_stmt
3147: { expand_end_case ($4);
3148: pop_momentary ();
3149: pop_implicit_try_blocks (NULL_TREE);
3150: expand_end_bindings (getdecls (), kept_level_p (), 1);
3151: poplevel (kept_level_p (), 1, 0);
3152: pop_momentary ();
3153: finish_stmt (); }
3154: | CASE expr_no_commas ':'
3155: { register tree value = $2;
3156: register tree label
3157: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
3158:
3159: /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
3160: Strip such NOP_EXPRs. */
3161: if (TREE_CODE (value) == NOP_EXPR
3162: && TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0)))
3163: value = TREE_OPERAND (value, 0);
3164:
3165: if (TREE_READONLY_DECL_P (value))
3166: {
3167: value = decl_constant_value (value);
3168: /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
3169: Strip such NOP_EXPRs. */
3170: if (TREE_CODE (value) == NOP_EXPR
3171: && TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0)))
3172: value = TREE_OPERAND (value, 0);
3173: }
3174: value = fold (value);
3175:
3176: if (TREE_CODE (value) != INTEGER_CST
3177: && value != error_mark_node)
3178: {
3179: cp_error ("case label `%E' does not reduce to an integer constant", $2);
3180: value = error_mark_node;
3181: }
3182: else
3183: /* Promote char or short to int. */
3184: value = default_conversion (value);
3185: if (value != error_mark_node)
3186: {
3187: tree duplicate;
3188: int success = pushcase (value, convert_and_check,
3189: label, &duplicate);
3190: if (success == 1)
3191: cp_error ("case label `%E' not within a switch statement", $2);
3192: else if (success == 2)
3193: {
3194: cp_error ("duplicate case value `%E'", $2);
3195: cp_error_at ("`%E' previously used here", duplicate);
3196: }
3197: else if (success == 3)
3198: warning ("case value out of range");
3199: else if (success == 5)
3200: cp_error ("case label `%E' within scope of cleanup or variable array", $2);
3201: }
3202: define_case_label (label);
3203: }
3204: stmt
3205: | CASE expr_no_commas RANGE expr_no_commas ':'
3206: { register tree value1 = $2;
3207: register tree value2 = $4;
3208: register tree label
3209: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
3210:
3211: if (pedantic)
3212: pedwarn ("ANSI C++ forbids range expressions in switch statement");
3213:
3214: /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
3215: Strip such NOP_EXPRs. */
3216: if (TREE_CODE (value1) == NOP_EXPR
3217: && TREE_TYPE (value1) == TREE_TYPE (TREE_OPERAND (value1, 0)))
3218: value1 = TREE_OPERAND (value1, 0);
3219:
3220: if (TREE_READONLY_DECL_P (value1))
3221: {
3222: value1 = decl_constant_value (value1);
3223: /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
3224: Strip such NOP_EXPRs. */
3225: if (TREE_CODE (value1) == NOP_EXPR
3226: && TREE_TYPE (value1) == TREE_TYPE (TREE_OPERAND (value1, 0)))
3227: value1 = TREE_OPERAND (value1, 0);
3228: }
3229: value1 = fold (value1);
3230:
3231: /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
3232: Strip such NOP_EXPRs. */
3233: if (TREE_CODE (value2) == NOP_EXPR
3234: && TREE_TYPE (value2) == TREE_TYPE (TREE_OPERAND (value2, 0)))
3235: value2 = TREE_OPERAND (value2, 0);
3236:
3237: if (TREE_READONLY_DECL_P (value2))
3238: {
3239: value2 = decl_constant_value (value2);
3240: /* build_c_cast puts on a NOP_EXPR to make a non-lvalue.
3241: Strip such NOP_EXPRs. */
3242: if (TREE_CODE (value2) == NOP_EXPR
3243: && TREE_TYPE (value2) == TREE_TYPE (TREE_OPERAND (value2, 0)))
3244: value2 = TREE_OPERAND (value2, 0);
3245: }
3246: value2 = fold (value2);
3247:
3248:
3249: if (TREE_CODE (value1) != INTEGER_CST
3250: && value1 != error_mark_node)
3251: {
3252: error ("case label does not reduce to an integer constant");
3253: value1 = error_mark_node;
3254: }
3255: if (TREE_CODE (value2) != INTEGER_CST
3256: && value2 != error_mark_node)
3257: {
3258: error ("case label does not reduce to an integer constant");
3259: value2 = error_mark_node;
3260: }
3261: if (value1 != error_mark_node
3262: && value2 != error_mark_node)
3263: {
3264: tree duplicate;
3265: int success = pushcase_range (value1, value2,
3266: convert_and_check, label,
3267: &duplicate);
3268: if (success == 1)
3269: error ("case label not within a switch statement");
3270: else if (success == 2)
3271: {
3272: error ("duplicate (or overlapping) case value");
3273: error_with_decl (duplicate, "this is the first entry overlapping that value");
3274: }
3275: else if (success == 3)
3276: warning ("case value out of range");
3277: else if (success == 4)
3278: warning ("empty range specified");
3279: else if (success == 5)
3280: error ("case label within scope of cleanup or variable array");
3281: }
3282: define_case_label (label);
3283: }
3284: stmt
3285: | DEFAULT ':'
3286: {
3287: tree duplicate;
3288: register tree label
3289: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
3290: int success = pushcase (NULL_TREE, 0, label, &duplicate);
3291: if (success == 1)
3292: error ("default label not within a switch statement");
3293: else if (success == 2)
3294: {
3295: error ("multiple default labels in one switch");
3296: error_with_decl (duplicate, "this is the first default label");
3297: }
3298: define_case_label (NULL_TREE);
3299: }
3300: stmt
3301: | BREAK ';'
3302: { emit_line_note (input_filename, lineno);
3303: if ( ! expand_exit_something ())
3304: error ("break statement not within loop or switch"); }
3305: | CONTINUE ';'
3306: { emit_line_note (input_filename, lineno);
3307: if (! expand_continue_loop (0))
3308: error ("continue statement not within a loop"); }
3309: | RETURN ';'
3310: { emit_line_note (input_filename, lineno);
3311: c_expand_return (NULL_TREE); }
3312: | RETURN expr ';'
3313: { emit_line_note (input_filename, lineno);
3314: c_expand_return ($2);
3315: finish_stmt ();
3316: }
3317: | asm_keyword maybe_type_qual '(' string ')' ';'
3318: { if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
3319: emit_line_note (input_filename, lineno);
3320: expand_asm ($4);
3321: finish_stmt ();
3322: }
3323: /* This is the case with just output operands. */
3324: | asm_keyword maybe_type_qual '(' string ':' asm_operands ')' ';'
3325: { if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
3326: emit_line_note (input_filename, lineno);
3327: c_expand_asm_operands ($4, $6, NULL_TREE, NULL_TREE,
3328: $2 == ridpointers[(int)RID_VOLATILE],
3329: input_filename, lineno);
3330: finish_stmt ();
3331: }
3332: /* This is the case with input operands as well. */
3333: | asm_keyword maybe_type_qual '(' string ':' asm_operands ':' asm_operands ')' ';'
3334: { if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
3335: emit_line_note (input_filename, lineno);
3336: c_expand_asm_operands ($4, $6, $8, NULL_TREE,
3337: $2 == ridpointers[(int)RID_VOLATILE],
3338: input_filename, lineno);
3339: finish_stmt ();
3340: }
3341: /* This is the case with clobbered registers as well. */
3342: | asm_keyword maybe_type_qual '(' string ':' asm_operands ':'
3343: asm_operands ':' asm_clobbers ')' ';'
3344: { if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
3345: emit_line_note (input_filename, lineno);
3346: c_expand_asm_operands ($4, $6, $8, $10,
3347: $2 == ridpointers[(int)RID_VOLATILE],
3348: input_filename, lineno);
3349: finish_stmt ();
3350: }
3351: | GOTO '*' expr ';'
3352: { emit_line_note (input_filename, lineno);
3353: expand_computed_goto ($3); }
3354: | GOTO identifier ';'
3355: { tree decl;
3356: emit_line_note (input_filename, lineno);
3357: decl = lookup_label ($2);
3358: TREE_USED (decl) = 1;
3359: expand_goto (decl); }
3360: | label_colon stmt
3361: { finish_stmt (); }
3362: | label_colon '}'
3363: { error ("label must be followed by statement");
3364: yyungetc ('}', 0);
3365: finish_stmt (); }
3366: | ';'
3367: { finish_stmt (); }
3368:
3369: /* Exception handling extensions. */
3370: | ANSI_THROW ';' { cplus_expand_throw (NULL_TREE); }
3371: | ANSI_THROW expr ';' { cplus_expand_throw ($2); }
3372: | THROW raise_identifier '(' nonnull_exprlist ')' ';'
3373: { cplus_expand_raise ($2, $4, NULL_TREE, 0);
3374: finish_stmt (); }
3375: | THROW raise_identifier LEFT_RIGHT ';'
3376: { cplus_expand_raise ($2, NULL_TREE, NULL_TREE, 0);
3377: finish_stmt (); }
3378: | RAISE raise_identifier '(' nonnull_exprlist ')' ';'
3379: { cplus_expand_raise ($2, $4, NULL_TREE, 0);
3380: finish_stmt (); }
3381: | RAISE raise_identifier LEFT_RIGHT ';'
3382: { cplus_expand_raise ($2, NULL_TREE, NULL_TREE, 0);
3383: finish_stmt (); }
3384: | RAISE identifier ';'
3385: { cplus_expand_reraise ($2);
3386: finish_stmt (); }
3387: | try EXCEPT identifier '{'
3388: {
3389: tree decl = cplus_expand_end_try ($1);
3390: $<ttype>2 = current_exception_type;
3391: $<ttype>4 = current_exception_decl;
3392: $<ttype>$ = current_exception_object;
3393: cplus_expand_start_except ($3, decl);
3394: pushlevel (0);
3395: clear_last_expr ();
3396: push_momentary ();
3397: expand_start_bindings (0);
3398: }
3399: except_stmts '}'
3400: {
3401: tree decls = getdecls ();
3402: /* If there is a default exception to handle,
3403: handle it here. */
3404: if ($6)
3405: {
3406: tree decl = build_decl (CPLUS_CATCH_DECL, NULL_TREE, 0);
3407: tree block;
3408:
3409: pushlevel (1);
3410: expand_start_bindings (0);
3411: expand_expr ($6, 0, 0, 0);
3412: expand_end_bindings (0, 1, 0);
3413: block = poplevel (1, 0, 0);
3414:
3415: /* This is a catch block. */
3416: TREE_LANG_FLAG_2 (block) = 1;
3417: BLOCK_VARS (block) = decl;
3418: }
3419:
3420: expand_end_bindings (decls, decls != 0, 1);
3421: poplevel (decls != 0, 1, 0);
3422: pop_momentary ();
3423: current_exception_type = $<ttype>2;
3424: current_exception_decl = $<ttype>4;
3425: current_exception_object = $<ttype>5;
3426: cplus_expand_end_except ($6);
3427: }
3428: | try error
3429: {
3430: cplus_expand_end_try ($1);
3431: /* These are the important actions of
3432: `cplus_expand_end_except' which we must emulate. */
3433: if (expand_escape_except ())
3434: expand_end_except ();
3435: expand_end_bindings (0, 0, 1);
3436: poplevel (0, 0, 0);
3437: }
3438: | ansi_try ansi_dummy ansi_dummy
3439: {
3440: tree decl = cplus_expand_end_try ($1);
3441: $<ttype>2 = current_exception_type;
3442: $<ttype>3 = current_exception_decl;
3443: $<ttype>$ = current_exception_object;
3444: cplus_expand_start_except (NULL, decl);
3445: pushlevel (0);
3446: clear_last_expr ();
3447: push_momentary ();
3448: expand_start_bindings (0);
3449: }
3450: ansi_except_stmts
3451: {
3452: tree decls = getdecls ();
3453: /* If there is a default exception to handle,
3454: handle it here. */
3455: if ($5)
3456: {
3457: tree decl = build_decl (CPLUS_CATCH_DECL, NULL_TREE, 0);
3458: tree block;
3459:
3460: pushlevel (1);
3461: expand_start_bindings (0);
3462: expand_expr ($5, 0, 0, 0);
3463: expand_end_bindings (0, 1, 0);
3464: block = poplevel (1, 0, 0);
3465:
3466: /* This is a catch block. */
3467: TREE_LANG_FLAG_2 (block) = 1;
3468: BLOCK_VARS (block) = decl;
3469: }
3470:
3471: expand_end_bindings (decls, decls != 0, 1);
3472: poplevel (decls != 0, 1, 0);
3473: pop_momentary ();
3474: current_exception_type = $<ttype>2;
3475: current_exception_decl = $<ttype>3;
3476: current_exception_object = $<ttype>4;
3477: cplus_expand_end_except ($5);
3478: }
3479: | try RERAISE raise_identifiers /* ';' checked for at bottom. */
3480: { tree name = get_identifier ("(compiler error)");
3481: tree orig_ex_type = current_exception_type;
3482: tree orig_ex_decl = current_exception_decl;
3483: tree orig_ex_obj = current_exception_object;
3484: tree decl = cplus_expand_end_try ($1), decls;
3485:
3486: /* Start hidden EXCEPT. */
3487: cplus_expand_start_except (name, decl);
3488: pushlevel (0);
3489: clear_last_expr ();
3490: push_momentary ();
3491: expand_start_bindings (0);
3492:
3493: /* This sets up the reraise. */
3494: cplus_expand_reraise ($3);
3495:
3496: decls = getdecls ();
3497: expand_end_bindings (decls, decls != 0, 1);
3498: poplevel (decls != 0, 1, 0);
3499: pop_momentary ();
3500: current_exception_type = orig_ex_type;
3501: current_exception_decl = orig_ex_decl;
3502: current_exception_object = orig_ex_obj;
3503: /* This will reraise for us. */
3504: cplus_expand_end_except (error_mark_node);
3505: if (yychar == YYEMPTY)
3506: yychar = YYLEX;
3507: if (yychar != ';')
3508: error ("missing ';' after reraise statement");
3509: }
3510: | try %prec EMPTY
3511: { yyerror ("`except' missing after `try' statement");
3512: /* Terminate the binding contour started by special
3513: code in `.pushlevel'. Automagically pops off
3514: the conditional we started for `try' stmt. */
3515: cplus_expand_end_try ($1);
3516: expand_end_bindings (0, 0, 1);
3517: poplevel (0, 0, 0);
3518: pop_momentary ();
3519: YYERROR; }
3520: ;
3521:
3522: try: try_head '}'
3523: /* An empty try block is degenerate, but it's better to
3524: do extra work here than to do all the special-case work
3525: everywhere else. */
3526: {
3527: $$ = 1;
3528: pop_implicit_try_blocks (NULL_TREE);
3529: }
3530: | try_head stmts '}'
3531: {
3532: $$ = 1;
3533: pop_implicit_try_blocks (NULL_TREE);
3534: }
3535: | try_head error '}'
3536: {
3537: $$ = 0;
3538: pop_implicit_try_blocks (NULL_TREE);
3539: }
3540: ;
3541:
3542: label_colon:
3543: IDENTIFIER ':'
3544: { tree label;
3545: do_label:
3546: label = define_label (input_filename, lineno, $1);
3547: if (label)
3548: expand_label (label);
3549: }
3550: | PTYPENAME ':'
3551: { goto do_label; }
3552: | TYPENAME_COLON
3553: { tree label = define_label (input_filename, lineno, $1);
3554: if (label)
3555: expand_label (label);
3556: }
3557: ;
3558:
3559: try_head: TRY '{' { cplus_expand_start_try (0); } .pushlevel
3560:
3561: ansi_try: ansi_try_head '}'
3562: /* An empty try block is degenerate, but it's better to
3563: do extra work here than to do all the special-case work
3564: everywhere else. */
3565: {
3566: $$ = 1;
3567: pop_implicit_try_blocks (NULL_TREE);
3568: }
3569: | ansi_try_head stmts '}'
3570: {
3571: $$ = 1;
3572: pop_implicit_try_blocks (NULL_TREE);
3573: }
3574: | ansi_try_head error '}'
3575: {
3576: $$ = 0;
3577: pop_implicit_try_blocks (NULL_TREE);
3578: }
3579: ;
3580:
3581: ansi_dummy: ; /* Temporary place-holder. */
3582: ansi_try_head: ANSI_TRY '{' { cplus_expand_start_try (0); } .pushlevel
3583:
3584: except_stmts:
3585: /* empty */
3586: { $$ = NULL_TREE; }
3587: | except_stmts raise_identifier
3588: {
3589: tree type = lookup_exception_type (current_class_type, current_class_name, $2);
3590: if (type == NULL_TREE)
3591: {
3592: error ("`%s' is not an exception type",
3593: IDENTIFIER_POINTER (TREE_VALUE ($2)));
3594: current_exception_type = NULL_TREE;
3595: TREE_TYPE (current_exception_object) = error_mark_node;
3596: }
3597: else
3598: {
3599: current_exception_type = type;
3600: /* In-place union. */
3601: TREE_TYPE (current_exception_object) = type;
3602: }
3603: $2 = cplus_expand_start_catch ($2);
3604: pushlevel (1);
3605: expand_start_bindings (0);
3606: }
3607: compstmt
3608: {
3609: expand_end_bindings (0, 1, 0);
3610: $4 = poplevel (1, 0, 0);
3611:
3612: cplus_expand_end_catch (0);
3613:
3614: /* Mark this as a catch block. */
3615: TREE_LANG_FLAG_2 ($4) = 1;
3616: if ($2 != error_mark_node)
3617: {
3618: tree decl = build_decl (CPLUS_CATCH_DECL, DECL_NAME ($2), 0);
3619: DECL_RTL (decl) = DECL_RTL ($2);
3620: TREE_CHAIN (decl) = BLOCK_VARS ($4);
3621: BLOCK_VARS ($4) = decl;
3622: }
3623: }
3624: | except_stmts DEFAULT
3625: {
3626: if ($1)
3627: error ("duplicate default in exception handler");
3628: current_exception_type = NULL_TREE;
3629: /* Takes it right out of scope. */
3630: TREE_TYPE (current_exception_object) = error_mark_node;
3631:
3632: if (! expand_catch_default ())
3633: compiler_error ("default catch botch");
3634:
3635: /* The default exception is handled as the
3636: last in the chain of exceptions handled. */
3637: do_pending_stack_adjust ();
3638: $1 = make_node (RTL_EXPR);
3639: TREE_TYPE ($1) = void_type_node;
3640: start_sequence_for_rtl_expr ($1);
3641: }
3642: compstmt
3643: {
3644: extern struct rtx_def *get_insns ();
3645: do_pending_stack_adjust ();
3646: if (! expand_catch (NULL_TREE))
3647: compiler_error ("except nesting botch");
3648: if (! expand_end_catch ())
3649: compiler_error ("except nesting botch");
3650: RTL_EXPR_SEQUENCE ($1) = get_insns ();
3651: if ($4)
3652: {
3653: /* Mark this block as the default catch block. */
3654: TREE_LANG_FLAG_1 ($4) = 1;
3655: TREE_LANG_FLAG_2 ($4) = 1;
3656: }
3657: end_sequence ();
3658: }
3659: ;
3660:
3661: optional_identifier:
3662: /* empty */
3663: { $$ = NULL_TREE; }
3664: | identifier ;
3665:
3666: ansi_except_stmts:
3667: /* empty */
3668: { $$ = NULL_TREE; }
3669: | ansi_except_stmts CATCH '(' typename optional_identifier ')'
3670: {
3671: tree type = groktypename ($4);
3672: current_exception_type = type;
3673: /* In-place union. */
3674: if ($5)
3675: {
3676: tree tmp;
3677: tmp = pushdecl (build_decl (VAR_DECL, $5, type));
3678: current_exception_object =
3679: build1 (INDIRECT_REF, type, tmp);
3680: }
3681: $4 = ansi_expand_start_catch(type);
3682: pushlevel (1);
3683: expand_start_bindings (0);
3684: }
3685: compstmt
3686: {
3687: expand_end_bindings (0, 1, 0);
3688: $8 = poplevel (1, 0, 0);
3689:
3690: cplus_expand_end_catch (0);
3691:
3692: /* Mark this as a catch block. */
3693: TREE_LANG_FLAG_2 ($8) = 1;
3694: if ($4 != error_mark_node)
3695: {
3696: tree decl = build_decl (CPLUS_CATCH_DECL, DECL_NAME ($4), 0);
3697: DECL_RTL (decl) = DECL_RTL ($4);
3698: TREE_CHAIN (decl) = BLOCK_VARS ($8);
3699: BLOCK_VARS ($8) = decl;
3700: }
3701: }
3702: ;
3703:
3704: forhead.1:
3705: FOR '(' ';'
3706: { $$ = NULL_TREE; }
3707: | FOR '(' expr ';'
3708: { $$ = $3; }
3709: | FOR '(' '{' '}'
3710: { $$ = NULL_TREE; }
3711: ;
3712:
3713: forhead.2:
3714: FOR '(' decl
3715: { $$ = 0; }
3716: | FOR '(' error ';'
3717: { $$ = 0; }
3718: | FOR '(' '{' .pushlevel stmts '}'
3719: { $$ = 1; }
3720: | FOR '(' '{' .pushlevel error '}'
3721: { $$ = -1; }
3722: ;
3723:
3724: /* Either a type-qualifier or nothing. First thing in an `asm' statement. */
3725:
3726: maybe_type_qual:
3727: /* empty */
3728: { emit_line_note (input_filename, lineno);
3729: $$ = NULL_TREE; }
3730: | TYPE_QUAL
3731: { emit_line_note (input_filename, lineno); }
3732: ;
3733:
3734: xexpr:
3735: /* empty */
3736: { $$ = NULL_TREE; }
3737: | expr
3738: | error
3739: { $$ = NULL_TREE; }
3740: ;
3741:
3742: /* These are the operands other than the first string and colon
3743: in asm ("addextend %2,%1": "=dm" (x), "0" (y), "g" (*x)) */
3744: asm_operands: /* empty */
3745: { $$ = NULL_TREE; }
3746: | nonnull_asm_operands
3747: ;
3748:
3749: nonnull_asm_operands:
3750: asm_operand
3751: | nonnull_asm_operands ',' asm_operand
3752: { $$ = chainon ($$, $3); }
3753: ;
3754:
3755: asm_operand:
3756: STRING '(' expr ')'
3757: { $$ = build_tree_list ($$, $3); }
3758: ;
3759:
3760: asm_clobbers:
3761: STRING
3762: { $$ = tree_cons (NULL_TREE, $$, NULL_TREE); }
3763: | asm_clobbers ',' STRING
3764: { $$ = tree_cons (NULL_TREE, $3, $$); }
3765: ;
3766:
3767: /* This is what appears inside the parens in a function declarator.
3768: Its value is represented in the format that grokdeclarator expects.
3769:
3770: In C++, declaring a function with no parameters
3771: means that that function takes *no* parameters. */
3772: parmlist: /* empty */
3773: {
3774: if (strict_prototype)
3775: $$ = void_list_node;
3776: else
3777: $$ = NULL_TREE;
3778: }
3779: | parms
3780: {
3781: $$ = chainon ($$, void_list_node);
3782: TREE_PARMLIST ($$) = 1;
3783: }
3784: | parms ',' ELLIPSIS
3785: {
3786: TREE_PARMLIST ($$) = 1;
3787: }
3788: /* C++ allows an ellipsis without a separating ',' */
3789: | parms ELLIPSIS
3790: {
3791: TREE_PARMLIST ($$) = 1;
3792: }
3793: | ELLIPSIS
3794: {
3795: /* ARM $8.2.5 has this as a boxed-off comment. */
3796: if (pedantic)
3797: warning ("use of `...' without a first argument is non-portable");
3798: $$ = NULL_TREE;
3799: }
3800: | TYPENAME_ELLIPSIS
3801: {
3802: TREE_PARMLIST ($$) = 1;
3803: }
3804: | parms TYPENAME_ELLIPSIS
3805: {
3806: TREE_PARMLIST ($$) = 1;
3807: }
3808: | parms ':'
3809: {
3810: /* This helps us recover from really nasty
3811: parse errors, for example, a missing right
3812: parenthesis. */
3813: yyerror ("possibly missing ')'");
3814: $$ = chainon ($$, void_list_node);
3815: TREE_PARMLIST ($$) = 1;
3816: yyungetc (':', 0);
3817: yychar = ')';
3818: }
3819: ;
3820:
3821: /* A nonempty list of parameter declarations or type names. */
3822: parms:
3823: parm
3824: { $$ = build_tree_list (NULL_TREE, $$); }
3825: | parm '=' init
3826: { $$ = build_tree_list ($3, $$); }
3827: | parms ',' parm
3828: { $$ = chainon ($$, build_tree_list (NULL_TREE, $3)); }
3829: | parms ',' parm '=' init
3830: { $$ = chainon ($$, build_tree_list ($5, $3)); }
3831: | parms ',' bad_parm
3832: { $$ = chainon ($$, build_tree_list (NULL_TREE, $3)); }
3833: | parms ',' bad_parm '=' init
3834: { $$ = chainon ($$, build_tree_list ($5, $3)); }
3835: ;
3836:
3837: /* A single parameter declaration or parameter type name,
3838: as found in a parmlist. The first four cases make up for 10%
3839: of the time spent parsing C++. We cannot use them because
3840: of `int id[]' which won't get parsed properly. */
3841: parm:
3842: /*
3843: typed_declspecs dont_see_typename '*' IDENTIFIER
3844: { $$ = build_tree_list ($$, build_parse_node (INDIRECT_REF, $4));
3845: see_typename (); }
3846: | typed_declspecs dont_see_typename '&' IDENTIFIER
3847: { $$ = build_tree_list ($$, build_parse_node (ADDR_EXPR, $4));
3848: see_typename (); }
3849: | TYPENAME IDENTIFIER
3850: { $$ = build_tree_list (list_hash_lookup_or_cons ($$), $2); }
3851: | TYPESPEC IDENTIFIER
3852: { $$ = build_tree_list (list_hash_lookup_or_cons ($$), $2); }
3853: | */
3854: typed_declspecs dont_see_typename abs_or_notype_decl
3855: { $$ = build_tree_list ($$, $3);
3856: see_typename (); }
3857: | declmods dont_see_typename abs_or_notype_decl
3858: { $$ = build_tree_list ($$, $3);
3859: see_typename (); }
3860: ;
3861:
3862: abs_or_notype_decl: absdcl
3863: | notype_declarator
3864: | START_DECLARATOR notype_declarator
3865: { $$ = $2; }
3866: ;
3867:
3868: see_typename: type_quals
3869: { see_typename (); }
3870: ;
3871:
3872: dont_see_typename: /* empty */
3873: { dont_see_typename (); }
3874: ;
3875:
3876: /*
3877: try_for_typename:
3878: {
3879: if ($<ttype>-1 == error_mark_node)
3880: $$ = 0;
3881: else
3882: {
3883: $$ = 1;
3884: pushclass ($<ttype>-1, 1);
3885: }
3886: }
3887: ;
3888: */
3889:
3890: bad_parm:
3891: abs_or_notype_decl
3892: {
3893: warning ("type specifier omitted for parameter");
3894: $$ = build_tree_list (TREE_PURPOSE (TREE_VALUE ($<ttype>-1)), $$);
3895: }
3896: ;
3897:
3898: maybe_raises:
3899: /* empty */
3900: { $$ = NULL_TREE; }
3901: | RAISES raise_identifiers %prec EMPTY
3902: { $$ = $2; }
3903: | ANSI_THROW '(' ansi_raise_identifiers ')' %prec EMPTY
3904: { $$ = $3; }
3905: ;
3906:
3907: raise_identifier:
3908: ALL
3909: { $$ = void_list_node; }
3910: | IDENTIFIER
3911: { $$ = build_decl_list (NULL_TREE, $$); }
3912: | TYPENAME
3913: { $$ = build_decl_list (NULL_TREE, $$); }
3914: | SCOPE IDENTIFIER
3915: { $$ = build_decl_list (void_type_node, $2); }
3916: | SCOPE TYPENAME
3917: { $$ = build_decl_list (void_type_node, $2); }
3918: %ifobjc
3919: | OBJECTNAME
3920: { $$ = build_decl_list (NULL_TREE, $$); }
3921: %endifobjc
3922: | id_scope IDENTIFIER
3923: { $$ = build_decl_list ($$, $2); }
3924: | scoped_typename
3925: ;
3926:
3927: ansi_raise_identifier:
3928: typename
3929: { $$ = build_decl_list (NULL_TREE, $$); }
3930: ;
3931:
3932: raise_identifiers:
3933: raise_identifier
3934: | raise_identifiers ',' raise_identifier
3935: {
3936: TREE_CHAIN ($3) = $$;
3937: $$ = $3;
3938: }
3939: ;
3940:
3941: ansi_raise_identifiers:
3942: ansi_raise_identifier
3943: | ansi_raise_identifiers ',' ansi_raise_identifier
3944: {
3945: TREE_CHAIN ($3) = $$;
3946: $$ = $3;
3947: }
3948: ;
3949:
3950: operator_name:
3951: OPERATOR '*'
3952: { $$ = ansi_opname[MULT_EXPR]; }
3953: | OPERATOR '/'
3954: { $$ = ansi_opname[TRUNC_DIV_EXPR]; }
3955: | OPERATOR '%'
3956: { $$ = ansi_opname[TRUNC_MOD_EXPR]; }
3957: | OPERATOR '+'
3958: { $$ = ansi_opname[PLUS_EXPR]; }
3959: | OPERATOR '-'
3960: { $$ = ansi_opname[MINUS_EXPR]; }
3961: | OPERATOR '&'
3962: { $$ = ansi_opname[BIT_AND_EXPR]; }
3963: | OPERATOR '|'
3964: { $$ = ansi_opname[BIT_IOR_EXPR]; }
3965: | OPERATOR '^'
3966: { $$ = ansi_opname[BIT_XOR_EXPR]; }
3967: | OPERATOR '~'
3968: { $$ = ansi_opname[BIT_NOT_EXPR]; }
3969: | OPERATOR ','
3970: { $$ = ansi_opname[COMPOUND_EXPR]; }
3971: | OPERATOR ARITHCOMPARE
3972: { $$ = ansi_opname[$2]; }
3973: | OPERATOR '<'
3974: { $$ = ansi_opname[LT_EXPR]; }
3975: | OPERATOR '>'
3976: { $$ = ansi_opname[GT_EXPR]; }
3977: | OPERATOR EQCOMPARE
3978: { $$ = ansi_opname[$2]; }
3979: | OPERATOR ASSIGN
3980: { $$ = ansi_assopname[$2]; }
3981: | OPERATOR '='
3982: {
3983: $$ = ansi_opname [MODIFY_EXPR];
3984: if (current_class_type)
3985: {
3986: TYPE_HAS_ASSIGNMENT (current_class_type) = 1;
3987: TYPE_GETS_ASSIGNMENT (current_class_type) = 1;
3988: }
3989: }
3990: | OPERATOR LSHIFT
3991: { $$ = ansi_opname[$2]; }
3992: | OPERATOR RSHIFT
3993: { $$ = ansi_opname[$2]; }
3994: | OPERATOR PLUSPLUS
3995: { $$ = ansi_opname[POSTINCREMENT_EXPR]; }
3996: | OPERATOR MINUSMINUS
3997: { $$ = ansi_opname[PREDECREMENT_EXPR]; }
3998: | OPERATOR ANDAND
3999: { $$ = ansi_opname[TRUTH_ANDIF_EXPR]; }
4000: | OPERATOR OROR
4001: { $$ = ansi_opname[TRUTH_ORIF_EXPR]; }
4002: | OPERATOR '!'
4003: { $$ = ansi_opname[TRUTH_NOT_EXPR]; }
4004: | OPERATOR '?' ':'
4005: { $$ = ansi_opname[COND_EXPR]; }
4006: | OPERATOR MIN_MAX
4007: { $$ = ansi_opname[$2]; }
4008: | OPERATOR POINTSAT %prec EMPTY
4009: { $$ = ansi_opname[COMPONENT_REF];
4010: if (current_class_type)
4011: {
4012: tree t = current_class_type;
4013: while (t)
4014: {
4015: TYPE_OVERLOADS_ARROW (t) = 1;
4016: t = TYPE_NEXT_VARIANT (t);
4017: }
4018: }
4019: }
4020: | OPERATOR POINTSAT_STAR %prec EMPTY
4021: { $$ = ansi_opname[MEMBER_REF];
4022: if (current_class_type)
4023: {
4024: tree t = current_class_type;
4025: while (t)
4026: {
4027: TYPE_OVERLOADS_ARROW (t) = 1;
4028: t = TYPE_NEXT_VARIANT (t);
4029: }
4030: }
4031: }
4032: | OPERATOR LEFT_RIGHT
4033: { $$ = ansi_opname[CALL_EXPR];
4034: if (current_class_type)
4035: {
4036: tree t = current_class_type;
4037: while (t)
4038: {
4039: TYPE_OVERLOADS_CALL_EXPR (t) = 1;
4040: t = TYPE_NEXT_VARIANT (t);
4041: }
4042: }
4043: }
4044: | OPERATOR '[' ']'
4045: { $$ = ansi_opname[ARRAY_REF];
4046: if (current_class_type)
4047: {
4048: tree t = current_class_type;
4049: while (t)
4050: {
4051: TYPE_OVERLOADS_ARRAY_REF (t) = 1;
4052: t = TYPE_NEXT_VARIANT (t);
4053: }
4054: }
4055: }
4056: | OPERATOR NEW
4057: {
4058: $$ = ansi_opname[NEW_EXPR];
4059: if (current_class_type)
4060: {
4061: tree t = current_class_type;
4062: while (t)
4063: {
4064: TREE_GETS_NEW (t) = 1;
4065: t = TYPE_NEXT_VARIANT (t);
4066: }
4067: }
4068: }
4069: /*
4070: | OPERATOR NEW '[' ']'
4071: {
4072: $$ = ansi_opname[VEC_NEW_EXPR];
4073: if (current_class_type)
4074: {
4075: tree t = current_class_type;
4076: while (t)
4077: {
4078: TREE_GETS_VEC_NEW (t) = 1;
4079: t = TYPE_NEXT_VARIANT (t);
4080: }
4081: }
4082: }
4083: */
4084: | OPERATOR DELETE
4085: {
4086: $$ = ansi_opname[DELETE_EXPR];
4087: if (current_class_type)
4088: {
4089: tree t = current_class_type;
4090: while (t)
4091: {
4092: TREE_GETS_DELETE (t) = 1;
4093: t = TYPE_NEXT_VARIANT (t);
4094: }
4095: }
4096: }
4097: /*
4098: | OPERATOR DELETE '[' ']'
4099: {
4100: $$ = ansi_opname[VEC_DELETE_EXPR];
4101: if (current_class_type)
4102: {
4103: tree t = current_class_type;
4104: while (t)
4105: {
4106: TREE_GETS_VEC_DELETE (t) = 1;
4107: t = TYPE_NEXT_VARIANT (t);
4108: }
4109: }
4110: }
4111: */
4112:
4113: /* These should do `groktypename' and set up TREE_HAS_X_CONVERSION
4114: here, rather than doing it in class.c . */
4115: | OPERATOR typed_typespecs absdcl
4116: { $$ = build1 (TYPE_EXPR, $2, $3); }
4117: | OPERATOR error
4118: { $$ = ansi_opname[ERROR_MARK]; }
4119: ;
4120:
4121:
4122: /*
4123: * Objective-C productions.
4124: */
4125:
4126: /* records the type and storage class specs to use for processing
4127: the declarators that follow */
4128:
4129: %ifobjc
4130: .setspecs: /* empty */
4131: { current_declspecs = $<ttype>0;
4132: $<itype>$ = suspend_momentary (); }
4133: ;
4134:
4135: objcdef:
4136: classdef
4137: | classdecl
4138: | protocoldecl
4139: | aliasdecl
4140: | protocoldef
4141: | methoddef
4142: | END
4143: {
4144: if (objc_implementation_context)
4145: {
4146: finish_class(objc_implementation_context);
4147: objc_ivar_chain = NULL_TREE;
4148: objc_implementation_context = NULL_TREE;
4149: }
4150: else
4151: warning("`@end' must appear in an implementation context");
4152: }
4153: ;
4154:
4155: /* A nonempty list of identifiers. */
4156: identifier_list:
4157: identifier
4158: { $$ = build_tree_list (NULL_TREE, $1); }
4159: | identifier_list ',' identifier
4160: { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
4161: ;
4162:
4163: classdecl:
4164: CLASS identifier_list ';'
4165: {
4166: objc_declare_class ($2);
4167: }
4168:
4169: protocoldecl:
4170: PROTOCOL identifier_list ';'
4171: {
4172: objc_declare_protocols ($2);
4173: }
4174:
4175: aliasdecl:
4176: ALIAS identifier identifier ';'
4177: {
4178: objc_declare_alias ($2, $3);
4179: }
4180:
4181: /* This is necessary for living in this c++ parser */
4182: identifier_colon:
4183: identifier ':'
4184: { $$ = $1 }
4185: | TYPENAME_COLON
4186: ;
4187:
4188: classdef:
4189: INTERFACE identifier protocolrefs '{'
4190: {
4191: objc_interface_context = objc_ivar_context
4192: = start_class (CLASS_INTERFACE_TYPE, $2, NULL_TREE, $3);
4193: objc_public_flag = 0;
4194: }
4195: ivar_decl_list '}'
4196: {
4197: continue_class (objc_interface_context);
4198: }
4199: methodprotolist
4200: END
4201: {
4202: finish_class (objc_interface_context);
4203: objc_interface_context = NULL_TREE;
4204: }
4205:
4206: | INTERFACE identifier protocolrefs
4207: {
4208: objc_interface_context
4209: = start_class (CLASS_INTERFACE_TYPE, $2, NULL_TREE, $3);
4210: continue_class (objc_interface_context);
4211: }
4212: methodprotolist
4213: END
4214: {
4215: finish_class(objc_interface_context);
4216: objc_interface_context = NULL_TREE;
4217: }
4218:
4219: | INTERFACE identifier_colon identifier protocolrefs '{'
4220: {
4221: objc_interface_context = objc_ivar_context
4222: = start_class (CLASS_INTERFACE_TYPE, $2, $3, $4);
4223: objc_public_flag = 0;
4224: }
4225: ivar_decl_list '}'
4226: {
4227: continue_class (objc_interface_context);
4228: }
4229: methodprotolist
4230: END
4231: {
4232: finish_class(objc_interface_context);
4233: objc_interface_context = NULL_TREE;
4234: }
4235:
4236: | INTERFACE identifier_colon identifier protocolrefs
4237: {
4238: objc_interface_context
4239: = start_class (CLASS_INTERFACE_TYPE, $2, $3, $4);
4240: continue_class (objc_interface_context);
4241: }
4242: methodprotolist
4243: END
4244: {
4245: finish_class (objc_interface_context);
4246: objc_interface_context = NULL_TREE;
4247: }
4248:
4249: | IMPLEMENTATION identifier '{'
4250: {
4251: objc_implementation_context = objc_ivar_context
4252: = start_class (CLASS_IMPLEMENTATION_TYPE, $2, NULL_TREE, NULL_TREE);
4253: objc_public_flag = 0;
4254: }
4255: ivar_decl_list '}'
4256: {
4257: objc_ivar_chain
4258: = continue_class (objc_implementation_context);
4259: }
4260:
4261: | IMPLEMENTATION identifier
4262: {
4263: objc_implementation_context
4264: = start_class (CLASS_IMPLEMENTATION_TYPE, $2, NULL_TREE, NULL_TREE);
4265: objc_ivar_chain
4266: = continue_class (objc_implementation_context);
4267: }
4268:
4269: | IMPLEMENTATION identifier_colon identifier '{'
4270: {
4271: objc_implementation_context = objc_ivar_context
4272: = start_class (CLASS_IMPLEMENTATION_TYPE, $2, $3, NULL_TREE);
4273: objc_public_flag = 0;
4274: }
4275: ivar_decl_list '}'
4276: {
4277: objc_ivar_chain
4278: = continue_class (objc_implementation_context);
4279: }
4280:
4281: | IMPLEMENTATION identifier_colon identifier
4282: {
4283: objc_implementation_context
4284: = start_class (CLASS_IMPLEMENTATION_TYPE, $2, $3, NULL_TREE);
4285: objc_ivar_chain
4286: = continue_class (objc_implementation_context);
4287: }
4288:
4289: | INTERFACE identifier '(' identifier ')' protocolrefs
4290: {
4291: objc_interface_context
4292: = start_class (CATEGORY_INTERFACE_TYPE, $2, $4, $6);
4293: continue_class (objc_interface_context);
4294: }
4295: methodprotolist
4296: END
4297: {
4298: finish_class (objc_interface_context);
4299: objc_interface_context = NULL_TREE;
4300: }
4301:
4302: | IMPLEMENTATION identifier '(' identifier ')'
4303: {
4304: objc_implementation_context
4305: = start_class (CATEGORY_IMPLEMENTATION_TYPE, $2, $4, NULL_TREE);
4306: objc_ivar_chain
4307: = continue_class (objc_implementation_context);
4308: }
4309: ;
4310:
4311: protocoldef:
4312: PROTOCOL identifier protocolrefs
4313: {
4314: objc_interface_context =
4315: start_protocol(PROTOCOL_INTERFACE_TYPE, $2, $3);
4316: }
4317: methodprotolist
4318: END
4319: {
4320: finish_protocol(objc_interface_context);
4321: objc_interface_context = NULL_TREE;
4322: }
4323: ;
4324:
4325: ivar_decl_list:
4326: ivar_decl_list visibility_spec ivar_decls
4327: | ivar_decls
4328: ;
4329:
4330: visibility_spec:
4331: PUBLIC { objc_public_flag = 1; }
4332: | PRIVATE { objc_public_flag = 2; }
4333: | PROTECTED { objc_public_flag = 0; }
4334: ;
4335:
4336: ivar_decls:
4337: /* empty */
4338: {
4339: $$ = NULL_TREE;
4340: }
4341: | ivar_decls ivar_decl ';'
4342: | ivar_decls ';'
4343: {
4344: if (pedantic)
4345: warning ("extra semicolon in struct or union specified");
4346: }
4347: ;
4348:
4349: ivar_decl:
4350: typed_typespecs .setspecs ivars
4351: {
4352: $$ = $3;
4353: resume_momentary ($<itype>2);
4354: }
4355: | nonempty_type_quals .setspecs ivars
4356: {
4357: $$ = $3;
4358: resume_momentary ($<itype>2);
4359: }
4360: | error
4361: { $$ = NULL_TREE; }
4362: ;
4363:
4364: ivars:
4365: /* empty */
4366: { $$ = NULL_TREE; }
4367: | ivar_declarator
4368: | ivars ',' ivar_declarator
4369: ;
4370:
4371: ivar_declarator:
4372: declarator
4373: {
4374: $$ = add_instance_variable(objc_ivar_context, objc_public_flag,
4375: $1, current_declspecs, NULL_TREE);
4376: }
4377: | declarator ':' expr_no_commas
4378: {
4379: $$ = add_instance_variable(objc_ivar_context, objc_public_flag,
4380: $1, current_declspecs, $3);
4381: }
4382: | ':' expr_no_commas
4383: {
4384: $$ = add_instance_variable(objc_ivar_context, objc_public_flag,
4385: NULL_TREE, current_declspecs, $2);
4386: }
4387: ;
4388:
4389: methoddef:
4390: '+'
4391: {
4392: if (objc_implementation_context)
4393: objc_inherit_code = CLASS_METHOD_DECL;
4394: else
4395: fatal("Illegal method definition - must be in a class context.");
4396: }
4397: methoddecl
4398: {
4399: add_class_method(objc_implementation_context,$3);
4400: start_method_def ($3);
4401: objc_method_context = $3;
4402: }
4403: optarglist
4404: {
4405: continue_method_def();
4406: }
4407: compstmt_or_error
4408: {
4409: finish_method_def ();
4410: objc_method_context = NULL_TREE;
4411: }
4412:
4413: | '-'
4414: {
4415: if (objc_implementation_context)
4416: objc_inherit_code = INSTANCE_METHOD_DECL;
4417: else
4418: fatal("Illegal method definition - must be in a class context.");
4419: }
4420: methoddecl
4421: {
4422: add_instance_method(objc_implementation_context,$3);
4423: start_method_def ($3);
4424: objc_method_context = $3;
4425: }
4426: optarglist
4427: {
4428: continue_method_def();
4429: }
4430: compstmt_or_error
4431: {
4432: finish_method_def ();
4433: objc_method_context = NULL_TREE;
4434: }
4435: ;
4436:
4437: /* the reason for the strange actions in this rule
4438: is so that notype_initdecls when reached via datadef
4439: can find a valid list of type and sc specs in $0. */
4440:
4441: methodprotolist:
4442: /* empty */
4443: | {$<ttype>$ = NULL_TREE; } methodprotolist2
4444: ;
4445:
4446: methodprotolist2: /* eliminates a shift/reduce conflict */
4447: methodproto
4448: | datadef
4449: | methodprotolist2 methodproto
4450: | methodprotolist2 {$<ttype>$ = NULL_TREE; } datadef
4451: ;
4452:
4453: semi_or_error:
4454: ';'
4455: | error
4456: ;
4457:
4458: methodproto:
4459: '+'
4460: {
4461: objc_inherit_code = CLASS_METHOD_DECL;
4462: }
4463: methoddecl
4464: {
4465: add_class_method(objc_interface_context,$3);
4466: }
4467: semi_or_error
4468:
4469: | '-'
4470: {
4471: objc_inherit_code = INSTANCE_METHOD_DECL;
4472: }
4473: methoddecl
4474: {
4475: add_instance_method(objc_interface_context,$3);
4476: }
4477: semi_or_error
4478: ;
4479:
4480: methodtype:
4481: '('
4482: {
4483: remember_protocol_qualifiers();
4484: }
4485: typename
4486: {
4487: forget_protocol_qualifiers();
4488: }
4489: ')'
4490: { $$ = $3; }
4491: ;
4492:
4493: methoddecl:
4494: methodtype unaryselector
4495: {
4496: $$ = build_method_decl (objc_inherit_code, $1, $2, NULL_TREE);
4497: }
4498:
4499: | unaryselector
4500: {
4501: $$ = build_method_decl (objc_inherit_code, NULL_TREE, $1, NULL_TREE);
4502: }
4503:
4504: | methodtype keywordselector optparmlist
4505: {
4506: $$ = build_method_decl (objc_inherit_code, $1, $2, $3);
4507: }
4508:
4509: | keywordselector optparmlist
4510: {
4511: $$ = build_method_decl (objc_inherit_code, NULL_TREE, $1, $2);
4512: }
4513: ;
4514:
4515:
4516: /* "optarglist" assumes that start_method_def() has already been called...
4517: if it is not, the "xdecls" will not be placed in the proper scope */
4518:
4519: optarglist:
4520: /* empty */
4521: | ';' myxdecls
4522: ;
4523:
4524: /* to get around the following situation: "int foo(int a) int b; {}" that
4525: is synthesized when parsing "- a:a b:b; id c; id d; { ... }" */
4526:
4527: myxdecls:
4528: /* empty */
4529: | mydecls
4530: ;
4531:
4532: mydecls:
4533: mydecl
4534: | errstmt
4535: | mydecls mydecl
4536: | mydecl errstmt
4537: ;
4538:
4539: mydecl:
4540: typed_declspecs .setspecs myparms ';'
4541: { resume_momentary ($<itype>2); }
4542: | typed_declspecs ';'
4543: { shadow_tag ($1); }
4544: | declmods ';'
4545: { warning ("empty declaration"); }
4546: ;
4547:
4548: /* this must be converted to live in the g++ world...snaroff */
4549:
4550: myparms:
4551: myparm
4552: { objcplus_push_parm_decl ($1); }
4553: | myparms ',' myparm
4554: { objcplus_push_parm_decl ($3); }
4555: ;
4556:
4557: /* A single parameter declaration or parameter type name,
4558: as found in a parmlist. DOES NOT ALLOW AN INITIALIZER OR ASMSPEC */
4559:
4560: myparm:
4561: dont_see_typename notype_declarator
4562: { $$ = build_tree_list (current_declspecs, $2) ; }
4563: | notype_declarator
4564: { $$ = build_tree_list (current_declspecs, $1) ; }
4565: | absdcl
4566: { $$ = build_tree_list (current_declspecs, $1) ; }
4567: ;
4568:
4569: optparmlist:
4570: /* empty */
4571: {
4572: $$ = NULL_TREE;
4573: }
4574: | ',' ELLIPSIS
4575: {
4576: /* oh what a kludge! */
4577: $$ = (tree)1;
4578: }
4579: | ','
4580: {
4581: pushlevel (0);
4582: }
4583: parmlist
4584: {
4585: /* returns a tree list node generated by `get_parm_info()' */
4586: $$ = $3;
4587: poplevel(0,0,0);
4588: }
4589: ;
4590:
4591: unaryselector:
4592: selector
4593: ;
4594:
4595: keywordselector:
4596: keyworddecl
4597: | keywordselector keyworddecl
4598: {
4599: $$ = chainon($1, $2);
4600: }
4601: ;
4602:
4603: selector:
4604: IDENTIFIER
4605: | TYPENAME
4606: | OBJECTNAME
4607: | reservedword
4608: ;
4609:
4610: reservedword:
4611: ENUM { $$ = get_identifier("enum"); }
4612: | AGGR
4613: {
4614: if (yylval.ttype == class_type_node)
4615: $$ = get_identifier("class");
4616: else if (yylval.ttype == record_type_node)
4617: $$ = get_identifier("struct");
4618: else if (yylval.ttype == union_type_node)
4619: $$ = get_identifier("union");
4620: else if (yylval.ttype == enum_type_node)
4621: $$ = get_identifier("enum");
4622: else
4623: abort ();
4624: }
4625: | IF { $$ = get_identifier("if"); }
4626: | ELSE { $$ = get_identifier("else"); }
4627: | WHILE { $$ = get_identifier("while"); }
4628: | DO { $$ = get_identifier("do"); }
4629: | FOR { $$ = get_identifier("for"); }
4630: | SWITCH { $$ = get_identifier("switch"); }
4631: | CASE { $$ = get_identifier("case"); }
4632: | DEFAULT { $$ = get_identifier("default"); }
4633: | BREAK { $$ = get_identifier("break"); }
4634: | CONTINUE { $$ = get_identifier("continue"); }
4635: | RETURN { $$ = get_identifier("return"); }
4636: | GOTO { $$ = get_identifier("goto"); }
4637: | ASM_KEYWORD { $$ = get_identifier("asm"); }
4638: | SIZEOF { $$ = get_identifier("sizeof"); }
4639: | TYPEOF { $$ = get_identifier("typeof"); }
4640: | ALIGNOF { $$ = get_identifier("alignof"); }
4641: | NEW { $$ = get_identifier("new"); }
4642: | DELETE { $$ = get_identifier("delete"); }
4643: | OPERATOR { $$ = get_identifier("operator"); }
4644: | VISSPEC {
4645: if ($1 == visibility_private)
4646: $$ = get_identifier ("private");
4647: else if ($1 == visibility_public)
4648: $$ = get_identifier ("public");
4649: else if ($1 == visibility_protected)
4650: $$ = get_identifier ("protected");
4651: else
4652: abort ();
4653: }
4654: | SCSPEC { $$ = yylval.ttype; }
4655: | TYPESPEC { $$ = yylval.ttype; }
4656: | OVERLOAD { $$ = get_identifier("overload"); }
4657: ;
4658:
4659: keyworddecl:
4660: selector ':' methodtype identifier
4661: {
4662: $$ = build_keyword_decl($1, $3, $4);
4663: }
4664:
4665: | selector ':' identifier
4666: {
4667: $$ = build_keyword_decl($1, NULL_TREE, $3);
4668: }
4669:
4670: | ':' methodtype identifier
4671: {
4672: $$ = build_keyword_decl(NULL_TREE, $2, $3);
4673: }
4674:
4675: | ':' identifier
4676: {
4677: $$ = build_keyword_decl(NULL_TREE, NULL_TREE, $2);
4678: }
4679: ;
4680:
4681: messageargs:
4682: selector
4683: | keywordarglist
4684: ;
4685:
4686: keywordarglist:
4687: keywordarg
4688: | keywordarglist keywordarg
4689: {
4690: $$ = chainon($1, $2);
4691: }
4692: ;
4693:
4694:
4695: keywordexpr:
4696: nonnull_exprlist
4697: {
4698: if (TREE_CHAIN($1) == NULL_TREE)
4699: /* just return the expr., remove a level of indirection */
4700: $$ = TREE_VALUE($1);
4701: else
4702: /* we have a comma expr., we will collapse later */
4703: $$ = $1;
4704: }
4705: ;
4706:
4707: keywordarg:
4708: selector ':' keywordexpr
4709: {
4710: $$ = build_tree_list($1, $3);
4711: }
4712: | ':' keywordexpr
4713: {
4714: $$ = build_tree_list(NULL_TREE,$2);
4715: }
4716: ;
4717:
4718: receiver:
4719: nonnull_exprlist
4720: {
4721: $$ = build_x_compound_expr ($1);
4722: }
4723: | CLASSNAME
4724: {
4725: $$ = get_class_reference($1);
4726: }
4727: ;
4728:
4729: objc_openbracket.expr:
4730: '['
4731: { objc_receiver_context = 1; objc_msg_context += 1; }
4732: receiver
4733: { objc_receiver_context = 0; $$ = $3; }
4734: ;
4735:
4736: objc_closebracket:
4737: ']'
4738: { objc_msg_context -= 1; }
4739: ;
4740:
4741: objcmessageexpr:
4742: objc_openbracket.expr
4743: messageargs
4744: objc_closebracket
4745: {
4746: $$ = build_tree_list($1,$2);
4747: TREE_TYPE ($$) = NULL_TREE;
4748: }
4749: /*
4750: | CLASSNAME SCOPE '['
4751: { objc_receiver_context = 1; }
4752: receiver
4753: { objc_receiver_context = 0; }
4754: messageargs ']'
4755: {
4756: $$ = build_tree_list($5,$7);
4757: TREE_TYPE ($$) = get_class_reference ($1);
4758: }
4759: */
4760: ;
4761:
4762: selectorarg:
4763: selector
4764: | keywordnamelist
4765: ;
4766:
4767: keywordnamelist:
4768: keywordname
4769: | keywordnamelist keywordname
4770: {
4771: $$ = chainon ($1, $2);
4772: }
4773: ;
4774:
4775: keywordname:
4776: selector ':'
4777: {
4778: $$ = build_tree_list ($1, NULL_TREE);
4779: }
4780: | ':'
4781: {
4782: $$ = build_tree_list (NULL_TREE,NULL_TREE);
4783: }
4784: | SCOPE
4785: {
4786: $$ = chainon (build_tree_list (NULL_TREE,NULL_TREE),
4787: build_tree_list (NULL_TREE,NULL_TREE));
4788: }
4789: ;
4790:
4791: objcselectorexpr:
4792: SELECTOR '(' selectorarg ')'
4793: {
4794: $$ = $3;
4795: }
4796: ;
4797:
4798: objcprotocolexpr:
4799: PROTOCOL '(' identifier ')'
4800: {
4801: $$ = $3;
4802: }
4803: ;
4804:
4805: /* extension to support C-structures in the archiver */
4806:
4807: objcencodeexpr:
4808: ENCODE '(' typename ')'
4809: {
4810: $$ = groktypename($3);
4811: }
4812: ;
4813: %endifobjc
4814: %%
4815:
4816:
4817:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.