|
|
1.1 root 1: /* YACC parser for C++ syntax.
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:
22: /* This grammar is based on the GNU CC grammar. */
23:
24: /* Note: Bison automatically applies a default action of "$$ = $1" for
25: all derivations; this is applied before the explicit action, if one
26: is given. Keep this in mind when reading the actions. */
27:
28: /* Also note: this version contains experimental exception
29: handling features. They could break, change, disappear,
30: or otherwise exhibit volatile behavior. Don't depend on
31: me (Michael Tiemann) to protect you from any negative impact
32: this may have on your professional, personal, or spiritual life.
33:
34: NEWS FLASH: This version now supports the exception handling
35: syntax of Stroustrup's 2nd edition, if -fansi-exceptions is given.
36: THIS IS WORK IN PROGRESS!!! The type of the 'throw' and the
37: 'catch' much match EXACTLY (no inheritance support or coercions).
38: Also, throw-specifications of functions don't work.
39: Destructors aren't called correctly. Etc, etc. --Per Bothner.
40: */
41:
42: %{
43: /* Cause the `yydebug' variable to be defined. */
44: #define YYDEBUG 1
45:
46: #include "config.h"
47:
48: #include <stdio.h>
49: #include <errno.h>
50:
51: #include "tree.h"
52: #include "input.h"
53: #include "flags.h"
54: #include "lex.h"
55: #include "cp-tree.h"
56:
57: /* Since parsers are distinct for each language, put the language string
58: definition here. (fnf) */
59: char *language_string = "GNU C++";
60:
61: extern tree void_list_node;
62: extern struct obstack permanent_obstack;
63:
64: #ifndef errno
65: extern int errno;
66: #endif
67:
68: extern int end_of_file;
69: extern int current_class_depth;
70:
71: void yyerror ();
72:
73: /* Like YYERROR but do call yyerror. */
74: #define YYERROR1 { yyerror ("syntax error"); YYERROR; }
75:
76: #define OP0(NODE) (TREE_OPERAND (NODE, 0))
77: #define OP1(NODE) (TREE_OPERAND (NODE, 1))
78:
79: /* Contains the statement keyword (if/while/do) to include in an
80: error message if the user supplies an empty conditional expression. */
81: static char *cond_stmt_keyword;
82:
83: /* Nonzero if we have an `extern "C"' acting as an extern specifier. */
84: int have_extern_spec;
85: int used_extern_spec;
86:
87: void yyhook ();
88:
89: /* Cons up an empty parameter list. */
90: #ifdef __GNUC__
91: __inline
92: #endif
93: static tree
94: empty_parms ()
95: {
96: tree parms;
97:
98: if (strict_prototype)
99: parms = void_list_node;
100: else
101: parms = NULL_TREE;
102: return parms;
103: }
104: %}
105:
106: %start program
107:
108: %union {long itype; tree ttype; char *strtype; enum tree_code code; }
109:
110: /* All identifiers that are not reserved words
111: and are not declared typedefs in the current block */
112: %token IDENTIFIER
113:
114: /* All identifiers that are declared typedefs in the current block.
115: In some contexts, they are treated just like IDENTIFIER,
116: but they can also serve as typespecs in declarations. */
117: %token TYPENAME
118:
119: /* Reserved words that specify storage class.
120: yylval contains an IDENTIFIER_NODE which indicates which one. */
121: %token SCSPEC
122:
123: /* Reserved words that specify type.
124: yylval contains an IDENTIFIER_NODE which indicates which one. */
125: %token TYPESPEC
126:
127: /* Reserved words that qualify type: "const" or "volatile".
128: yylval contains an IDENTIFIER_NODE which indicates which one. */
129: %token TYPE_QUAL
130:
131: /* Character or numeric constants.
132: yylval is the node for the constant. */
133: %token CONSTANT
134:
135: /* String constants in raw form.
136: yylval is a STRING_CST node. */
137: %token STRING
138:
139: /* "...", used for functions with variable arglists. */
140: %token ELLIPSIS
141:
142: /* the reserved words */
143: /* SCO include files test "ASM", so use something else. */
144: %token SIZEOF ENUM /* STRUCT UNION */ IF ELSE WHILE DO FOR SWITCH CASE DEFAULT
145: %token BREAK CONTINUE RETURN GOTO ASM_KEYWORD GCC_ASM_KEYWORD TYPEOF ALIGNOF
146: %token HEADOF CLASSOF SIGOF
147: %token ATTRIBUTE EXTENSION LABEL
148:
149: /* the reserved words... C++ extensions */
150: %token <ttype> AGGR
151: %token <itype> VISSPEC
152: %token DELETE NEW OVERLOAD THIS OPERATOR CXX_TRUE CXX_FALSE
153: %token LEFT_RIGHT TEMPLATE
154: %token TYPEID DYNAMIC_CAST STATIC_CAST REINTERPRET_CAST CONST_CAST
155: %token <itype> SCOPE
156:
157: /* Define the operator tokens and their precedences.
158: The value is an integer because, if used, it is the tree code
159: to use in the expression made from the operator. */
160:
161: %left EMPTY /* used to resolve s/r with epsilon */
162:
163: %left error
164:
165: /* Add precedence rules to solve dangling else s/r conflict */
166: %nonassoc IF
167: %nonassoc ELSE
168:
169: %left IDENTIFIER TYPENAME PTYPENAME SCSPEC TYPESPEC TYPE_QUAL ENUM AGGR ELLIPSIS TYPEOF SIGOF OPERATOR
170:
171: %left '{' ',' ';'
172:
173: %right <code> ASSIGN '='
174: %right <code> '?' ':'
175: %left <code> OROR
176: %left <code> ANDAND
177: %left <code> '|'
178: %left <code> '^'
179: %left <code> '&'
180: %left <code> MIN_MAX
181: %left <code> EQCOMPARE
182: %left <code> ARITHCOMPARE '<' '>'
183: %left <code> LSHIFT RSHIFT
184: %left <code> '+' '-'
185: %left <code> '*' '/' '%'
186: %left <code> POINTSAT_STAR DOT_STAR
187: %right <code> UNARY PLUSPLUS MINUSMINUS '~'
188: %left HYPERUNARY
189: %left <ttype> PAREN_STAR_PAREN LEFT_RIGHT
190: %left <code> POINTSAT '.' '(' '['
191:
192: %right SCOPE /* C++ extension */
193: %nonassoc NEW DELETE TRY CATCH THROW
194:
195: %type <code> unop
196:
197: %type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist
198: %type <ttype> paren_expr_or_null nontrivial_exprlist
199: %type <ttype> expr_no_commas cast_expr unary_expr primary string STRING
200: %type <ttype> typed_declspecs reserved_declspecs boolean.literal
201: %type <ttype> typed_typespecs reserved_typespecquals
202: %type <ttype> declmods typespec typespecqual_reserved
203: %type <ttype> SCSPEC TYPESPEC TYPE_QUAL nonempty_type_quals maybe_type_qual
204: %type <itype> initdecls notype_initdecls initdcl /* C++ modification */
205: %type <ttype> init initlist maybeasm
206: %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
207: %type <ttype> maybe_attribute attributes attribute attribute_list attrib
208: %type <ttype> any_word
209:
210: %type <ttype> compstmt implicitly_scoped_stmt
211:
212: %type <ttype> declarator notype_declarator after_type_declarator
213: %type <ttype> direct_notype_declarator direct_after_type_declarator
214:
215: %type <ttype> structsp opt.component_decl_list component_decl_list
216: %type <ttype> component_decl components component_declarator
217: %type <ttype> notype_components notype_component_declarator
218: %type <ttype> after_type_component_declarator after_type_component_declarator0
219: %type <ttype> notype_component_declarator0 component_decl_1
220: %type <ttype> enumlist enumerator
221: %type <ttype> type_id absdcl type_quals
222: %type <ttype> direct_abstract_declarator conversion_declarator
223: %type <ttype> new_type_id new_declarator direct_new_declarator
224: %type <ttype> xexpr parmlist parms parm bad_parm full_parm
225: %type <ttype> identifiers_or_typenames
226: %type <ttype> fcast_or_absdcl regcast_or_absdcl sub_cast_expr
227: %type <ttype> expr_or_declarator complex_notype_declarator
228: %type <ttype> notype_unqualified_id unqualified_id qualified_id
229: %type <ttype> overqualified_id notype_qualified_id
230: %type <ttype> complex_direct_notype_declarator functional_cast
231: %type <ttype> named_parm complex_parmlist typed_declspecs1 parms_comma
232:
233: /* C++ extensions */
234: %token <ttype> TYPENAME_ELLIPSIS PTYPENAME
235: %token <ttype> PRE_PARSED_FUNCTION_DECL EXTERN_LANG_STRING ALL
236: %token <ttype> PRE_PARSED_CLASS_DECL
237: %type <ttype> fn.def1 /* Not really! */
238: %type <ttype> fn.def2 return_id
239: %type <ttype> named_class_head named_class_head_sans_basetype
240: %type <ttype> unnamed_class_head
241: %type <ttype> class_head base_class_list
242: %type <itype> base_class_access_list
243: %type <ttype> base_class maybe_base_class_list base_class.1
244: %type <ttype> maybe_raises ansi_raise_identifier ansi_raise_identifiers
245: %type <ttype> component_declarator0
246: %type <ttype> forhead.1 operator_name
247: %type <ttype> object aggr
248: %type <itype> new delete
249: /* %type <ttype> primary_no_id */
250: %type <ttype> nonmomentary_expr
251: %type <itype> forhead.2 initdcl0 notype_initdcl0 member_init_list
252: %type <ttype> template_header template_parm_list template_parm
253: %type <ttype> template_type_parm
254: %type <ttype> template_type template_arg_list template_arg
255: %type <ttype> template_instantiation template_type_name tmpl.2
256: %type <ttype> template_instantiate_once template_instantiate_some
257: %type <itype> fn_tmpl_end
258: /* %type <itype> try_for_typename */
259: %type <ttype> condition xcond paren_cond_or_null
260: %type <ttype> type_name nested_name_specifier nested_type ptr_to_mem
261: %type <ttype> qualified_type_name complete_type_name notype_identifier
262: %type <ttype> complex_type_name nested_name_specifier_1
263: %type <itype> nomods_initdecls nomods_initdcl0
264: %type <ttype> new_initializer new_placement specialization type_specifier_seq
265:
266: /* in order to recognize aggr tags as defining and thus shadowing. */
267: %token TYPENAME_DEFN IDENTIFIER_DEFN PTYPENAME_DEFN
268: %type <ttype> named_class_head_sans_basetype_defn
269: %type <ttype> identifier_defn IDENTIFIER_DEFN TYPENAME_DEFN PTYPENAME_DEFN
270:
271: %type <strtype> .pushlevel
272:
273: /* spew.c depends on this being the last token. Define
274: any new tokens before this one! */
275: %token END_OF_SAVED_INPUT
276:
277: %{
278: /* List of types and structure classes of the current declaration. */
279: static tree current_declspecs;
280:
281: /* When defining an aggregate, this is the most recent one being defined. */
282: static tree current_aggr;
283:
284: /* Tell yyparse how to print a token's value, if yydebug is set. */
285:
286: #define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL)
287: extern void yyprint ();
288: extern tree combine_strings PROTO((tree));
289: %}
290:
291: %%
292: program: /* empty */
293: | extdefs
294: {
295: /* In case there were missing closebraces,
296: get us back to the global binding level. */
297: while (! global_bindings_p ())
298: poplevel (0, 0, 0);
299: finish_file ();
300: }
301: ;
302:
303: /* the reason for the strange actions in this rule
304: is so that notype_initdecls when reached via datadef
305: can find a valid list of type and sc specs in $0. */
306:
307: extdefs:
308: { $<ttype>$ = NULL_TREE; } lang_extdef
309: { $<ttype>$ = NULL_TREE; }
310: | extdefs lang_extdef
311: { $<ttype>$ = NULL_TREE; }
312: ;
313:
314: .hush_warning:
315: { have_extern_spec = 1;
316: used_extern_spec = 0;
317: $<ttype>$ = NULL_TREE; }
318: ;
319: .warning_ok:
320: { have_extern_spec = 0; }
321: ;
322:
323: asm_keyword:
324: ASM_KEYWORD
325: | GCC_ASM_KEYWORD
326: ;
327:
328: lang_extdef:
329: { if (pending_lang_change) do_pending_lang_change(); }
330: extdef
331: { if (! global_bindings_p () && ! pseudo_global_level_p())
332: pop_everything (); }
333: ;
334:
335: extdef:
336: fndef
337: { if (pending_inlines) do_pending_inlines (); }
338: | datadef
339: { if (pending_inlines) do_pending_inlines (); }
340: | template_def
341: { if (pending_inlines) do_pending_inlines (); }
342: | overloaddef
343: | asm_keyword '(' string ')' ';'
344: { if (TREE_CHAIN ($3)) $3 = combine_strings ($3);
345: assemble_asm ($3); }
346: | extern_lang_string '{' extdefs '}'
347: { pop_lang_context (); }
348: | extern_lang_string '{' '}'
349: { pop_lang_context (); }
350: | extern_lang_string .hush_warning fndef .warning_ok
351: { if (pending_inlines) do_pending_inlines ();
352: pop_lang_context (); }
353: | extern_lang_string .hush_warning datadef .warning_ok
354: { if (pending_inlines) do_pending_inlines ();
355: pop_lang_context (); }
356: ;
357:
358: extern_lang_string:
359: EXTERN_LANG_STRING
360: { push_lang_context ($1); }
361: ;
362:
363: template_header:
364: TEMPLATE '<'
365: { begin_template_parm_list (); }
366: template_parm_list '>'
367: { $$ = end_template_parm_list ($4); }
368: ;
369:
370: template_parm_list:
371: template_parm
372: { $$ = process_template_parm (NULL_TREE, $1); }
373: | template_parm_list ',' template_parm
374: { $$ = process_template_parm ($1, $3); }
375: ;
376:
377: template_type_parm:
378: aggr
379: {
380: $$ = build_tree_list ($1, NULL_TREE);
381: ttpa:
382: if (TREE_PURPOSE ($$) == signature_type_node)
383: sorry ("signature as template type parameter");
384: else if (TREE_PURPOSE ($$) != class_type_node)
385: pedwarn ("template type parameters must use the keyword `class'");
386: }
387: | aggr identifier
388: { $$ = build_tree_list ($1, $2); goto ttpa; }
389: ;
390:
391: template_parm:
392: /* The following rules introduce a new reduce/reduce
393: conflict on the ',' and '>' input tokens: they are valid
394: prefixes for a `structsp', which means they could match a
395: nameless parameter. See 14.6, paragraph 3.
396: By putting them before the `parm' rule, we get
397: their match before considering them nameless parameter
398: declarations. */
399: template_type_parm
400: { $$ = build_tree_list (NULL_TREE, $$); }
401: | template_type_parm '=' typespec
402: { $$ = build_tree_list ($3, $$); }
403: | full_parm
404: ;
405:
406: overloaddef:
407: OVERLOAD ov_identifiers ';'
408: { warning ("use of `overload' is an anachronism"); }
409: ;
410:
411: ov_identifiers: IDENTIFIER
412: { declare_overloaded ($1); }
413: | ov_identifiers ',' IDENTIFIER
414: { declare_overloaded ($3); }
415: ;
416:
417: template_def:
418: /* Class template declarations go here; they aren't normal class
419: declarations, because we can't process the bodies yet. */
420: template_header named_class_head_sans_basetype '{'
421: { yychar = '{'; goto template1; }
422: ';'
423: | template_header named_class_head_sans_basetype_defn '{'
424: { yychar = '{'; goto template1; }
425: ';'
426: | template_header named_class_head_sans_basetype ':'
427: { yychar = ':'; goto template1; }
428: ';'
429: | template_header named_class_head_sans_basetype_defn ':'
430: {
431: yychar = ':';
432: template1:
433: if (current_aggr == exception_type_node)
434: error ("template type must define an aggregate or union");
435: else if (current_aggr == signature_type_node)
436: sorry ("template type defining a signature");
437: /* Maybe pedantic warning for union?
438: How about an enum? :-) */
439: end_template_decl ($1, $2, current_aggr, 1);
440: reinit_parse_for_template (yychar, $1, $2);
441: yychar = YYEMPTY;
442: }
443: ';'
444: | template_header named_class_head_sans_basetype ';'
445: {
446: end_template_decl ($1, $2, current_aggr, 0);
447: /* declare $2 as template name with $1 parm list */
448: }
449: | template_header named_class_head_sans_basetype_defn ';'
450: {
451: end_template_decl ($1, $2, current_aggr, 0);
452: /* declare $2 as template name with $1 parm list */
453: }
454: | template_header /* notype_initdcl0 ';' */
455: notype_declarator maybe_raises maybeasm maybe_attribute
456: fn_tmpl_end
457: {
458: tree d;
459: int momentary;
460: int def = ($6 != ';');
461: momentary = suspend_momentary ();
462: d = start_decl ($<ttype>2, /*current_declspecs*/NULL_TREE, 0,
463: $3);
464: cplus_decl_attributes (d, $5);
465: finish_decl (d, NULL_TREE, $4, 0);
466: end_template_decl ($1, d, 0, def);
467: if (def)
468: reinit_parse_for_template ((int) $6, $1, d);
469: resume_momentary (momentary);
470: }
471: | template_header typed_declspecs /*initdcl0*/
472: declarator maybe_raises maybeasm maybe_attribute
473: fn_tmpl_end
474: {
475: tree d;
476: int momentary;
477: int def = ($7 != ';');
478:
479: current_declspecs = $2;
480: momentary = suspend_momentary ();
481: d = start_decl ($<ttype>3, current_declspecs,
482: 0, $<ttype>4);
483: cplus_decl_attributes (d, $6);
484: finish_decl (d, NULL_TREE, $5, 0);
485: end_template_decl ($1, d, 0, def);
486: if (def)
487: {
488: reinit_parse_for_template ((int) $7, $1, d);
489: yychar = YYEMPTY;
490: }
491: note_list_got_semicolon ($<ttype>2);
492: resume_momentary (momentary);
493: }
494: | template_header declmods notype_declarator fn_tmpl_end
495: {
496: int def = ($4 != ';');
497: tree d = start_decl ($<ttype>3, $<ttype>2, 0, NULL_TREE);
498: finish_decl (d, NULL_TREE, NULL_TREE, 0);
499: end_template_decl ($1, d, 0, def);
500: if (def)
501: reinit_parse_for_template ((int) $4, $1, d);
502: }
503: /* Try to recover from syntax errors in templates. */
504: | template_header error '}' { end_template_decl ($1, 0, 0, 0); }
505: | template_header error ';' { end_template_decl ($1, 0, 0, 0); }
506: ;
507:
508: fn_tmpl_end: '{' { $$ = '{'; }
509: | ':' { $$ = ':'; }
510: | ';' { $$ = ';'; }
511: | '=' { $$ = '='; }
512: | RETURN { $$ = RETURN; }
513: ;
514:
515: datadef:
516: nomods_initdecls ';'
517: {}
518: | declmods notype_initdecls ';'
519: {}
520: /* Normal case to make fast: "const i;". */
521: | declmods notype_declarator ';'
522: { tree d;
523: d = start_decl ($<ttype>2, $<ttype>$, 0, NULL_TREE);
524: finish_decl (d, NULL_TREE, NULL_TREE, 0);
525: }
526: | typed_declspecs initdecls ';'
527: {
528: note_list_got_semicolon ($<ttype>$);
529: }
530: /* Normal case: make this fast. */
531: | typed_declspecs declarator ';'
532: { tree d;
533: d = start_decl ($<ttype>2, $<ttype>$, 0, NULL_TREE);
534: finish_decl (d, NULL_TREE, NULL_TREE, 0);
535: note_list_got_semicolon ($<ttype>$);
536: }
537: | declmods ';'
538: { pedwarn ("empty declaration"); }
539: | explicit_instantiation ';'
540: | typed_declspecs ';'
541: {
542: tree t = $<ttype>$;
543: shadow_tag (t);
544: if (TREE_CODE (t) == TREE_LIST
545: && TREE_PURPOSE (t) == NULL_TREE)
546: {
547: t = TREE_VALUE (t);
548: if (IS_AGGR_TYPE (t)
549: && IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (t)))
550: {
551: if (CLASSTYPE_USE_TEMPLATE (t) == 0)
552: SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (t);
553: else if (CLASSTYPE_TEMPLATE_INSTANTIATION (t))
554: error ("override declaration for already-expanded template");
555: }
556: }
557: note_list_got_semicolon ($<ttype>$);
558: }
559: | error ';'
560: | error '}'
561: | ';'
562: ;
563:
564: fndef:
565: fn.def1 base_init compstmt_or_error
566: {
567: finish_function (lineno, 1);
568: /* finish_function performs these three statements:
569:
570: expand_end_bindings (getdecls (), 1, 0);
571: poplevel (1, 1, 0);
572:
573: expand_end_bindings (0, 0, 0);
574: poplevel (0, 0, 1);
575: */
576: if ($<ttype>$) process_next_inline ($<ttype>$);
577: }
578: | fn.def1 return_init base_init compstmt_or_error
579: {
580: finish_function (lineno, 1);
581: /* finish_function performs these three statements:
582:
583: expand_end_bindings (getdecls (), 1, 0);
584: poplevel (1, 1, 0);
585:
586: expand_end_bindings (0, 0, 0);
587: poplevel (0, 0, 1);
588: */
589: if ($<ttype>$) process_next_inline ($<ttype>$);
590: }
591: | fn.def1 nodecls compstmt_or_error
592: { finish_function (lineno, 0);
593: if ($<ttype>$) process_next_inline ($<ttype>$); }
594: | fn.def1 return_init ';' nodecls compstmt_or_error
595: { finish_function (lineno, 0);
596: if ($<ttype>$) process_next_inline ($<ttype>$); }
597: | fn.def1 return_init nodecls compstmt_or_error
598: { finish_function (lineno, 0);
599: if ($<ttype>$) process_next_inline ($<ttype>$); }
600: | typed_declspecs declarator error
601: {}
602: | declmods notype_declarator error
603: {}
604: | notype_declarator error
605: {}
606: ;
607:
608: fn.def1:
609: typed_declspecs declarator maybe_raises
610: { if (! start_function ($$, $2, $3, 0))
611: YYERROR1;
612: reinit_parse_for_function ();
613: $$ = NULL_TREE; }
614: | declmods notype_declarator maybe_raises
615: { if (! start_function ($$, $2, $3, 0))
616: YYERROR1;
617: reinit_parse_for_function ();
618: $$ = NULL_TREE; }
619: | notype_declarator maybe_raises
620: { if (! start_function (NULL_TREE, $$, $2, 0))
621: YYERROR1;
622: reinit_parse_for_function ();
623: $$ = NULL_TREE; }
624: | PRE_PARSED_FUNCTION_DECL
625: { start_function (NULL_TREE, TREE_VALUE ($$), NULL_TREE, 1);
626: reinit_parse_for_function (); }
627: ;
628:
629: /* more C++ complexity. See component_decl for a comment on the
630: reduce/reduce conflict introduced by these rules. */
631: fn.def2:
632: typed_declspecs '(' parmlist ')' type_quals maybe_raises
633: {
634: $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1), $3, $5);
635: $$ = start_method (TREE_CHAIN ($1), $$, $6);
636: rest_of_mdef:
637: if (! $$)
638: YYERROR1;
639: if (yychar == YYEMPTY)
640: yychar = YYLEX;
641: reinit_parse_for_method (yychar, $$); }
642: | typed_declspecs LEFT_RIGHT type_quals maybe_raises
643: {
644: $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1),
645: empty_parms (), $3);
646: $$ = start_method (TREE_CHAIN ($1), $$, $4);
647: goto rest_of_mdef;
648: }
649: | typed_declspecs declarator maybe_raises
650: { $$ = start_method ($$, $2, $3); goto rest_of_mdef; }
651: | declmods notype_declarator maybe_raises
652: { $$ = start_method ($$, $2, $3); goto rest_of_mdef; }
653: | notype_declarator maybe_raises
654: { $$ = start_method (NULL_TREE, $$, $2); goto rest_of_mdef; }
655: ;
656:
657: return_id: RETURN IDENTIFIER
658: {
659: if (! current_function_parms_stored)
660: store_parm_decls ();
661: $$ = $2;
662: }
663: ;
664:
665: return_init: return_id
666: { store_return_init ($<ttype>$, NULL_TREE); }
667: | return_id '=' init
668: { store_return_init ($<ttype>$, $3); }
669: | return_id '(' nonnull_exprlist ')'
670: { store_return_init ($<ttype>$, $3); }
671: | return_id LEFT_RIGHT
672: { store_return_init ($<ttype>$, NULL_TREE); }
673: ;
674:
675: base_init:
676: ':' .set_base_init member_init_list
677: {
678: if ($3 == 0)
679: error ("no base initializers given following ':'");
680: setup_vtbl_ptr ();
681: /* Always keep the BLOCK node associated with the outermost
682: pair of curley braces of a function. These are needed
683: for correct operation of dwarfout.c. */
684: keep_next_level ();
685: }
686: ;
687:
688: .set_base_init:
689: /* empty */
690: {
691: if (! current_function_parms_stored)
692: store_parm_decls ();
693:
694: /* Flag that we are processing base and member initializers. */
695: current_vtable_decl = error_mark_node;
696:
697: if (DECL_CONSTRUCTOR_P (current_function_decl))
698: {
699: /* Make a contour for the initializer list. */
700: pushlevel (0);
701: clear_last_expr ();
702: expand_start_bindings (0);
703: }
704: else if (current_class_type == NULL_TREE)
705: error ("base initializers not allowed for non-member functions");
706: else if (! DECL_CONSTRUCTOR_P (current_function_decl))
707: error ("only constructors take base initializers");
708: }
709: ;
710:
711: member_init_list:
712: /* empty */
713: { $$ = 0; }
714: | member_init
715: { $$ = 1; }
716: | member_init_list ',' member_init
717: | member_init_list error
718: ;
719:
720: member_init: '(' nonnull_exprlist ')'
721: {
722: if (current_class_name && !flag_traditional)
723: pedwarn ("anachronistic old style base class initializer");
724: expand_member_init (C_C_D, NULL_TREE, $2);
725: }
726: | LEFT_RIGHT
727: {
728: if (current_class_name && !flag_traditional)
729: pedwarn ("anachronistic old style base class initializer");
730: expand_member_init (C_C_D, NULL_TREE, void_type_node);
731: }
732: | notype_identifier '(' nonnull_exprlist ')'
733: { expand_member_init (C_C_D, $<ttype>$, $3); }
734: | notype_identifier LEFT_RIGHT
735: { expand_member_init (C_C_D, $<ttype>$, void_type_node); }
736: | complete_type_name '(' nonnull_exprlist ')'
737: { expand_member_init (C_C_D, $<ttype>$, $3); }
738: | complete_type_name LEFT_RIGHT
739: { expand_member_init (C_C_D, $<ttype>$, void_type_node); }
740: /* GNU extension */
741: | notype_qualified_id '(' nonnull_exprlist ')'
742: {
743: do_member_init (OP0 ($1), OP1 ($1), $3);
744: }
745: | notype_qualified_id LEFT_RIGHT
746: {
747: do_member_init (OP0 ($1), OP1 ($1), void_type_node);
748: }
749: ;
750:
751: identifier:
752: IDENTIFIER
753: | TYPENAME
754: | PTYPENAME
755: ;
756:
757: notype_identifier:
758: IDENTIFIER
759: | PTYPENAME %prec EMPTY
760: ;
761:
762: identifier_defn:
763: IDENTIFIER_DEFN
764: | TYPENAME_DEFN
765: | PTYPENAME_DEFN
766: ;
767:
768: explicit_instantiation:
769: TEMPLATE specialization template_instantiation
770: { do_type_instantiation ($3 ? $3 : $2, NULL_TREE); }
771: | TEMPLATE typed_declspecs declarator
772: { do_function_instantiation ($2, $3, NULL_TREE); }
773: | SCSPEC TEMPLATE specialization template_instantiation
774: { do_type_instantiation ($4 ? $4 : $3, $1); }
775: | SCSPEC TEMPLATE typed_declspecs declarator
776: { do_function_instantiation ($3, $4, $1); }
777: ;
778:
779: template_type:
780: template_type_name tmpl.2 template_instantiation
781: { if ($3) $$ = $3; }
782: ;
783:
784: template_type_name:
785: PTYPENAME '<' template_arg_list '>'
786: { $$ = lookup_template_class ($$, $3, NULL_TREE); }
787: | PTYPENAME '<' '>'
788: { $$ = lookup_template_class ($$, NULL_TREE, NULL_TREE); }
789: | TYPENAME '<' template_arg_list '>'
790: { $$ = lookup_template_class ($$, $3, NULL_TREE); }
791: ;
792:
793: tmpl.2:
794: /* empty */ %prec EMPTY
795: { $$ = instantiate_class_template ($<ttype>0, 1); }
796: ;
797:
798: template_arg_list:
799: template_arg
800: { $$ = build_tree_list (NULL_TREE, $$); }
801: | template_arg_list ',' template_arg
802: { $$ = chainon ($$, build_tree_list (NULL_TREE, $3)); }
803: ;
804:
805: template_arg:
806: type_id
807: { $$ = groktypename ($$); }
808: | expr_no_commas %prec UNARY
809: ;
810:
811: template_instantiate_once:
812: PRE_PARSED_CLASS_DECL maybe_base_class_list
813: {
814: tree t, decl, tmpl;
815:
816: tmpl = TREE_PURPOSE (IDENTIFIER_TEMPLATE ($1));
817: t = xref_tag (DECL_TEMPLATE_INFO (tmpl)->aggr, $1, $2, 0);
818: set_current_level_tags_transparency (1);
819: my_friendly_assert (TREE_CODE (t) == RECORD_TYPE
820: || TREE_CODE (t) == UNION_TYPE, 257);
821: $<ttype>$ = t;
822:
823: /* Now, put a copy of the decl in global scope, to avoid
824: recursive expansion. */
825: decl = IDENTIFIER_LOCAL_VALUE ($1);
826: if (!decl)
827: decl = IDENTIFIER_CLASS_VALUE ($1);
828: /* Now, put a copy of the decl in global scope, to avoid
829: recursive expansion. */
830: if (decl)
831: {
832: /* Need to copy it to clear the chain pointer,
833: and need to get it into permanent storage. */
834: my_friendly_assert (TREE_CODE (decl) == TYPE_DECL, 258);
835: push_obstacks (&permanent_obstack, &permanent_obstack);
836: decl = copy_node (decl);
837: if (DECL_LANG_SPECIFIC (decl))
838: copy_lang_decl (decl);
839: pop_obstacks ();
840: pushdecl_top_level (decl);
841: }
842: /* Kludge; see instantiate_class_template. */
843: TYPE_BEING_DEFINED (t) = 0;
844: }
845: left_curly opt.component_decl_list '}'
846: {
847: tree t = finish_struct ($<ttype>3, $5, 0);
848:
849: pop_obstacks ();
850: end_template_instantiation ($1);
851:
852: /* Now go after the methods & class data. */
853: instantiate_member_templates ($1);
854:
855: pop_tinst_level();
856:
857: CLASSTYPE_GOT_SEMICOLON (t) = 1;
858: }
859: ;
860:
861: template_instantiation:
862: /* empty */
863: { $$ = NULL_TREE; }
864: | template_instantiate_once
865: { $$ = $1; }
866: ;
867:
868: template_instantiate_some:
869: /* empty */
870: { $$ = NULL_TREE; /* never used from here... */}
871: | template_instantiate_once template_instantiate_some
872: { $$ = $1; /*???*/ }
873: ;
874:
875: unop: '-'
876: { $$ = NEGATE_EXPR; }
877: | '+'
878: { $$ = CONVERT_EXPR; }
879: | PLUSPLUS
880: { $$ = PREINCREMENT_EXPR; }
881: | MINUSMINUS
882: { $$ = PREDECREMENT_EXPR; }
883: | '!'
884: { $$ = TRUTH_NOT_EXPR; }
885: ;
886:
887: expr: nontrivial_exprlist
888: { $$ = build_x_compound_expr ($$); }
889: | expr_no_commas
890: ;
891:
892: paren_expr_or_null:
893: LEFT_RIGHT
894: { error ("ANSI C++ forbids an empty condition for `%s'",
895: cond_stmt_keyword);
896: $$ = integer_zero_node; }
897: | '(' expr ')'
898: { $$ = build1 (CLEANUP_POINT_EXPR, bool_type_node,
899: bool_truthvalue_conversion ($2)); }
900: ;
901:
902: paren_cond_or_null:
903: LEFT_RIGHT
904: { error ("ANSI C++ forbids an empty condition for `%s'",
905: cond_stmt_keyword);
906: $$ = integer_zero_node; }
907: | '(' condition ')'
908: { $$ = build1 (CLEANUP_POINT_EXPR, bool_type_node,
909: bool_truthvalue_conversion ($2)); }
910: ;
911:
912: xcond:
913: /* empty */
914: { $$ = NULL_TREE; }
915: | condition
916: { $$ = build1 (CLEANUP_POINT_EXPR, bool_type_node,
917: bool_truthvalue_conversion ($$)); }
918: | error
919: { $$ = NULL_TREE; }
920: ;
921:
922: condition:
923: type_specifier_seq declarator maybe_raises maybeasm maybe_attribute '='
924: { {
925: tree d;
926: for (d = getdecls (); d; d = TREE_CHAIN (d))
927: if (TREE_CODE (d) == TYPE_DECL) {
928: tree s = TREE_TYPE (d);
929: if (TREE_CODE (s) == RECORD_TYPE)
930: cp_error ("definition of class `%T' in condition", s);
931: else if (TREE_CODE (s) == ENUMERAL_TYPE)
932: cp_error ("definition of enum `%T' in condition", s);
933: }
934: }
935: current_declspecs = $1;
936: $<itype>6 = suspend_momentary ();
937: $<ttype>$ = start_decl ($<ttype>2, current_declspecs, 1, $3);
938: cplus_decl_attributes ($<ttype>$, $5);
939: }
940: init
941: {
942: finish_decl ($<ttype>7, $8, $5, 0);
943: resume_momentary ($<itype>6);
944: $$ = $<ttype>7;
945: if (TREE_CODE (TREE_TYPE ($$)) == ARRAY_TYPE)
946: cp_error ("definition of array `%#D' in condition", $$);
947: }
948: | expr
949: ;
950:
951: already_scoped_stmt:
952: '{' '}'
953: { finish_stmt (); }
954: | '{' maybe_label_decls stmts '}'
955: { finish_stmt (); }
956: | '{' maybe_label_decls error '}'
957: { finish_stmt (); }
958: | simple_stmt
959: ;
960:
961:
962: nontrivial_exprlist:
963: expr_no_commas ',' expr_no_commas
964: { $$ = tree_cons (NULL_TREE, $$,
965: build_tree_list (NULL_TREE, $3)); }
966: | expr_no_commas ',' error
967: { $$ = tree_cons (NULL_TREE, $$,
968: build_tree_list (NULL_TREE, error_mark_node)); }
969: | nontrivial_exprlist ',' expr_no_commas
970: { chainon ($$, build_tree_list (NULL_TREE, $3)); }
971: | nontrivial_exprlist ',' error
972: { chainon ($$, build_tree_list (NULL_TREE, error_mark_node)); }
973: ;
974:
975: nonnull_exprlist:
976: expr_no_commas
977: { $$ = build_tree_list (NULL_TREE, $$); }
978: | nontrivial_exprlist
979: ;
980:
981: unary_expr:
982: primary %prec UNARY
983: {
984: #if 0
985: if (TREE_CODE ($$) == TYPE_EXPR)
986: $$ = build_component_type_expr (C_C_D, $$, NULL_TREE, 1);
987: #endif
988: }
989: /* __extension__ turns off -pedantic for following primary. */
990: | EXTENSION
991: { $<itype>1 = pedantic;
992: pedantic = 0; }
993: cast_expr %prec UNARY
994: { $$ = $3;
995: pedantic = $<itype>1; }
996: | '*' cast_expr %prec UNARY
997: { $$ = build_x_indirect_ref ($2, "unary *"); }
998: | '&' cast_expr %prec UNARY
999: { $$ = build_x_unary_op (ADDR_EXPR, $2); }
1000: | '~' cast_expr
1001: { $$ = build_x_unary_op (BIT_NOT_EXPR, $2); }
1002: | unop cast_expr %prec UNARY
1003: { $$ = build_x_unary_op ($1, $2);
1004: if ($1 == NEGATE_EXPR && TREE_CODE ($2) == INTEGER_CST)
1005: TREE_NEGATED_INT ($$) = 1;
1006: overflow_warning ($$);
1007: }
1008: /* Refer to the address of a label as a pointer. */
1009: | ANDAND identifier
1010: { tree label = lookup_label ($2);
1011: if (label == NULL_TREE)
1012: $$ = null_pointer_node;
1013: else
1014: {
1015: TREE_USED (label) = 1;
1016: $$ = build1 (ADDR_EXPR, ptr_type_node, label);
1017: TREE_CONSTANT ($$) = 1;
1018: }
1019: }
1020: | SIZEOF unary_expr %prec UNARY
1021: { if (TREE_CODE ($2) == COMPONENT_REF
1022: && DECL_BIT_FIELD (TREE_OPERAND ($2, 1)))
1023: error ("sizeof applied to a bit-field");
1024: /* ANSI says arrays and functions are converted inside comma.
1025: But we can't really convert them in build_compound_expr
1026: because that would break commas in lvalues.
1027: So do the conversion here if operand was a comma. */
1028: if (TREE_CODE ($2) == COMPOUND_EXPR
1029: && (TREE_CODE (TREE_TYPE ($2)) == ARRAY_TYPE
1030: || TREE_CODE (TREE_TYPE ($2)) == FUNCTION_TYPE))
1031: $2 = default_conversion ($2);
1032: else if (TREE_CODE ($2) == TREE_LIST)
1033: {
1034: tree t = TREE_VALUE ($2);
1035: if (t != NULL_TREE
1036: && TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
1037: pedwarn ("ANSI C++ forbids using sizeof() on a function");
1038: }
1039: $$ = c_sizeof (TREE_TYPE ($2)); }
1040: | SIZEOF '(' type_id ')' %prec HYPERUNARY
1041: { $$ = c_sizeof (groktypename ($3)); }
1042: | ALIGNOF unary_expr %prec UNARY
1043: { $$ = grok_alignof ($2); }
1044: | ALIGNOF '(' type_id ')' %prec HYPERUNARY
1045: { $$ = c_alignof (groktypename ($3)); }
1046:
1047: /* The %prec EMPTY's here are required by the = init initializer
1048: syntax extension; see below. */
1049: | new new_type_id %prec EMPTY
1050: { $$ = build_new (NULL_TREE, $2, NULL_TREE, $1); }
1051: | new new_type_id new_initializer
1052: { $$ = build_new (NULL_TREE, $2, $3, $1); }
1053: | new new_placement new_type_id %prec EMPTY
1054: { $$ = build_new ($2, $3, NULL_TREE, $1); }
1055: | new new_placement new_type_id new_initializer
1056: { $$ = build_new ($2, $3, $4, $1); }
1057: | new '(' type_id ')' %prec EMPTY
1058: { $$ = build_new (NULL_TREE, groktypename($3),
1059: NULL_TREE, $1); }
1060: | new '(' type_id ')' new_initializer
1061: { $$ = build_new (NULL_TREE, groktypename($3), $5, $1); }
1062: | new new_placement '(' type_id ')' %prec EMPTY
1063: { $$ = build_new ($2, groktypename($4), NULL_TREE, $1); }
1064: | new new_placement '(' type_id ')' new_initializer
1065: { $$ = build_new ($2, groktypename($4), $6, $1); }
1066:
1067: | delete cast_expr %prec UNARY
1068: { $$ = delete_sanity ($2, NULL_TREE, 0, $1); }
1069: | delete '[' ']' cast_expr %prec UNARY
1070: { $$ = delete_sanity ($4, NULL_TREE, 1, $1);
1071: if (yychar == YYEMPTY)
1072: yychar = YYLEX; }
1073: | delete '[' expr ']' cast_expr %prec UNARY
1074: { $$ = delete_sanity ($5, $3, 2, $1);
1075: if (yychar == YYEMPTY)
1076: yychar = YYLEX; }
1077: ;
1078:
1079: new_placement:
1080: '(' nonnull_exprlist ')'
1081: { $$ = $2; }
1082: | '{' nonnull_exprlist '}'
1083: {
1084: $$ = $2;
1085: pedwarn ("old style placement syntax, use () instead");
1086: }
1087: ;
1088:
1089: new_initializer:
1090: '(' nonnull_exprlist ')'
1091: { $$ = $2; }
1092: | LEFT_RIGHT
1093: { $$ = NULL_TREE; }
1094: | '(' typespec ')'
1095: {
1096: cp_error ("`%T' is not a valid expression", $2);
1097: $$ = error_mark_node;
1098: }
1099: /* GNU extension so people can use initializer lists. Note that
1100: this alters the meaning of `new int = 1', which was previously
1101: syntactically valid but semantically invalid. */
1102: | '=' init
1103: {
1104: if (flag_ansi)
1105: pedwarn ("ANSI C++ forbids initialization of new expression with `='");
1106: $$ = $2;
1107: }
1108: ;
1109:
1110: /* This is necessary to postpone reduction of `int ((int)(int)(int))'. */
1111: regcast_or_absdcl:
1112: '(' type_id ')' %prec EMPTY
1113: { $2 = tree_cons (NULL_TREE, $2, void_list_node);
1114: TREE_PARMLIST ($2) = 1;
1115: $$ = build_parse_node (CALL_EXPR, NULL_TREE, $2,
1116: NULL_TREE); }
1117: | regcast_or_absdcl '(' type_id ')' %prec EMPTY
1118: { $3 = tree_cons (NULL_TREE, $3, void_list_node);
1119: TREE_PARMLIST ($3) = 1;
1120: $$ = build_parse_node (CALL_EXPR, $$, $3, NULL_TREE); }
1121: ;
1122:
1123: cast_expr:
1124: sub_cast_expr
1125: | regcast_or_absdcl sub_cast_expr %prec UNARY
1126: { $$ = reparse_absdcl_as_casts ($$, $2); }
1127: | regcast_or_absdcl '{' initlist maybecomma '}' %prec UNARY
1128: {
1129: tree init = build_nt (CONSTRUCTOR, NULL_TREE,
1130: nreverse ($3));
1131: if (flag_ansi)
1132: pedwarn ("ANSI C++ forbids constructor-expressions");
1133: /* Indicate that this was a GNU C constructor expression. */
1134: TREE_HAS_CONSTRUCTOR (init) = 1;
1135:
1136: $$ = reparse_absdcl_as_casts ($$, init);
1137: }
1138: ;
1139:
1140: sub_cast_expr:
1141: unary_expr
1142: | HEADOF '(' expr ')'
1143: { $$ = build_headof ($3); }
1144: | CLASSOF '(' expr ')'
1145: { $$ = build_classof ($3); }
1146: | CLASSOF '(' TYPENAME ')'
1147: { if (is_aggr_typedef ($3, 1))
1148: {
1149: tree type = IDENTIFIER_TYPE_VALUE ($3);
1150: if (! IS_SIGNATURE(type))
1151: $$ = CLASSTYPE_DOSSIER (type);
1152: else
1153: {
1154: sorry ("signature name as argument of `classof'");
1155: $$ = error_mark_node;
1156: }
1157: }
1158: else
1159: $$ = error_mark_node;
1160: }
1161: ;
1162:
1163: expr_no_commas:
1164: cast_expr
1165: /* Handle general members. */
1166: | expr_no_commas POINTSAT_STAR expr_no_commas
1167: { $$ = build_x_binary_op (MEMBER_REF, $$, $3); }
1168: | expr_no_commas DOT_STAR expr_no_commas
1169: { $$ = build_m_component_ref ($$, $3); }
1170: | expr_no_commas '+' expr_no_commas
1171: { $$ = build_x_binary_op ($2, $$, $3); }
1172: | expr_no_commas '-' expr_no_commas
1173: { $$ = build_x_binary_op ($2, $$, $3); }
1174: | expr_no_commas '*' expr_no_commas
1175: { $$ = build_x_binary_op ($2, $$, $3); }
1176: | expr_no_commas '/' expr_no_commas
1177: { $$ = build_x_binary_op ($2, $$, $3); }
1178: | expr_no_commas '%' expr_no_commas
1179: { $$ = build_x_binary_op ($2, $$, $3); }
1180: | expr_no_commas LSHIFT expr_no_commas
1181: { $$ = build_x_binary_op ($2, $$, $3); }
1182: | expr_no_commas RSHIFT expr_no_commas
1183: { $$ = build_x_binary_op ($2, $$, $3); }
1184: | expr_no_commas ARITHCOMPARE expr_no_commas
1185: { $$ = build_x_binary_op ($2, $$, $3); }
1186: | expr_no_commas '<' expr_no_commas
1187: { $$ = build_x_binary_op (LT_EXPR, $$, $3); }
1188: | expr_no_commas '>' expr_no_commas
1189: { $$ = build_x_binary_op (GT_EXPR, $$, $3); }
1190: | expr_no_commas EQCOMPARE expr_no_commas
1191: { $$ = build_x_binary_op ($2, $$, $3); }
1192: | expr_no_commas MIN_MAX expr_no_commas
1193: { $$ = build_x_binary_op ($2, $$, $3); }
1194: | expr_no_commas '&' expr_no_commas
1195: { $$ = build_x_binary_op ($2, $$, $3); }
1196: | expr_no_commas '|' expr_no_commas
1197: { $$ = build_x_binary_op ($2, $$, $3); }
1198: | expr_no_commas '^' expr_no_commas
1199: { $$ = build_x_binary_op ($2, $$, $3); }
1200: | expr_no_commas ANDAND expr_no_commas
1201: { $$ = build_x_binary_op (TRUTH_ANDIF_EXPR, $$, $3); }
1202: | expr_no_commas OROR expr_no_commas
1203: { $$ = build_x_binary_op (TRUTH_ORIF_EXPR, $$, $3); }
1204: | expr_no_commas '?' xexpr ':' expr_no_commas
1205: { $$ = build_x_conditional_expr ($$, $3, $5); }
1206: | expr_no_commas '=' expr_no_commas
1207: { $$ = build_modify_expr ($$, NOP_EXPR, $3); }
1208: | expr_no_commas ASSIGN expr_no_commas
1209: { register tree rval;
1210: if ((rval = build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL, $$, $3,
1211: make_node ($2))))
1212: $$ = rval;
1213: else
1214: $$ = build_modify_expr ($$, $2, $3); }
1215: | THROW
1216: { $$ = build_throw (NULL_TREE); }
1217: | THROW expr_no_commas
1218: { $$ = build_throw ($2); }
1219: /* These extensions are not defined. The second arg to build_m_component_ref
1220: is old, build_m_component_ref now does an implicit
1221: build_indirect_ref (x, NULL_PTR) on the second argument.
1222: | object '&' expr_no_commas %prec UNARY
1223: { $$ = build_m_component_ref ($$, build_x_unary_op (ADDR_EXPR, $3)); }
1224: | object unop expr_no_commas %prec UNARY
1225: { $$ = build_m_component_ref ($$, build_x_unary_op ($2, $3)); }
1226: | object '(' type_id ')' expr_no_commas %prec UNARY
1227: { tree type = groktypename ($3);
1228: $$ = build_m_component_ref ($$, build_c_cast (type, $5)); }
1229: | object primary_no_id %prec UNARY
1230: { $$ = build_m_component_ref ($$, $2); }
1231: */
1232: ;
1233:
1234: notype_unqualified_id:
1235: '~' see_typename identifier
1236: { $$ = build_parse_node (BIT_NOT_EXPR, $3); }
1237: | operator_name
1238: | IDENTIFIER
1239: | PTYPENAME %prec EMPTY
1240: ;
1241:
1242: unqualified_id:
1243: notype_unqualified_id
1244: | TYPENAME
1245: ;
1246:
1247: expr_or_declarator:
1248: notype_unqualified_id
1249: | notype_qualified_id
1250: | '*' expr_or_declarator %prec UNARY
1251: { $$ = build_parse_node (INDIRECT_REF, $2); }
1252: | '&' expr_or_declarator %prec UNARY
1253: { $$ = build_parse_node (ADDR_EXPR, $2); }
1254: ;
1255:
1256: direct_notype_declarator:
1257: complex_direct_notype_declarator
1258: | notype_unqualified_id
1259: | notype_qualified_id
1260: { push_nested_class (TREE_TYPE (OP0 ($$)), 3);
1261: TREE_COMPLEXITY ($$) = current_class_depth; }
1262: ;
1263:
1264: primary:
1265: notype_unqualified_id
1266: {
1267: if (TREE_CODE ($$) == BIT_NOT_EXPR)
1268: $$ = build_x_unary_op (BIT_NOT_EXPR, TREE_OPERAND ($$, 0));
1269: else if (IDENTIFIER_OPNAME_P ($$))
1270: {
1271: tree op = $$;
1272: $$ = lookup_name (op, 0);
1273: if ($$ == NULL_TREE)
1274: {
1275: if (op != ansi_opname[ERROR_MARK])
1276: error ("operator %s not defined",
1277: operator_name_string (op));
1278: $$ = error_mark_node;
1279: }
1280: }
1281: else
1282: $$ = do_identifier ($$);
1283: }
1284: | CONSTANT
1285: | boolean.literal
1286: | string
1287: { $$ = combine_strings ($$); }
1288: | '(' expr ')'
1289: { $$ = $2; }
1290: | '(' error ')'
1291: { $$ = error_mark_node; }
1292: | '('
1293: { if (current_function_decl == 0)
1294: {
1295: error ("braced-group within expression allowed only inside a function");
1296: YYERROR;
1297: }
1298: keep_next_level ();
1299: $<ttype>$ = expand_start_stmt_expr (); }
1300: compstmt ')'
1301: { tree rtl_exp;
1302: if (flag_ansi)
1303: pedwarn ("ANSI C++ forbids braced-groups within expressions");
1304: rtl_exp = expand_end_stmt_expr ($<ttype>2);
1305: /* The statements have side effects, so the group does. */
1306: TREE_SIDE_EFFECTS (rtl_exp) = 1;
1307:
1308: if (TREE_CODE ($3) == BLOCK)
1309: {
1310: /* Make a BIND_EXPR for the BLOCK already made. */
1311: $$ = build (BIND_EXPR, TREE_TYPE (rtl_exp),
1312: NULL_TREE, rtl_exp, $3);
1313: /* Remove the block from the tree at this point.
1314: It gets put back at the proper place
1315: when the BIND_EXPR is expanded. */
1316: delete_block ($3);
1317: }
1318: else
1319: $$ = $3;
1320: }
1321: | primary '(' nonnull_exprlist ')'
1322: { /* [eichin:19911016.1902EST] */
1323: $<ttype>$ = build_x_function_call ($1, $3, current_class_decl);
1324: /* here we instantiate_class_template as needed... */
1325: do_pending_templates ();
1326: } template_instantiate_some {
1327: if (TREE_CODE ($<ttype>5) == CALL_EXPR
1328: && TREE_TYPE ($<ttype>5) != void_type_node)
1329: $$ = require_complete_type ($<ttype>5);
1330: else
1331: $$ = $<ttype>5;
1332: }
1333: | primary LEFT_RIGHT
1334: {
1335: $$ = build_x_function_call ($$, NULL_TREE, current_class_decl);
1336: if (TREE_CODE ($$) == CALL_EXPR
1337: && TREE_TYPE ($$) != void_type_node)
1338: $$ = require_complete_type ($$);
1339: }
1340: | primary '[' expr ']'
1341: { $$ = grok_array_decl ($$, $3); }
1342: | primary PLUSPLUS
1343: { /* If we get an OFFSET_REF, turn it into what it really
1344: means (e.g., a COMPONENT_REF). This way if we've got,
1345: say, a reference to a static member that's being operated
1346: on, we don't end up trying to find a member operator for
1347: the class it's in. */
1348: if (TREE_CODE ($$) == OFFSET_REF)
1349: $$ = resolve_offset_ref ($$);
1350: $$ = build_x_unary_op (POSTINCREMENT_EXPR, $$); }
1351: | primary MINUSMINUS
1352: { if (TREE_CODE ($$) == OFFSET_REF)
1353: $$ = resolve_offset_ref ($$);
1354: $$ = build_x_unary_op (POSTDECREMENT_EXPR, $$); }
1355: /* C++ extensions */
1356: | THIS
1357: { if (current_class_decl)
1358: {
1359: #ifdef WARNING_ABOUT_CCD
1360: TREE_USED (current_class_decl) = 1;
1361: #endif
1362: $$ = current_class_decl;
1363: }
1364: else if (current_function_decl
1365: && DECL_STATIC_FUNCTION_P (current_function_decl))
1366: {
1367: error ("`this' is unavailable for static member functions");
1368: $$ = error_mark_node;
1369: }
1370: else
1371: {
1372: if (current_function_decl)
1373: error ("invalid use of `this' in non-member function");
1374: else
1375: error ("invalid use of `this' at top level");
1376: $$ = error_mark_node;
1377: }
1378: }
1379: | TYPE_QUAL '(' nonnull_exprlist ')'
1380: {
1381: tree type;
1382: tree id = $$;
1383:
1384: /* This is a C cast in C++'s `functional' notation. */
1385: if ($3 == error_mark_node)
1386: {
1387: $$ = error_mark_node;
1388: break;
1389: }
1390: #if 0
1391: if ($3 == NULL_TREE)
1392: {
1393: error ("cannot cast null list to type `%s'",
1394: IDENTIFIER_POINTER (TYPE_NAME (id)));
1395: $$ = error_mark_node;
1396: break;
1397: }
1398: #endif
1399: #if 0
1400: /* type is not set! (mrs) */
1401: if (type == error_mark_node)
1402: $$ = error_mark_node;
1403: else
1404: #endif
1405: {
1406: if (id == ridpointers[(int) RID_CONST])
1407: type = build_type_variant (integer_type_node, 1, 0);
1408: else if (id == ridpointers[(int) RID_VOLATILE])
1409: type = build_type_variant (integer_type_node, 0, 1);
1410: #if 0
1411: /* should not be able to get here (mrs) */
1412: else if (id == ridpointers[(int) RID_FRIEND])
1413: {
1414: error ("cannot cast expression to `friend' type");
1415: $$ = error_mark_node;
1416: break;
1417: }
1418: #endif
1419: else my_friendly_abort (79);
1420: $$ = build_c_cast (type, build_compound_expr ($3));
1421: }
1422: }
1423: | functional_cast
1424: | DYNAMIC_CAST '<' type_id '>' '(' expr ')'
1425: { tree type = groktypename ($3);
1426: $$ = build_dynamic_cast (type, $6); }
1427: | STATIC_CAST '<' type_id '>' '(' expr ')'
1428: { tree type = groktypename ($3);
1429: $$ = build_static_cast (type, $6); }
1430: | REINTERPRET_CAST '<' type_id '>' '(' expr ')'
1431: { tree type = groktypename ($3);
1432: $$ = build_reinterpret_cast (type, $6); }
1433: | CONST_CAST '<' type_id '>' '(' expr ')'
1434: { tree type = groktypename ($3);
1435: $$ = build_const_cast (type, $6); }
1436: | TYPEID '(' expr ')'
1437: { $$ = build_typeid ($3); }
1438: | TYPEID '(' type_id ')'
1439: { tree type = groktypename ($3);
1440: $$ = get_typeid (type); }
1441: | global_scope IDENTIFIER
1442: {
1443: do_scoped_id:
1444: $$ = IDENTIFIER_GLOBAL_VALUE ($2);
1445: if (yychar == YYEMPTY)
1446: yychar = YYLEX;
1447: if (! $$)
1448: {
1449: if (yychar == '(' || yychar == LEFT_RIGHT)
1450: $$ = implicitly_declare ($2);
1451: else
1452: {
1453: if (IDENTIFIER_GLOBAL_VALUE ($2) != error_mark_node)
1454: error ("undeclared variable `%s' (first use here)",
1455: IDENTIFIER_POINTER ($2));
1456: $$ = error_mark_node;
1457: /* Prevent repeated error messages. */
1458: IDENTIFIER_GLOBAL_VALUE ($2) = error_mark_node;
1459: }
1460: }
1461: else
1462: {
1463: if (TREE_CODE ($$) == ADDR_EXPR)
1464: assemble_external (TREE_OPERAND ($$, 0));
1465: else
1466: assemble_external ($$);
1467: TREE_USED ($$) = 1;
1468: }
1469: if (TREE_CODE ($$) == CONST_DECL)
1470: {
1471: /* XXX CHS - should we set TREE_USED of the constant? */
1472: $$ = DECL_INITIAL ($$);
1473: /* This is to prevent an enum whose value is 0
1474: from being considered a null pointer constant. */
1475: $$ = build1 (NOP_EXPR, TREE_TYPE ($$), $$);
1476: TREE_CONSTANT ($$) = 1;
1477: }
1478:
1479: }
1480: | global_scope operator_name
1481: {
1482: got_scope = NULL_TREE;
1483: if (TREE_CODE ($2) == IDENTIFIER_NODE)
1484: goto do_scoped_id;
1485: $$ = $2;
1486: }
1487: | overqualified_id %prec HYPERUNARY
1488: { $$ = build_offset_ref (OP0 ($$), OP1 ($$)); }
1489: | overqualified_id '(' nonnull_exprlist ')'
1490: { $$ = build_member_call (OP0 ($$), OP1 ($$), $3); }
1491: | overqualified_id LEFT_RIGHT
1492: { $$ = build_member_call (OP0 ($$), OP1 ($$), NULL_TREE); }
1493: | object unqualified_id %prec UNARY
1494: { $$ = build_component_ref ($$, $2, NULL_TREE, 1); }
1495: | object qualified_id %prec UNARY
1496: { $$ = build_object_ref ($$, OP0 ($2), OP1 ($2)); }
1497: | object unqualified_id '(' nonnull_exprlist ')'
1498: {
1499: #if 0
1500: /* This is a future direction of this code, but because
1501: build_x_function_call cannot always undo what is done
1502: in build_component_ref entirely yet, we cannot do this. */
1503: $$ = build_x_function_call (build_component_ref ($$, $2, NULL_TREE, 1), $4, $$);
1504: if (TREE_CODE ($$) == CALL_EXPR
1505: && TREE_TYPE ($$) != void_type_node)
1506: $$ = require_complete_type ($$);
1507: #else
1508: $$ = build_method_call ($$, $2, $4, NULL_TREE,
1509: (LOOKUP_NORMAL|LOOKUP_AGGR));
1510: #endif
1511: }
1512: | object unqualified_id LEFT_RIGHT
1513: {
1514: #if 0
1515: /* This is a future direction of this code, but because
1516: build_x_function_call cannot always undo what is done
1517: in build_component_ref entirely yet, we cannot do this. */
1518: $$ = build_x_function_call (build_component_ref ($$, $2, NULL_TREE, 1), NULL_TREE, $$);
1519: if (TREE_CODE ($$) == CALL_EXPR
1520: && TREE_TYPE ($$) != void_type_node)
1521: $$ = require_complete_type ($$);
1522: #else
1523: $$ = build_method_call ($$, $2, NULL_TREE, NULL_TREE,
1524: (LOOKUP_NORMAL|LOOKUP_AGGR));
1525: #endif
1526: }
1527: | object qualified_id '(' nonnull_exprlist ')'
1528: {
1529: if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (OP0 ($2))))
1530: {
1531: warning ("signature name in scope resolution ignored");
1532: $$ = build_method_call ($$, OP1 ($2), $4, NULL_TREE,
1533: (LOOKUP_NORMAL|LOOKUP_AGGR));
1534: }
1535: else
1536: $$ = build_scoped_method_call ($$, OP0 ($2), OP1 ($2), $4);
1537: }
1538: | object qualified_id LEFT_RIGHT
1539: {
1540: if (IS_SIGNATURE (IDENTIFIER_TYPE_VALUE (OP0 ($2))))
1541: {
1542: warning ("signature name in scope resolution ignored");
1543: $$ = build_method_call ($$, OP1 ($2), NULL_TREE, NULL_TREE,
1544: (LOOKUP_NORMAL|LOOKUP_AGGR));
1545: }
1546: else
1547: $$ = build_scoped_method_call ($$, OP0 ($2), OP1 ($2), NULL_TREE);
1548: }
1549: /* p->int::~int() is valid -- 12.4 */
1550: | object '~' TYPESPEC LEFT_RIGHT
1551: {
1552: if (TREE_CODE (TREE_TYPE ($1))
1553: != TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($3))))
1554: cp_error ("`%E' is not of type `%T'", $1, $3);
1555: $$ = convert (void_type_node, $1);
1556: }
1557: | object TYPESPEC SCOPE '~' TYPESPEC LEFT_RIGHT
1558: {
1559: if ($2 != $5)
1560: cp_error ("destructor specifier `%T::~%T()' must have matching names", $2, $5);
1561: if (TREE_CODE (TREE_TYPE ($1))
1562: != TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE ($2))))
1563: cp_error ("`%E' is not of type `%T'", $1, $2);
1564: $$ = convert (void_type_node, $1);
1565: }
1566: ;
1567:
1568: /* Not needed for now.
1569:
1570: primary_no_id:
1571: '(' expr ')'
1572: { $$ = $2; }
1573: | '(' error ')'
1574: { $$ = error_mark_node; }
1575: | '('
1576: { if (current_function_decl == 0)
1577: {
1578: error ("braced-group within expression allowed only inside a function");
1579: YYERROR;
1580: }
1581: $<ttype>$ = expand_start_stmt_expr (); }
1582: compstmt ')'
1583: { if (flag_ansi)
1584: pedwarn ("ANSI C++ forbids braced-groups within expressions");
1585: $$ = expand_end_stmt_expr ($<ttype>2); }
1586: | primary_no_id '(' nonnull_exprlist ')'
1587: { $$ = build_x_function_call ($$, $3, current_class_decl); }
1588: | primary_no_id LEFT_RIGHT
1589: { $$ = build_x_function_call ($$, NULL_TREE, current_class_decl); }
1590: | primary_no_id '[' expr ']'
1591: { goto do_array; }
1592: | primary_no_id PLUSPLUS
1593: { $$ = build_x_unary_op (POSTINCREMENT_EXPR, $$); }
1594: | primary_no_id MINUSMINUS
1595: { $$ = build_x_unary_op (POSTDECREMENT_EXPR, $$); }
1596: | SCOPE IDENTIFIER
1597: { goto do_scoped_id; }
1598: | SCOPE operator_name
1599: { if (TREE_CODE ($2) == IDENTIFIER_NODE)
1600: goto do_scoped_id;
1601: goto do_scoped_operator;
1602: }
1603: ;
1604: */
1605:
1606: new: NEW
1607: { $$ = 0; }
1608: | global_scope NEW
1609: { got_scope = NULL_TREE; $$ = 1; }
1610: ;
1611:
1612: delete: DELETE
1613: { $$ = 0; }
1614: | global_scope delete
1615: { got_scope = NULL_TREE; $$ = 1; }
1616: ;
1617:
1618: boolean.literal:
1619: CXX_TRUE
1620: { $$ = true_node; }
1621: | CXX_FALSE
1622: { $$ = false_node; }
1623: ;
1624:
1625: /* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it. */
1626: string:
1627: STRING
1628: | string STRING
1629: { $$ = chainon ($$, $2); }
1630: ;
1631:
1632: nodecls:
1633: /* empty */
1634: {
1635: if (! current_function_parms_stored)
1636: store_parm_decls ();
1637: setup_vtbl_ptr ();
1638: /* Always keep the BLOCK node associated with the outermost
1639: pair of curley braces of a function. These are needed
1640: for correct operation of dwarfout.c. */
1641: keep_next_level ();
1642: }
1643: ;
1644:
1645: object: primary '.'
1646: | primary POINTSAT
1647: {
1648: $$ = build_x_arrow ($$);
1649: }
1650: ;
1651:
1652: decl:
1653: /* Normal case: make this fast. */
1654: typespec declarator ';'
1655: { tree d = get_decl_list ($1);
1656: int yes = suspend_momentary ();
1657: d = start_decl ($2, d, 0, NULL_TREE);
1658: finish_decl (d, NULL_TREE, NULL_TREE, 0);
1659: resume_momentary (yes);
1660: if (IS_AGGR_TYPE_CODE (TREE_CODE ($1)))
1661: note_got_semicolon ($1);
1662: }
1663: | typed_declspecs declarator ';'
1664: { tree d = $1;
1665: int yes = suspend_momentary ();
1666: d = start_decl ($2, d, 0, NULL_TREE);
1667: finish_decl (d, NULL_TREE, NULL_TREE, 0);
1668: resume_momentary (yes);
1669: note_list_got_semicolon ($1);
1670: }
1671: | typespec initdecls ';'
1672: {
1673: resume_momentary ($2);
1674: if (IS_AGGR_TYPE_CODE (TREE_CODE ($1)))
1675: note_got_semicolon ($1);
1676: }
1677: | typed_declspecs initdecls ';'
1678: {
1679: resume_momentary ($2);
1680: note_list_got_semicolon ($1);
1681: }
1682: | declmods notype_initdecls ';'
1683: { resume_momentary ($2); }
1684: | typed_declspecs ';'
1685: {
1686: shadow_tag ($1);
1687: note_list_got_semicolon ($1);
1688: }
1689: | declmods ';'
1690: { warning ("empty declaration"); }
1691: ;
1692:
1693: /* Any kind of declarator (thus, all declarators allowed
1694: after an explicit typespec). */
1695:
1696: declarator:
1697: after_type_declarator %prec EMPTY
1698: | notype_declarator %prec EMPTY
1699: ;
1700:
1701: /* This is necessary to postpone reduction of `int()()()()'. */
1702: fcast_or_absdcl:
1703: LEFT_RIGHT %prec EMPTY
1704: { $$ = build_parse_node (CALL_EXPR, NULL_TREE, empty_parms (),
1705: NULL_TREE); }
1706: | fcast_or_absdcl LEFT_RIGHT %prec EMPTY
1707: { $$ = build_parse_node (CALL_EXPR, $$, empty_parms (),
1708: NULL_TREE); }
1709: ;
1710:
1711: /* ANSI type-id (8.1) */
1712: type_id:
1713: typed_typespecs absdcl
1714: { $$ = build_decl_list ($$, $2); }
1715: | nonempty_type_quals absdcl
1716: { $$ = build_decl_list ($$, $2); }
1717: | typespec absdcl
1718: { $$ = build_decl_list (get_decl_list ($$), $2); }
1719: | typed_typespecs %prec EMPTY
1720: { $$ = build_decl_list ($$, NULL_TREE); }
1721: | nonempty_type_quals %prec EMPTY
1722: { $$ = build_decl_list ($$, NULL_TREE); }
1723: ;
1724:
1725: /* Declspecs which contain at least one type specifier or typedef name.
1726: (Just `const' or `volatile' is not enough.)
1727: A typedef'd name following these is taken as a name to be declared. */
1728:
1729: typed_declspecs:
1730: typed_typespecs %prec EMPTY
1731: | typed_declspecs1
1732:
1733: typed_declspecs1:
1734: declmods typespec
1735: { $$ = decl_tree_cons (NULL_TREE, $2, $$); }
1736: | typespec reserved_declspecs %prec HYPERUNARY
1737: { $$ = decl_tree_cons (NULL_TREE, $$, $2); }
1738: | declmods typespec reserved_declspecs
1739: { $$ = decl_tree_cons (NULL_TREE, $2, chainon ($3, $$)); }
1740: | declmods typespec reserved_typespecquals
1741: { $$ = decl_tree_cons (NULL_TREE, $2, chainon ($3, $$)); }
1742: | declmods typespec reserved_typespecquals reserved_declspecs
1743: { $$ = decl_tree_cons (NULL_TREE, $2,
1744: chainon ($3, chainon ($4, $$))); }
1745: ;
1746:
1747: reserved_declspecs:
1748: SCSPEC
1749: { if (extra_warnings)
1750: warning ("`%s' is not at beginning of declaration",
1751: IDENTIFIER_POINTER ($$));
1752: $$ = build_decl_list (NULL_TREE, $$); }
1753: | reserved_declspecs typespecqual_reserved
1754: { $$ = decl_tree_cons (NULL_TREE, $2, $$); }
1755: | reserved_declspecs SCSPEC
1756: { if (extra_warnings)
1757: warning ("`%s' is not at beginning of declaration",
1758: IDENTIFIER_POINTER ($2));
1759: $$ = decl_tree_cons (NULL_TREE, $2, $$); }
1760: ;
1761:
1762: /* List of just storage classes and type modifiers.
1763: A declaration can start with just this, but then it cannot be used
1764: to redeclare a typedef-name. */
1765:
1766: declmods:
1767: nonempty_type_quals %prec EMPTY
1768: { TREE_STATIC ($$) = 1; }
1769: | SCSPEC
1770: { $$ = IDENTIFIER_AS_LIST ($$); }
1771: | declmods TYPE_QUAL
1772: { $$ = decl_tree_cons (NULL_TREE, $2, $$);
1773: TREE_STATIC ($$) = 1; }
1774: | declmods SCSPEC
1775: { if (extra_warnings && TREE_STATIC ($$))
1776: warning ("`%s' is not at beginning of declaration",
1777: IDENTIFIER_POINTER ($2));
1778: $$ = decl_tree_cons (NULL_TREE, $2, $$);
1779: TREE_STATIC ($$) = TREE_STATIC ($1); }
1780: ;
1781:
1782:
1783: /* Used instead of declspecs where storage classes are not allowed
1784: (that is, for typenames and structure components).
1785:
1786: C++ can takes storage classes for structure components.
1787: Don't accept a typedef-name if anything but a modifier precedes it. */
1788:
1789: typed_typespecs:
1790: typespec %prec EMPTY
1791: { $$ = get_decl_list ($$); }
1792: | nonempty_type_quals typespec
1793: { $$ = decl_tree_cons (NULL_TREE, $2, $$); }
1794: | typespec reserved_typespecquals
1795: { $$ = decl_tree_cons (NULL_TREE, $$, $2); }
1796: | nonempty_type_quals typespec reserved_typespecquals
1797: { $$ = decl_tree_cons (NULL_TREE, $2, chainon ($3, $$)); }
1798: ;
1799:
1800: reserved_typespecquals:
1801: typespecqual_reserved
1802: { $$ = build_decl_list (NULL_TREE, $$); }
1803: | reserved_typespecquals typespecqual_reserved
1804: { $$ = decl_tree_cons (NULL_TREE, $2, $$); }
1805: ;
1806:
1807: /* A typespec (but not a type qualifier).
1808: Once we have seen one of these in a declaration,
1809: if a typedef name appears then it is being redeclared. */
1810:
1811: typespec: structsp
1812: | TYPESPEC %prec EMPTY
1813: | complete_type_name
1814: | TYPEOF '(' expr ')'
1815: { $$ = TREE_TYPE ($3);
1816: if (flag_ansi)
1817: pedwarn ("ANSI C++ forbids `typeof'"); }
1818: | TYPEOF '(' type_id ')'
1819: { $$ = groktypename ($3);
1820: if (flag_ansi)
1821: pedwarn ("ANSI C++ forbids `typeof'"); }
1822: | SIGOF '(' expr ')'
1823: { tree type = TREE_TYPE ($3);
1824:
1825: if (IS_AGGR_TYPE (type))
1826: {
1827: sorry ("sigof type specifier");
1828: $$ = type;
1829: }
1830: else
1831: {
1832: error ("`sigof' applied to non-aggregate expression");
1833: $$ = error_mark_node;
1834: }
1835: }
1836: | SIGOF '(' type_id ')'
1837: { tree type = groktypename ($3);
1838:
1839: if (IS_AGGR_TYPE (type))
1840: {
1841: sorry ("sigof type specifier");
1842: $$ = type;
1843: }
1844: else
1845: {
1846: error("`sigof' applied to non-aggregate type");
1847: $$ = error_mark_node;
1848: }
1849: }
1850: ;
1851:
1852: /* A typespec that is a reserved word, or a type qualifier. */
1853:
1854: typespecqual_reserved: TYPESPEC
1855: | TYPE_QUAL
1856: | structsp
1857: ;
1858:
1859: initdecls:
1860: initdcl0
1861: | initdecls ',' initdcl
1862: ;
1863:
1864: notype_initdecls:
1865: notype_initdcl0
1866: | notype_initdecls ',' initdcl
1867: ;
1868:
1869: nomods_initdecls:
1870: nomods_initdcl0
1871: | nomods_initdecls ',' initdcl
1872: ;
1873:
1874: maybeasm:
1875: /* empty */
1876: { $$ = NULL_TREE; }
1877: | asm_keyword '(' string ')'
1878: { if (TREE_CHAIN ($3)) $3 = combine_strings ($3); $$ = $3; }
1879: ;
1880:
1881: initdcl0:
1882: declarator maybe_raises maybeasm maybe_attribute '='
1883: { current_declspecs = $<ttype>0;
1884: if (TREE_CODE (current_declspecs) != TREE_LIST)
1885: current_declspecs = get_decl_list (current_declspecs);
1886: if (have_extern_spec && !used_extern_spec)
1887: {
1888: current_declspecs = decl_tree_cons
1889: (NULL_TREE, get_identifier ("extern"),
1890: current_declspecs);
1891: used_extern_spec = 1;
1892: }
1893: $<itype>5 = suspend_momentary ();
1894: $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1, $2);
1895: cplus_decl_attributes ($<ttype>$, $4); }
1896: init
1897: /* Note how the declaration of the variable is in effect while its init is parsed! */
1898: { finish_decl ($<ttype>6, $7, $3, 0);
1899: $$ = $<itype>5; }
1900: | declarator maybe_raises maybeasm maybe_attribute
1901: { tree d;
1902: current_declspecs = $<ttype>0;
1903: if (TREE_CODE (current_declspecs) != TREE_LIST)
1904: current_declspecs = get_decl_list (current_declspecs);
1905: if (have_extern_spec && !used_extern_spec)
1906: {
1907: current_declspecs = decl_tree_cons
1908: (NULL_TREE, get_identifier ("extern"),
1909: current_declspecs);
1910: used_extern_spec = 1;
1911: }
1912: $$ = suspend_momentary ();
1913: d = start_decl ($<ttype>1, current_declspecs, 0, $2);
1914: cplus_decl_attributes (d, $4);
1915: finish_decl (d, NULL_TREE, $3, 0); }
1916: ;
1917:
1918: initdcl:
1919: declarator maybe_raises maybeasm maybe_attribute '='
1920: { $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1, $2);
1921: cplus_decl_attributes ($<ttype>$, $4); }
1922: init
1923: /* Note how the declaration of the variable is in effect while its init is parsed! */
1924: { finish_decl ($<ttype>6, $7, $3, 0); }
1925: | declarator maybe_raises maybeasm maybe_attribute
1926: { $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 0, $2);
1927: cplus_decl_attributes ($<ttype>$, $4);
1928: finish_decl ($<ttype>$, NULL_TREE, $3, 0); }
1929: ;
1930:
1931: notype_initdcl0:
1932: notype_declarator maybe_raises maybeasm maybe_attribute '='
1933: { current_declspecs = $<ttype>0;
1934: $<itype>5 = suspend_momentary ();
1935: $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1, $2);
1936: cplus_decl_attributes ($<ttype>$, $4); }
1937: init
1938: /* Note how the declaration of the variable is in effect while its init is parsed! */
1939: { finish_decl ($<ttype>6, $7, $3, 0);
1940: $$ = $<itype>5; }
1941: | notype_declarator maybe_raises maybeasm maybe_attribute
1942: { tree d;
1943: current_declspecs = $<ttype>0;
1944: $$ = suspend_momentary ();
1945: d = start_decl ($<ttype>1, current_declspecs, 0, $2);
1946: cplus_decl_attributes (d, $4);
1947: finish_decl (d, NULL_TREE, $3, 0); }
1948: ;
1949:
1950: nomods_initdcl0:
1951: notype_declarator maybe_raises maybeasm maybe_attribute '='
1952: { current_declspecs = NULL_TREE;
1953: $<itype>5 = suspend_momentary ();
1954: $<ttype>$ = start_decl ($1, current_declspecs, 1, $2);
1955: cplus_decl_attributes ($<ttype>$, $4); }
1956: init
1957: /* Note how the declaration of the variable is in effect while its init is parsed! */
1958: { finish_decl ($<ttype>6, $7, $3, 0);
1959: $$ = $<itype>5; }
1960: | notype_declarator maybe_raises maybeasm maybe_attribute
1961: { tree d;
1962: current_declspecs = NULL_TREE;
1963: $$ = suspend_momentary ();
1964: d = start_decl ($1, current_declspecs, 0, $2);
1965: cplus_decl_attributes (d, $4);
1966: finish_decl (d, NULL_TREE, $3, 0); }
1967: ;
1968:
1969: /* the * rules are dummies to accept the Apollo extended syntax
1970: so that the header files compile. */
1971: maybe_attribute:
1972: /* empty */
1973: { $$ = NULL_TREE; }
1974: | attributes
1975: { $$ = $1; }
1976: ;
1977:
1978: attributes:
1979: attribute
1980: { $$ = $1; }
1981: | attributes attribute
1982: { $$ = chainon ($1, $2); }
1983: ;
1984:
1985: attribute:
1986: ATTRIBUTE '(' '(' attribute_list ')' ')'
1987: { $$ = $4; }
1988: ;
1989:
1990: attribute_list:
1991: attrib
1992: { $$ = build_tree_list (NULL_TREE, $1); }
1993: | attribute_list ',' attrib
1994: { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
1995: ;
1996:
1997: attrib:
1998: /* empty */
1999: { $$ = NULL_TREE; }
2000: | any_word
2001: { $$ = $1; }
2002: | any_word '(' IDENTIFIER ')'
2003: { $$ = tree_cons ($1, NULL_TREE, build_tree_list (NULL_TREE, $3)); }
2004: | any_word '(' IDENTIFIER ',' nonnull_exprlist ')'
2005: { $$ = tree_cons ($1, NULL_TREE, tree_cons (NULL_TREE, $3, $5)); }
2006: | any_word '(' nonnull_exprlist ')'
2007: { $$ = tree_cons ($1, NULL_TREE, $3); }
2008: ;
2009:
2010: /* This still leaves out most reserved keywords,
2011: shouldn't we include them? */
2012:
2013: any_word:
2014: identifier
2015: | SCSPEC
2016: | TYPESPEC
2017: | TYPE_QUAL
2018: ;
2019:
2020: /* A nonempty list of identifiers, including typenames. */
2021: identifiers_or_typenames:
2022: identifier
2023: { $$ = build_tree_list (NULL_TREE, $1); }
2024: | identifiers_or_typenames ',' identifier
2025: { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
2026: ;
2027:
2028: init:
2029: expr_no_commas %prec '='
2030: | '{' '}'
2031: { $$ = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE);
2032: TREE_HAS_CONSTRUCTOR ($$) = 1; }
2033: | '{' initlist '}'
2034: { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2));
2035: TREE_HAS_CONSTRUCTOR ($$) = 1; }
2036: | '{' initlist ',' '}'
2037: { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2));
2038: TREE_HAS_CONSTRUCTOR ($$) = 1; }
2039: | error
2040: { $$ = NULL_TREE; }
2041: ;
2042:
2043: /* This chain is built in reverse order,
2044: and put in forward order where initlist is used. */
2045: initlist:
2046: init
2047: { $$ = build_tree_list (NULL_TREE, $$); }
2048: | initlist ',' init
2049: { $$ = tree_cons (NULL_TREE, $3, $$); }
2050: /* These are for labeled elements. */
2051: | '[' expr_no_commas ']' init
2052: { $$ = build_tree_list ($2, $4); }
2053: | initlist ',' CASE expr_no_commas ':' init
2054: { $$ = tree_cons ($4, $6, $$); }
2055: | identifier ':' init
2056: { $$ = build_tree_list ($$, $3); }
2057: | initlist ',' identifier ':' init
2058: { $$ = tree_cons ($3, $5, $$); }
2059: ;
2060:
2061: structsp:
2062: ENUM identifier '{'
2063: { $<itype>3 = suspend_momentary ();
2064: $$ = start_enum ($2); }
2065: enumlist maybecomma_warn '}'
2066: { $$ = finish_enum ($<ttype>4, $5);
2067: resume_momentary ((int) $<itype>3);
2068: check_for_missing_semicolon ($<ttype>4); }
2069: | ENUM identifier '{' '}'
2070: { $$ = finish_enum (start_enum ($2), NULL_TREE);
2071: check_for_missing_semicolon ($$); }
2072: | ENUM '{'
2073: { $<itype>2 = suspend_momentary ();
2074: $$ = start_enum (make_anon_name ()); }
2075: enumlist maybecomma_warn '}'
2076: { $$ = finish_enum ($<ttype>3, $4);
2077: resume_momentary ((int) $<itype>1);
2078: check_for_missing_semicolon ($<ttype>3); }
2079: | ENUM '{' '}'
2080: { $$ = finish_enum (start_enum (make_anon_name()), NULL_TREE);
2081: check_for_missing_semicolon ($$); }
2082: | ENUM identifier
2083: { $$ = xref_tag (enum_type_node, $2, NULL_TREE, 0); }
2084: | ENUM complex_type_name
2085: { $$ = xref_tag (enum_type_node, $2, NULL_TREE, 0); }
2086:
2087: /* C++ extensions, merged with C to avoid shift/reduce conflicts */
2088: | class_head left_curly opt.component_decl_list '}'
2089: {
2090: int semi;
2091: tree id;
2092:
2093: #if 0
2094: /* Need to rework class nesting in the
2095: presence of nested classes, etc. */
2096: shadow_tag (CLASSTYPE_AS_LIST ($$)); */
2097: #endif
2098: if (yychar == YYEMPTY)
2099: yychar = YYLEX;
2100: semi = yychar == ';';
2101: /* finish_struct nukes this anyway; if
2102: finish_exception does too, then it can go. */
2103: if (semi)
2104: note_got_semicolon ($$);
2105:
2106: if (TREE_CODE ($$) == ENUMERAL_TYPE)
2107: /* $$ = $1 from default rule. */;
2108: else if (CLASSTYPE_DECLARED_EXCEPTION ($$))
2109: {
2110: }
2111: else
2112: {
2113: $$ = finish_struct ($$, $3, semi);
2114: if (semi) note_got_semicolon ($$);
2115: }
2116:
2117: pop_obstacks ();
2118:
2119: id = TYPE_IDENTIFIER ($$);
2120: if (id && IDENTIFIER_TEMPLATE (id))
2121: {
2122: tree decl;
2123:
2124: /* I don't know if the copying of this TYPE_DECL is
2125: * really needed. However, it's such a small per-
2126: * formance penalty that the extra safety is a bargain.
2127: * - [email protected]
2128: */
2129: push_obstacks (&permanent_obstack, &permanent_obstack);
2130: decl = copy_node (lookup_name (id, 0));
2131: if (DECL_LANG_SPECIFIC (decl))
2132: copy_lang_decl (decl);
2133: pop_obstacks ();
2134: undo_template_name_overload (id, 0);
2135: pushdecl_top_level (decl);
2136: }
2137: if (! semi)
2138: check_for_missing_semicolon ($$); }
2139: | class_head %prec EMPTY
2140: {
2141: #if 0
2142: /* It's no longer clear what the following error is supposed to
2143: accomplish. If it turns out to be needed, add a comment why. */
2144: if (TYPE_BINFO_BASETYPES ($$) && !TYPE_SIZE ($$))
2145: {
2146: error ("incomplete definition of type `%s'",
2147: TYPE_NAME_STRING ($$));
2148: $$ = error_mark_node;
2149: }
2150: #endif
2151: }
2152: ;
2153:
2154: maybecomma:
2155: /* empty */
2156: | ','
2157: ;
2158:
2159: maybecomma_warn:
2160: /* empty */
2161: | ','
2162: { if (pedantic) pedwarn ("comma at end of enumerator list"); }
2163: ;
2164:
2165: aggr: AGGR
2166: | aggr SCSPEC
2167: { error ("storage class specifier `%s' not allowed after struct or class", IDENTIFIER_POINTER ($2)); }
2168: | aggr TYPESPEC
2169: { error ("type specifier `%s' not allowed after struct or class", IDENTIFIER_POINTER ($2)); }
2170: | aggr TYPE_QUAL
2171: { error ("type qualifier `%s' not allowed after struct or class", IDENTIFIER_POINTER ($2)); }
2172: | aggr AGGR
2173: { error ("no body nor ';' separates two class, struct or union declarations"); }
2174: ;
2175:
2176: specialization:
2177: aggr template_type_name ';'
2178: {
2179: yyungetc (';', 1); current_aggr = $$; $$ = $2;
2180: if ($<ttype>0 == ridpointers[(int) RID_TEMPLATE])
2181: instantiate_class_template ($$, 2);
2182: }
2183: ;
2184:
2185: named_class_head_sans_basetype:
2186: aggr identifier
2187: { current_aggr = $$; $$ = $2; }
2188: | aggr complex_type_name
2189: { current_aggr = $$; $$ = $2; }
2190: | aggr template_type %prec EMPTY
2191: { current_aggr = $$; $$ = $2; }
2192: | aggr template_type_name '{'
2193: { yyungetc ('{', 1);
2194: aggr2:
2195: current_aggr = $$;
2196: $$ = $2;
2197: overload_template_name ($$, 0); }
2198: | aggr template_type_name ':'
2199: { yyungetc (':', 1); goto aggr2; }
2200: | specialization
2201: ;
2202:
2203: named_class_head_sans_basetype_defn:
2204: aggr identifier_defn %prec EMPTY
2205: { current_aggr = $$; $$ = $2; }
2206: ;
2207:
2208: do_xref: /* empty */ %prec EMPTY
2209: { $<ttype>$ = xref_tag (current_aggr, $<ttype>0, NULL_TREE, 1); }
2210:
2211: do_xref_defn: /* empty */ %prec EMPTY
2212: { $<ttype>$ = xref_defn_tag (current_aggr, $<ttype>0, NULL_TREE); }
2213:
2214: named_class_head:
2215: named_class_head_sans_basetype do_xref
2216: maybe_base_class_list %prec EMPTY
2217: {
2218: if ($3)
2219: $$ = xref_tag (current_aggr, $1, $3, 1);
2220: else
2221: $$ = $<ttype>2;
2222: }
2223: |
2224: named_class_head_sans_basetype_defn do_xref_defn
2225: maybe_base_class_list %prec EMPTY
2226: {
2227: if ($3)
2228: $$ = xref_defn_tag (current_aggr, $1, $3);
2229: else
2230: $$ = $<ttype>2;
2231: }
2232: ;
2233:
2234: unnamed_class_head: aggr '{'
2235: { $$ = xref_tag ($$, make_anon_name (), NULL_TREE, 0);
2236: yyungetc ('{', 1); }
2237: ;
2238:
2239: class_head: unnamed_class_head | named_class_head ;
2240:
2241: maybe_base_class_list:
2242: %prec EMPTY /* empty */
2243: { $$ = NULL_TREE; }
2244: | ':' %prec EMPTY
2245: { yyungetc(':', 1); $$ = NULL_TREE; }
2246: | ':' base_class_list %prec EMPTY
2247: { $$ = $2; }
2248: ;
2249:
2250: base_class_list:
2251: base_class
2252: | base_class_list ',' base_class
2253: { $$ = chainon ($$, $3); }
2254: ;
2255:
2256: base_class:
2257: base_class.1
2258: {
2259: tree type;
2260: do_base_class1:
2261: type = IDENTIFIER_TYPE_VALUE ($$);
2262: if (! is_aggr_typedef ($$, 1))
2263: $$ = NULL_TREE;
2264: else if (current_aggr == signature_type_node
2265: && (! type) && (! IS_SIGNATURE (type)))
2266: {
2267: error ("class name not allowed as base signature");
2268: $$ = NULL_TREE;
2269: }
2270: else if (current_aggr == signature_type_node)
2271: {
2272: sorry ("signature inheritance, base type `%s' ignored",
2273: IDENTIFIER_POINTER ($$));
2274: $$ = build_tree_list ((tree)access_public, $$);
2275: }
2276: else if (type && IS_SIGNATURE (type))
2277: {
2278: error ("signature name not allowed as base class");
2279: $$ = NULL_TREE;
2280: }
2281: else
2282: $$ = build_tree_list ((tree)access_default, $$);
2283: }
2284: | base_class_access_list base_class.1
2285: {
2286: tree type;
2287: do_base_class2:
2288: type = IDENTIFIER_TYPE_VALUE ($2);
2289: if (current_aggr == signature_type_node)
2290: error ("access and source specifiers not allowed in signature");
2291: if (! is_aggr_typedef ($2, 1))
2292: $$ = NULL_TREE;
2293: else if (current_aggr == signature_type_node
2294: && (! type) && (! IS_SIGNATURE (type)))
2295: {
2296: error ("class name not allowed as base signature");
2297: $$ = NULL_TREE;
2298: }
2299: else if (current_aggr == signature_type_node)
2300: {
2301: sorry ("signature inheritance, base type `%s' ignored",
2302: IDENTIFIER_POINTER ($$));
2303: $$ = build_tree_list ((tree)access_public, $2);
2304: }
2305: else if (type && IS_SIGNATURE (type))
2306: {
2307: error ("signature name not allowed as base class");
2308: $$ = NULL_TREE;
2309: }
2310: else
2311: $$ = build_tree_list ((tree) $$, $2);
2312: }
2313: ;
2314:
2315: base_class.1:
2316: complete_type_name
2317: | SIGOF '(' expr ')'
2318: {
2319: if (current_aggr == signature_type_node)
2320: {
2321: if (IS_AGGR_TYPE (TREE_TYPE ($3)))
2322: {
2323: sorry ("`sigof' as base signature specifier");
2324: /* need to return some dummy signature identifier */
2325: $$ = $3;
2326: }
2327: else
2328: {
2329: error ("`sigof' applied to non-aggregate expression");
2330: $$ = error_mark_node;
2331: }
2332: }
2333: else
2334: {
2335: error ("`sigof' in struct or class declaration");
2336: $$ = error_mark_node;
2337: }
2338: }
2339: | SIGOF '(' type_id ')'
2340: {
2341: if (current_aggr == signature_type_node)
2342: {
2343: if (IS_AGGR_TYPE (groktypename ($3)))
2344: {
2345: sorry ("`sigof' as base signature specifier");
2346: /* need to return some dummy signature identifier */
2347: $$ = $3;
2348: }
2349: else
2350: {
2351: error ("`sigof' applied to non-aggregate expression");
2352: $$ = error_mark_node;
2353: }
2354: }
2355: else
2356: {
2357: error ("`sigof' in struct or class declaration");
2358: $$ = error_mark_node;
2359: }
2360: }
2361: ;
2362:
2363: base_class_access_list:
2364: VISSPEC
2365: | SCSPEC
2366: { if ($<ttype>$ != ridpointers[(int)RID_VIRTUAL])
2367: sorry ("non-virtual access");
2368: $$ = access_default_virtual; }
2369: | base_class_access_list VISSPEC
2370: { int err = 0;
2371: if ($2 == access_protected)
2372: {
2373: warning ("`protected' access not implemented");
2374: $2 = access_public;
2375: err++;
2376: }
2377: else if ($2 == access_public)
2378: {
2379: if ($1 == access_private)
2380: {
2381: mixed:
2382: error ("base class cannot be public and private");
2383: }
2384: else if ($1 == access_default_virtual)
2385: $$ = access_public_virtual;
2386: }
2387: else /* $2 == access_private */
2388: {
2389: if ($1 == access_public)
2390: goto mixed;
2391: else if ($1 == access_default_virtual)
2392: $$ = access_private_virtual;
2393: }
2394: }
2395: | base_class_access_list SCSPEC
2396: { if ($2 != ridpointers[(int)RID_VIRTUAL])
2397: sorry ("non-virtual access");
2398: if ($$ == access_public)
2399: $$ = access_public_virtual;
2400: else if ($$ == access_private)
2401: $$ = access_private_virtual; }
2402: ;
2403:
2404: left_curly: '{'
2405: { tree t = $<ttype>0;
2406: push_obstacks_nochange ();
2407: end_temporary_allocation ();
2408:
2409: if (! IS_AGGR_TYPE (t))
2410: {
2411: t = $<ttype>0 = make_lang_type (RECORD_TYPE);
2412: TYPE_NAME (t) = get_identifier ("erroneous type");
2413: }
2414: if (TYPE_SIZE (t))
2415: duplicate_tag_error (t);
2416: if (TYPE_SIZE (t) || TYPE_BEING_DEFINED (t))
2417: {
2418: t = make_lang_type (TREE_CODE (t));
2419: pushtag (TYPE_IDENTIFIER ($<ttype>0), t, 0);
2420: $<ttype>0 = t;
2421: }
2422: pushclass (t, 0);
2423: TYPE_BEING_DEFINED (t) = 1;
2424: /* Reset the interface data, at the earliest possible
2425: moment, as it might have been set via a class foo;
2426: before. */
2427: /* Don't change signatures. */
2428: if (! IS_SIGNATURE (t))
2429: {
2430: extern tree pending_vtables;
2431: int needs_writing;
2432: tree name = TYPE_IDENTIFIER (t);
2433:
2434: CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
2435: SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
2436:
2437: /* Record how to set the access of this class's
2438: virtual functions. If write_virtuals == 2 or 3, then
2439: inline virtuals are ``extern inline''. */
2440: switch (write_virtuals)
2441: {
2442: case 0:
2443: case 1:
2444: needs_writing = 1;
2445: break;
2446: case 2:
2447: needs_writing = !! value_member (name, pending_vtables);
2448: break;
2449: case 3:
2450: needs_writing = ! CLASSTYPE_INTERFACE_ONLY (t)
2451: && CLASSTYPE_INTERFACE_KNOWN (t);
2452: break;
2453: default:
2454: needs_writing = 0;
2455: }
2456: CLASSTYPE_VTABLE_NEEDS_WRITING (t) = needs_writing;
2457: }
2458: #if 0
2459: t = TYPE_IDENTIFIER ($<ttype>0);
2460: if (t && IDENTIFIER_TEMPLATE (t))
2461: overload_template_name (t, 1);
2462: #endif
2463: }
2464: ;
2465:
2466: opt.component_decl_list:
2467: /* empty */
2468: { $$ = NULL_TREE; }
2469: | component_decl_list
2470: {
2471: if (current_aggr == signature_type_node)
2472: $$ = build_tree_list ((tree) access_public, $$);
2473: else
2474: $$ = build_tree_list ((tree) access_default, $$);
2475: }
2476: | opt.component_decl_list VISSPEC ':' component_decl_list
2477: {
2478: tree visspec = (tree) $2;
2479:
2480: if (current_aggr == signature_type_node)
2481: {
2482: error ("access specifier not allowed in signature");
2483: visspec = (tree) access_public;
2484: }
2485: $$ = chainon ($$, build_tree_list (visspec, $4));
2486: }
2487: | opt.component_decl_list VISSPEC ':'
2488: {
2489: if (current_aggr == signature_type_node)
2490: error ("access specifier not allowed in signature");
2491: }
2492: ;
2493:
2494: /* Note: we no longer warn about the semicolon after a component_decl_list.
2495: ARM $9.2 says that the semicolon is optional, and therefore allowed. */
2496: component_decl_list:
2497: component_decl
2498: { if ($$ == void_type_node) $$ = NULL_TREE;
2499: }
2500: | component_decl_list component_decl
2501: { /* In pushdecl, we created a reverse list of names
2502: in this binding level. Make sure that the chain
2503: of what we're trying to add isn't the item itself
2504: (which can happen with what pushdecl's doing). */
2505: if ($2 != NULL_TREE && $2 != void_type_node)
2506: {
2507: if (TREE_CHAIN ($2) != $$)
2508: $$ = chainon ($$, $2);
2509: else
2510: $$ = $2;
2511: }
2512: }
2513: | component_decl_list ';'
2514: ;
2515:
2516: component_decl:
2517: component_decl_1 ';'
2518: | component_decl_1 '}'
2519: { error ("missing ';' before right brace");
2520: yyungetc ('}', 0); }
2521: /* C++: handle constructors, destructors and inline functions */
2522: /* note that INLINE is like a TYPESPEC */
2523: | fn.def2 ':' /* base_init compstmt */
2524: { $$ = finish_method ($$); }
2525: | fn.def2 '{' /* nodecls compstmt */
2526: { $$ = finish_method ($$); }
2527: ;
2528:
2529: component_decl_1:
2530: /* Do not add a "typed_declspecs declarator" rule here for
2531: speed; we need to call grok_x_components for enums, so the
2532: speedup would be insignificant. */
2533: typed_declspecs components
2534: {
2535: $$ = grok_x_components ($$, $2);
2536: }
2537: | declmods notype_components
2538: {
2539: $$ = grok_x_components ($$, $2);
2540: }
2541: | notype_declarator maybe_raises maybeasm maybe_attribute
2542: { $$ = grokfield ($$, NULL_TREE, $2, NULL_TREE, $3);
2543: cplus_decl_attributes ($$, $4); }
2544: | ':' expr_no_commas
2545: { $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); }
2546: | error
2547: { $$ = NULL_TREE; }
2548:
2549: /* These rules introduce a reduce/reduce conflict; in
2550: typedef int foo, bar;
2551: class A {
2552: foo (bar);
2553: };
2554: should "A::foo" be declared as a function or "A::bar" as a data
2555: member? In other words, is "bar" an after_type_declarator or a
2556: parmlist? */
2557: | typed_declspecs '(' parmlist ')' type_quals
2558: { $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1),
2559: $3, $5);
2560: $$ = grokfield ($$, TREE_CHAIN ($1), NULL_TREE, NULL_TREE,
2561: NULL_TREE); }
2562: | typed_declspecs LEFT_RIGHT type_quals
2563: { $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1),
2564: empty_parms (), $3);
2565: $$ = grokfield ($$, TREE_CHAIN ($1), NULL_TREE, NULL_TREE,
2566: NULL_TREE); }
2567: ;
2568:
2569: /* The case of exactly one component is handled directly by component_decl. */
2570: components:
2571: /* empty: possibly anonymous */
2572: { $$ = NULL_TREE; }
2573: | component_declarator0
2574: | components ',' component_declarator
2575: {
2576: /* In this context, void_type_node encodes
2577: friends. They have been recorded elsewhere. */
2578: if ($$ == void_type_node)
2579: $$ = $3;
2580: else
2581: $$ = chainon ($$, $3);
2582: }
2583: ;
2584:
2585: notype_components:
2586: /* empty: possibly anonymous */
2587: { $$ = NULL_TREE; }
2588: | notype_component_declarator0
2589: | notype_components ',' notype_component_declarator
2590: {
2591: /* In this context, void_type_node encodes
2592: friends. They have been recorded elsewhere. */
2593: if ($$ == void_type_node)
2594: $$ = $3;
2595: else
2596: $$ = chainon ($$, $3);
2597: }
2598: ;
2599:
2600: component_declarator0:
2601: after_type_component_declarator0
2602: | notype_component_declarator0
2603: ;
2604:
2605: component_declarator:
2606: after_type_component_declarator
2607: | notype_component_declarator
2608: ;
2609:
2610: after_type_component_declarator0:
2611: after_type_declarator maybe_raises maybeasm maybe_attribute
2612: { current_declspecs = $<ttype>0;
2613: $$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3);
2614: cplus_decl_attributes ($$, $4); }
2615: | after_type_declarator maybe_raises maybeasm maybe_attribute '=' init
2616: { current_declspecs = $<ttype>0;
2617: $$ = grokfield ($$, current_declspecs, $2, $6, $3);
2618: cplus_decl_attributes ($$, $4); }
2619: | TYPENAME ':' expr_no_commas maybe_attribute
2620: { current_declspecs = $<ttype>0;
2621: $$ = grokbitfield ($$, current_declspecs, $3);
2622: cplus_decl_attributes ($$, $4); }
2623: ;
2624:
2625: notype_component_declarator0:
2626: notype_declarator maybe_raises maybeasm maybe_attribute
2627: { current_declspecs = $<ttype>0;
2628: $$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3);
2629: cplus_decl_attributes ($$, $4); }
2630: | notype_declarator maybe_raises maybeasm maybe_attribute '=' init
2631: { current_declspecs = $<ttype>0;
2632: $$ = grokfield ($$, current_declspecs, $2, $6, $3);
2633: cplus_decl_attributes ($$, $4); }
2634: | IDENTIFIER ':' expr_no_commas maybe_attribute
2635: { current_declspecs = $<ttype>0;
2636: $$ = grokbitfield ($$, current_declspecs, $3);
2637: cplus_decl_attributes ($$, $4); }
2638: | ':' expr_no_commas maybe_attribute
2639: { current_declspecs = $<ttype>0;
2640: $$ = grokbitfield (NULL_TREE, current_declspecs, $2);
2641: cplus_decl_attributes ($$, $3); }
2642: ;
2643:
2644: after_type_component_declarator:
2645: after_type_declarator maybe_raises maybeasm maybe_attribute
2646: { $$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3);
2647: cplus_decl_attributes ($$, $4); }
2648: | after_type_declarator maybe_raises maybeasm maybe_attribute '=' init
2649: { $$ = grokfield ($$, current_declspecs, $2, $6, $3);
2650: cplus_decl_attributes ($$, $4); }
2651: | TYPENAME ':' expr_no_commas maybe_attribute
2652: { $$ = grokbitfield ($$, current_declspecs, $3);
2653: cplus_decl_attributes ($$, $4); }
2654: ;
2655:
2656: notype_component_declarator:
2657: notype_declarator maybe_raises maybeasm maybe_attribute
2658: { $$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3);
2659: cplus_decl_attributes ($$, $4); }
2660: | notype_declarator maybe_raises maybeasm maybe_attribute '=' init
2661: { $$ = grokfield ($$, current_declspecs, $2, $6, $3);
2662: cplus_decl_attributes ($$, $4); }
2663: | IDENTIFIER ':' expr_no_commas maybe_attribute
2664: { $$ = grokbitfield ($$, current_declspecs, $3);
2665: cplus_decl_attributes ($$, $4); }
2666: | ':' expr_no_commas maybe_attribute
2667: { $$ = grokbitfield (NULL_TREE, current_declspecs, $2);
2668: cplus_decl_attributes ($$, $3); }
2669: ;
2670:
2671: /* We chain the enumerators in reverse order.
2672: Because of the way enums are built, the order is
2673: insignificant. Take advantage of this fact. */
2674:
2675: enumlist:
2676: enumerator
2677: | enumlist ',' enumerator
2678: { TREE_CHAIN ($3) = $$; $$ = $3; }
2679: ;
2680:
2681: enumerator:
2682: identifier
2683: { $$ = build_enumerator ($$, NULL_TREE); }
2684: | identifier '=' expr_no_commas
2685: { $$ = build_enumerator ($$, $3); }
2686: ;
2687:
2688: /* ANSI new-type-id (5.3.4) */
2689: new_type_id:
2690: type_specifier_seq new_declarator
2691: { $$ = build_decl_list ($$, $2); }
2692: | type_specifier_seq %prec EMPTY
2693: { $$ = build_decl_list ($$, NULL_TREE); }
2694: /* GNU extension to allow arrays of arbitrary types with
2695: non-constant dimension. */
2696: | '(' type_id ')' '[' expr ']'
2697: {
2698: if (flag_ansi)
2699: pedwarn ("ANSI C++ forbids array dimensions with parenthesized type in new");
2700: $$ = build_parse_node (ARRAY_REF, TREE_VALUE ($2), $5);
2701: $$ = build_decl_list (TREE_PURPOSE ($2), $$);
2702: }
2703: ;
2704:
2705: type_quals:
2706: /* empty */ %prec EMPTY
2707: { $$ = NULL_TREE; }
2708: | type_quals TYPE_QUAL
2709: { $$ = decl_tree_cons (NULL_TREE, $2, $$); }
2710: ;
2711:
2712: nonempty_type_quals:
2713: TYPE_QUAL
2714: { $$ = IDENTIFIER_AS_LIST ($$); }
2715: | nonempty_type_quals TYPE_QUAL
2716: { $$ = decl_tree_cons (NULL_TREE, $2, $$); }
2717: ;
2718:
2719: /* These rules must follow the rules for function declarations
2720: and component declarations. That way, longer rules are preferred. */
2721:
2722: /* An expression which will not live on the momentary obstack. */
2723: nonmomentary_expr:
2724: { $<itype>$ = suspend_momentary (); } expr
2725: { resume_momentary ((int) $<itype>1); $$ = $2; }
2726: ;
2727:
2728: /* A declarator that is allowed only after an explicit typespec. */
2729: /* may all be followed by prec '.' */
2730: after_type_declarator:
2731: '*' nonempty_type_quals after_type_declarator %prec UNARY
2732: { $$ = make_pointer_declarator ($2, $3); }
2733: | '&' nonempty_type_quals after_type_declarator %prec UNARY
2734: { $$ = make_reference_declarator ($2, $3); }
2735: | '*' after_type_declarator %prec UNARY
2736: { $$ = make_pointer_declarator (NULL_TREE, $2); }
2737: | '&' after_type_declarator %prec UNARY
2738: { $$ = make_reference_declarator (NULL_TREE, $2); }
2739: | ptr_to_mem type_quals after_type_declarator
2740: { tree arg = make_pointer_declarator ($2, $3);
2741: $$ = build_parse_node (SCOPE_REF, $1, arg);
2742: }
2743: | direct_after_type_declarator
2744: ;
2745:
2746: qualified_type_name:
2747: type_name %prec EMPTY
2748: {
2749: /* Remember that this name has been used in the class
2750: definition, as per [class.scope0] */
2751: if (current_class_type
2752: && TYPE_BEING_DEFINED (current_class_type)
2753: && ! IDENTIFIER_CLASS_VALUE ($$))
2754: {
2755: tree t = lookup_name ($$, -2);
2756: if (t)
2757: pushdecl_class_level (t);
2758: }
2759: }
2760: | nested_type
2761: ;
2762:
2763: nested_type:
2764: nested_name_specifier type_name %prec EMPTY
2765: { $$ = $2; }
2766: ;
2767:
2768: direct_after_type_declarator:
2769: direct_after_type_declarator '(' nonnull_exprlist ')' type_quals %prec '.'
2770: { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
2771: | direct_after_type_declarator '(' parmlist ')' type_quals %prec '.'
2772: { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
2773: | direct_after_type_declarator LEFT_RIGHT type_quals %prec '.'
2774: { $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $3); }
2775: | direct_after_type_declarator '(' error ')' type_quals %prec '.'
2776: { $$ = build_parse_node (CALL_EXPR, $$, NULL_TREE, NULL_TREE); }
2777: | direct_after_type_declarator '[' nonmomentary_expr ']'
2778: { $$ = build_parse_node (ARRAY_REF, $$, $3); }
2779: | direct_after_type_declarator '[' ']'
2780: { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); }
2781: | '(' after_type_declarator ')'
2782: { $$ = $2; }
2783: | nested_name_specifier type_name %prec EMPTY
2784: { push_nested_class (TREE_TYPE ($$), 3);
2785: $$ = build_parse_node (SCOPE_REF, $$, $2);
2786: TREE_COMPLEXITY ($$) = current_class_depth; }
2787: | type_name %prec EMPTY
2788: ;
2789:
2790: /* A declarator allowed whether or not there has been
2791: an explicit typespec. These cannot redeclare a typedef-name. */
2792:
2793: notype_declarator:
2794: '*' nonempty_type_quals notype_declarator %prec UNARY
2795: { $$ = make_pointer_declarator ($2, $3); }
2796: | '&' nonempty_type_quals notype_declarator %prec UNARY
2797: { $$ = make_reference_declarator ($2, $3); }
2798: | '*' notype_declarator %prec UNARY
2799: { $$ = make_pointer_declarator (NULL_TREE, $2); }
2800: | '&' notype_declarator %prec UNARY
2801: { $$ = make_reference_declarator (NULL_TREE, $2); }
2802: | ptr_to_mem type_quals notype_declarator
2803: { tree arg = make_pointer_declarator ($2, $3);
2804: $$ = build_parse_node (SCOPE_REF, $1, arg);
2805: }
2806: | direct_notype_declarator
2807: ;
2808:
2809: complex_notype_declarator:
2810: '*' nonempty_type_quals notype_declarator %prec UNARY
2811: { $$ = make_pointer_declarator ($2, $3); }
2812: | '&' nonempty_type_quals notype_declarator %prec UNARY
2813: { $$ = make_reference_declarator ($2, $3); }
2814: | '*' complex_notype_declarator %prec UNARY
2815: { $$ = make_pointer_declarator (NULL_TREE, $2); }
2816: | '&' complex_notype_declarator %prec UNARY
2817: { $$ = make_reference_declarator (NULL_TREE, $2); }
2818: | ptr_to_mem type_quals notype_declarator
2819: { tree arg = make_pointer_declarator ($2, $3);
2820: $$ = build_parse_node (SCOPE_REF, $1, arg);
2821: }
2822: | complex_direct_notype_declarator
2823: ;
2824:
2825: complex_direct_notype_declarator:
2826: direct_notype_declarator '(' nonnull_exprlist ')' type_quals %prec '.'
2827: { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
2828: | direct_notype_declarator '(' parmlist ')' type_quals %prec '.'
2829: { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
2830: | direct_notype_declarator LEFT_RIGHT type_quals %prec '.'
2831: { $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $3); }
2832: | direct_notype_declarator '(' error ')' type_quals %prec '.'
2833: { $$ = build_parse_node (CALL_EXPR, $$, NULL_TREE, NULL_TREE); }
2834: | '(' expr_or_declarator ')'
2835: { $$ = finish_decl_parsing ($2); }
2836: | '(' complex_notype_declarator ')'
2837: { $$ = $2; }
2838: | direct_notype_declarator '[' nonmomentary_expr ']'
2839: { $$ = build_parse_node (ARRAY_REF, $$, $3); }
2840: | direct_notype_declarator '[' ']'
2841: { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); }
2842: ;
2843:
2844: qualified_id:
2845: nested_name_specifier unqualified_id
2846: { got_scope = NULL_TREE;
2847: $$ = build_parse_node (SCOPE_REF, $$, $2); }
2848: ;
2849:
2850: notype_qualified_id:
2851: nested_name_specifier notype_unqualified_id
2852: { got_scope = NULL_TREE;
2853: $$ = build_parse_node (SCOPE_REF, $$, $2); }
2854: ;
2855:
2856: overqualified_id:
2857: notype_qualified_id
2858: | global_scope notype_qualified_id
2859: { $$ = $2; }
2860: ;
2861:
2862: functional_cast:
2863: typespec '(' nonnull_exprlist ')'
2864: { $$ = build_functional_cast ($$, $3); }
2865: | typespec '(' expr_or_declarator ')'
2866: { $$ = reparse_decl_as_expr ($$, $3); }
2867: | typespec fcast_or_absdcl %prec EMPTY
2868: { $$ = reparse_absdcl_as_expr ($$, $2); }
2869: ;
2870:
2871: type_name:
2872: TYPENAME
2873: | template_type %prec EMPTY
2874: ;
2875:
2876: nested_name_specifier:
2877: nested_name_specifier_1
2878: | nested_name_specifier nested_name_specifier_1
2879: { $$ = $2; }
2880: ;
2881:
2882: /* Why the @#$%^& do type_name and notype_identifier need to be expanded
2883: inline here?!? (jason) */
2884: nested_name_specifier_1:
2885: TYPENAME SCOPE
2886: { got_scope = TREE_TYPE ($$); }
2887: | template_type SCOPE
2888: { got_scope = TREE_TYPE ($$); }
2889: /* These break 'const i;'
2890: | IDENTIFIER SCOPE
2891: {
2892: failed_scope:
2893: cp_error ("`%D' is not an aggregate typedef",
2894: lastiddecl ? lastiddecl : $$);
2895: $$ = error_mark_node;
2896: }
2897: | PTYPENAME SCOPE
2898: { goto failed_scope; } */
2899: ;
2900:
2901: complete_type_name:
2902: qualified_type_name
2903: | global_scope qualified_type_name
2904: { $$ = $2; }
2905: ;
2906:
2907: complex_type_name:
2908: nested_type
2909: | global_scope qualified_type_name
2910: { $$ = $2; }
2911: ;
2912:
2913: ptr_to_mem:
2914: nested_name_specifier '*'
2915: { got_scope = NULL_TREE; }
2916: | global_scope nested_name_specifier '*'
2917: { $$ = $2; got_scope = NULL_TREE; }
2918: ;
2919:
2920: /* All uses of explicit global scope must go through this nonterminal so
2921: that got_scope will be set before yylex is called to get the next token. */
2922: global_scope:
2923: SCOPE
2924: { got_scope = void_type_node; }
2925: ;
2926:
2927: /* ANSI new-declarator (5.3.4) */
2928: new_declarator:
2929: '*' type_quals new_declarator
2930: { $$ = make_pointer_declarator ($2, $3); }
2931: | '*' type_quals %prec EMPTY
2932: { $$ = make_pointer_declarator ($2, NULL_TREE); }
2933: | '&' type_quals new_declarator %prec EMPTY
2934: { $$ = make_reference_declarator ($2, $3); }
2935: | '&' type_quals %prec EMPTY
2936: { $$ = make_reference_declarator ($2, NULL_TREE); }
2937: | ptr_to_mem type_quals %prec EMPTY
2938: { tree arg = make_pointer_declarator ($2, NULL_TREE);
2939: $$ = build_parse_node (SCOPE_REF, $1, arg);
2940: }
2941: | ptr_to_mem type_quals new_declarator
2942: { tree arg = make_pointer_declarator ($2, $3);
2943: $$ = build_parse_node (SCOPE_REF, $1, arg);
2944: }
2945: | direct_new_declarator %prec EMPTY
2946: ;
2947:
2948: /* ANSI direct-new-declarator (5.3.4) */
2949: direct_new_declarator:
2950: '[' expr ']'
2951: { $$ = build_parse_node (ARRAY_REF, NULL_TREE, $2); }
2952: | direct_new_declarator '[' nonmomentary_expr ']'
2953: { $$ = build_parse_node (ARRAY_REF, $$, $3); }
2954: ;
2955:
2956: /* ANSI abstract-declarator (8.1) */
2957: absdcl:
2958: '*' nonempty_type_quals absdcl
2959: { $$ = make_pointer_declarator ($2, $3); }
2960: | '*' absdcl
2961: { $$ = make_pointer_declarator (NULL_TREE, $2); }
2962: | '*' nonempty_type_quals %prec EMPTY
2963: { $$ = make_pointer_declarator ($2, NULL_TREE); }
2964: | '*' %prec EMPTY
2965: { $$ = make_pointer_declarator (NULL_TREE, NULL_TREE); }
2966: | '&' nonempty_type_quals absdcl
2967: { $$ = make_reference_declarator ($2, $3); }
2968: | '&' absdcl
2969: { $$ = make_reference_declarator (NULL_TREE, $2); }
2970: | '&' nonempty_type_quals %prec EMPTY
2971: { $$ = make_reference_declarator ($2, NULL_TREE); }
2972: | '&' %prec EMPTY
2973: { $$ = make_reference_declarator (NULL_TREE, NULL_TREE); }
2974: | ptr_to_mem type_quals %prec EMPTY
2975: { tree arg = make_pointer_declarator ($2, NULL_TREE);
2976: $$ = build_parse_node (SCOPE_REF, $1, arg);
2977: }
2978: | ptr_to_mem type_quals absdcl
2979: { tree arg = make_pointer_declarator ($2, $3);
2980: $$ = build_parse_node (SCOPE_REF, $1, arg);
2981: }
2982: | direct_abstract_declarator %prec EMPTY
2983: ;
2984:
2985: /* ANSI direct-abstract-declarator (8.1) */
2986: direct_abstract_declarator:
2987: '(' absdcl ')'
2988: { $$ = $2; }
2989: /* `(typedef)1' is `int'. */
2990: | PAREN_STAR_PAREN
2991: | direct_abstract_declarator '(' parmlist ')' type_quals %prec '.'
2992: { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); }
2993: | direct_abstract_declarator LEFT_RIGHT type_quals %prec '.'
2994: { $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $3); }
2995: | direct_abstract_declarator '[' nonmomentary_expr ']' %prec '.'
2996: { $$ = build_parse_node (ARRAY_REF, $$, $3); }
2997: | direct_abstract_declarator '[' ']' %prec '.'
2998: { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); }
2999: | '(' complex_parmlist ')' type_quals %prec '.'
3000: { $$ = build_parse_node (CALL_EXPR, NULL_TREE, $2, $4); }
3001: | regcast_or_absdcl type_quals %prec '.'
3002: { TREE_OPERAND ($$, 2) = $2; }
3003: | fcast_or_absdcl type_quals %prec '.'
3004: { TREE_OPERAND ($$, 2) = $2; }
3005: | '[' nonmomentary_expr ']' %prec '.'
3006: { $$ = build_parse_node (ARRAY_REF, NULL_TREE, $2); }
3007: | '[' ']' %prec '.'
3008: { $$ = build_parse_node (ARRAY_REF, NULL_TREE, NULL_TREE); }
3009: ;
3010:
3011: /* For C++, decls and stmts can be intermixed, so we don't need to
3012: have a special rule that won't start parsing the stmt section
3013: until we have a stmt that parses without errors. */
3014:
3015: stmts:
3016: stmt
3017: | errstmt
3018: | stmts stmt
3019: | stmts errstmt
3020: ;
3021:
3022: errstmt: error ';'
3023: ;
3024:
3025: /* build the LET_STMT node before parsing its contents,
3026: so that any LET_STMTs within the context can have their display pointers
3027: set up to point at this one. */
3028:
3029: .pushlevel: /* empty */
3030: { emit_line_note (input_filename, lineno);
3031: pushlevel (0);
3032: clear_last_expr ();
3033: push_momentary ();
3034: expand_start_bindings (0); }
3035: ;
3036:
3037: /* Read zero or more forward-declarations for labels
3038: that nested functions can jump to. */
3039: maybe_label_decls:
3040: /* empty */
3041: | label_decls
3042: { if (flag_ansi)
3043: pedwarn ("ANSI C++ forbids label declarations"); }
3044: ;
3045:
3046: label_decls:
3047: label_decl
3048: | label_decls label_decl
3049: ;
3050:
3051: label_decl:
3052: LABEL identifiers_or_typenames ';'
3053: { tree link;
3054: for (link = $2; link; link = TREE_CHAIN (link))
3055: {
3056: tree label = shadow_label (TREE_VALUE (link));
3057: C_DECLARED_LABEL_FLAG (label) = 1;
3058: declare_nonlocal_label (label);
3059: }
3060: }
3061: ;
3062:
3063: /* This is the body of a function definition.
3064: It causes syntax errors to ignore to the next openbrace. */
3065: compstmt_or_error:
3066: compstmt
3067: {}
3068: | error compstmt
3069: ;
3070:
3071: compstmt: '{' .pushlevel '}'
3072: { expand_end_bindings (getdecls (), kept_level_p(), 1);
3073: $$ = poplevel (kept_level_p (), 1, 0);
3074: pop_momentary (); }
3075: | '{' .pushlevel maybe_label_decls stmts '}'
3076: { expand_end_bindings (getdecls (), kept_level_p(), 1);
3077: $$ = poplevel (kept_level_p (), 1, 0);
3078: pop_momentary (); }
3079: | '{' .pushlevel maybe_label_decls stmts error '}'
3080: { expand_end_bindings (getdecls (), kept_level_p(), 1);
3081: $$ = poplevel (kept_level_p (), 0, 0);
3082: pop_momentary (); }
3083: | '{' .pushlevel maybe_label_decls error '}'
3084: { expand_end_bindings (getdecls (), kept_level_p(), 1);
3085: $$ = poplevel (kept_level_p (), 0, 0);
3086: pop_momentary (); }
3087: ;
3088:
3089: simple_if:
3090: IF
3091: { cond_stmt_keyword = "if"; }
3092: .pushlevel paren_cond_or_null
3093: { emit_line_note (input_filename, lineno);
3094: expand_start_cond ($4, 0); }
3095: implicitly_scoped_stmt
3096: ;
3097:
3098: implicitly_scoped_stmt:
3099: compstmt
3100: { finish_stmt (); }
3101: | .pushlevel simple_stmt
3102: { expand_end_bindings (getdecls (), kept_level_p (), 1);
3103: $$ = poplevel (kept_level_p (), 1, 0);
3104: pop_momentary (); }
3105: ;
3106:
3107: stmt:
3108: compstmt
3109: { finish_stmt (); }
3110: | simple_stmt
3111: ;
3112:
3113: simple_stmt:
3114: decl
3115: { finish_stmt (); }
3116: | expr ';'
3117: {
3118: tree expr = $1;
3119: emit_line_note (input_filename, lineno);
3120: /* Do default conversion if safe and possibly important,
3121: in case within ({...}). */
3122: if ((TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE
3123: && lvalue_p (expr))
3124: || TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE)
3125: expr = default_conversion (expr);
3126: cplus_expand_expr_stmt (expr);
3127: clear_momentary ();
3128: finish_stmt (); }
3129: | simple_if ELSE
3130: { expand_start_else (); }
3131: implicitly_scoped_stmt
3132: { expand_end_cond ();
3133: expand_end_bindings (getdecls (), kept_level_p (), 1);
3134: poplevel (kept_level_p (), 1, 0);
3135: pop_momentary ();
3136: finish_stmt (); }
3137: | simple_if %prec IF
3138: { expand_end_cond ();
3139: expand_end_bindings (getdecls (), kept_level_p (), 1);
3140: poplevel (kept_level_p (), 1, 0);
3141: pop_momentary ();
3142: finish_stmt (); }
3143: | WHILE
3144: { emit_nop ();
3145: emit_line_note (input_filename, lineno);
3146: expand_start_loop (1);
3147: cond_stmt_keyword = "while"; }
3148: .pushlevel paren_cond_or_null
3149: { expand_exit_loop_if_false (0, $4); }
3150: already_scoped_stmt
3151: { expand_end_bindings (getdecls (), kept_level_p (), 1);
3152: poplevel (kept_level_p (), 1, 0);
3153: pop_momentary ();
3154: expand_end_loop ();
3155: finish_stmt (); }
3156: | DO
3157: { emit_nop ();
3158: emit_line_note (input_filename, lineno);
3159: expand_start_loop_continue_elsewhere (1); }
3160: implicitly_scoped_stmt WHILE
3161: { expand_loop_continue_here ();
3162: cond_stmt_keyword = "do"; }
3163: paren_expr_or_null ';'
3164: { emit_line_note (input_filename, lineno);
3165: expand_exit_loop_if_false (0, $6);
3166: expand_end_loop ();
3167: clear_momentary ();
3168: finish_stmt (); }
3169: | forhead.1
3170: { emit_nop ();
3171: emit_line_note (input_filename, lineno);
3172: if ($1) cplus_expand_expr_stmt ($1);
3173: expand_start_loop_continue_elsewhere (1); }
3174: .pushlevel xcond ';'
3175: { emit_line_note (input_filename, lineno);
3176: if ($4) expand_exit_loop_if_false (0, $4); }
3177: xexpr ')'
3178: /* Don't let the tree nodes for $7 be discarded
3179: by clear_momentary during the parsing of the next stmt. */
3180: { push_momentary (); }
3181: already_scoped_stmt
3182: { emit_line_note (input_filename, lineno);
3183: expand_end_bindings (getdecls (), kept_level_p (), 1);
3184: poplevel (kept_level_p (), 1, 0);
3185: pop_momentary ();
3186: expand_loop_continue_here ();
3187: if ($7) cplus_expand_expr_stmt ($7);
3188: pop_momentary ();
3189: expand_end_loop ();
3190: finish_stmt (); }
3191: | forhead.2
3192: { emit_nop ();
3193: emit_line_note (input_filename, lineno);
3194: expand_start_loop_continue_elsewhere (1); }
3195: .pushlevel xcond ';'
3196: { emit_line_note (input_filename, lineno);
3197: if ($4) expand_exit_loop_if_false (0, $4); }
3198: xexpr ')'
3199: /* Don't let the tree nodes for $7 be discarded
3200: by clear_momentary during the parsing of the next stmt. */
3201: { push_momentary ();
3202: $<itype>8 = lineno; }
3203: already_scoped_stmt
3204: { emit_line_note (input_filename, (int) $<itype>8);
3205: expand_end_bindings (getdecls (), kept_level_p (), 1);
3206: poplevel (kept_level_p (), 1, 0);
3207: pop_momentary ();
3208: expand_loop_continue_here ();
3209: if ($7) cplus_expand_expr_stmt ($7);
3210: pop_momentary ();
3211: expand_end_loop ();
3212: finish_stmt ();
3213: }
3214: | SWITCH .pushlevel '(' condition ')'
3215: { emit_line_note (input_filename, lineno);
3216: c_expand_start_case ($4);
3217: /* Don't let the tree nodes for $4 be discarded by
3218: clear_momentary during the parsing of the next stmt. */
3219: push_momentary (); }
3220: implicitly_scoped_stmt
3221: { expand_end_case ($4);
3222: pop_momentary ();
3223: expand_end_bindings (getdecls (), kept_level_p (), 1);
3224: poplevel (kept_level_p (), 1, 0);
3225: pop_momentary ();
3226: finish_stmt (); }
3227: | CASE expr_no_commas ':'
3228: { register tree value = check_cp_case_value ($2);
3229: register tree label
3230: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
3231:
3232: if (value != error_mark_node)
3233: {
3234: tree duplicate;
3235: int success = pushcase (value, convert_and_check,
3236: label, &duplicate);
3237: if (success == 1)
3238: cp_error ("case label `%E' not within a switch statement", $2);
3239: else if (success == 2)
3240: {
3241: cp_error ("duplicate case value `%E'", $2);
3242: cp_error_at ("`%E' previously used here", duplicate);
3243: }
3244: else if (success == 3)
3245: warning ("case value out of range");
3246: else if (success == 5)
3247: cp_error ("case label `%E' within scope of cleanup or variable array", $2);
3248: }
3249: define_case_label (label);
3250: }
3251: stmt
3252: | CASE expr_no_commas ELLIPSIS expr_no_commas ':'
3253: { register tree value1 = check_cp_case_value ($2);
3254: register tree value2 = check_cp_case_value ($4);
3255: register tree label
3256: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
3257:
3258: if (flag_ansi)
3259: pedwarn ("ANSI C++ forbids range expressions in switch statement");
3260: if (value1 != error_mark_node
3261: && value2 != error_mark_node)
3262: {
3263: tree duplicate;
3264: int success = pushcase_range (value1, value2,
3265: convert_and_check, label,
3266: &duplicate);
3267: if (success == 1)
3268: error ("case label not within a switch statement");
3269: else if (success == 2)
3270: {
3271: error ("duplicate (or overlapping) case value");
3272: error_with_decl (duplicate, "this is the first entry overlapping that value");
3273: }
3274: else if (success == 3)
3275: warning ("case value out of range");
3276: else if (success == 4)
3277: warning ("empty range specified");
3278: else if (success == 5)
3279: error ("case label within scope of cleanup or variable array");
3280: }
3281: define_case_label (label);
3282: }
3283: stmt
3284: | DEFAULT ':'
3285: {
3286: tree duplicate;
3287: register tree label
3288: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
3289: int success = pushcase (NULL_TREE, 0, label, &duplicate);
3290: if (success == 1)
3291: error ("default label not within a switch statement");
3292: else if (success == 2)
3293: {
3294: error ("multiple default labels in one switch");
3295: error_with_decl (duplicate, "this is the first default label");
3296: }
3297: define_case_label (NULL_TREE);
3298: }
3299: stmt
3300: | BREAK ';'
3301: { emit_line_note (input_filename, lineno);
3302: if ( ! expand_exit_something ())
3303: error ("break statement not within loop or switch"); }
3304: | CONTINUE ';'
3305: { emit_line_note (input_filename, lineno);
3306: if (! expand_continue_loop (0))
3307: error ("continue statement not within a loop"); }
3308: | RETURN ';'
3309: { emit_line_note (input_filename, lineno);
3310: c_expand_return (NULL_TREE); }
3311: | RETURN expr ';'
3312: { emit_line_note (input_filename, lineno);
3313: c_expand_return ($2);
3314: finish_stmt ();
3315: }
3316: | asm_keyword maybe_type_qual '(' string ')' ';'
3317: { if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
3318: emit_line_note (input_filename, lineno);
3319: expand_asm ($4);
3320: finish_stmt ();
3321: }
3322: /* This is the case with just output operands. */
3323: | asm_keyword maybe_type_qual '(' string ':' asm_operands ')' ';'
3324: { if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
3325: emit_line_note (input_filename, lineno);
3326: c_expand_asm_operands ($4, $6, NULL_TREE, NULL_TREE,
3327: $2 == ridpointers[(int)RID_VOLATILE],
3328: input_filename, lineno);
3329: finish_stmt ();
3330: }
3331: /* This is the case with input operands as well. */
3332: | asm_keyword maybe_type_qual '(' string ':' asm_operands ':' asm_operands ')' ';'
3333: { if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
3334: emit_line_note (input_filename, lineno);
3335: c_expand_asm_operands ($4, $6, $8, NULL_TREE,
3336: $2 == ridpointers[(int)RID_VOLATILE],
3337: input_filename, lineno);
3338: finish_stmt ();
3339: }
3340: /* This is the case with clobbered registers as well. */
3341: | asm_keyword maybe_type_qual '(' string ':' asm_operands ':'
3342: asm_operands ':' asm_clobbers ')' ';'
3343: { if (TREE_CHAIN ($4)) $4 = combine_strings ($4);
3344: emit_line_note (input_filename, lineno);
3345: c_expand_asm_operands ($4, $6, $8, $10,
3346: $2 == ridpointers[(int)RID_VOLATILE],
3347: input_filename, lineno);
3348: finish_stmt ();
3349: }
3350: | GOTO '*' expr ';'
3351: { emit_line_note (input_filename, lineno);
3352: expand_computed_goto ($3); }
3353: | GOTO identifier ';'
3354: { tree decl;
3355: emit_line_note (input_filename, lineno);
3356: decl = lookup_label ($2);
3357: TREE_USED (decl) = 1;
3358: expand_goto (decl); }
3359: | label_colon stmt
3360: { finish_stmt (); }
3361: | label_colon '}'
3362: { error ("label must be followed by statement");
3363: yyungetc ('}', 0);
3364: finish_stmt (); }
3365: | ';'
3366: { finish_stmt (); }
3367: | try_block
3368: ;
3369:
3370: try_block:
3371: TRY '{' .pushlevel
3372: { expand_start_try_stmts (); }
3373: ansi_try_stmts
3374: { expand_end_try_stmts ();
3375: expand_start_all_catch (); }
3376: handler_seq
3377: { expand_end_all_catch (); }
3378: ;
3379:
3380: ansi_try_stmts:
3381: '}'
3382: /* An empty try block is degenerate, but it's better to
3383: do extra work here than to do all the special-case work
3384: everywhere else. */
3385: { expand_end_bindings (0,1,1);
3386: poplevel (2,0,0);
3387: }
3388: | stmts '}'
3389: { expand_end_bindings (0,1,1);
3390: poplevel (2,0,0);
3391: }
3392: | error '}'
3393: { expand_end_bindings (0,1,1);
3394: poplevel (2,0,0);
3395: }
3396: ;
3397:
3398: handler_seq:
3399: /* empty */
3400: | handler_seq CATCH
3401: { emit_line_note (input_filename, lineno); }
3402: handler_args compstmt
3403: { expand_end_catch_block (); }
3404: ;
3405:
3406: type_specifier_seq:
3407: typed_typespecs %prec EMPTY
3408: | nonempty_type_quals %prec EMPTY
3409: ;
3410:
3411: handler_args:
3412: '(' ELLIPSIS ')'
3413: { expand_start_catch_block (NULL_TREE, NULL_TREE); }
3414: /* This doesn't allow reference parameters, the below does.
3415: | '(' type_specifier_seq absdcl ')'
3416: { expand_start_catch_block ($2, $3); }
3417: | '(' type_specifier_seq ')'
3418: { expand_start_catch_block ($2, NULL_TREE); }
3419: | '(' type_specifier_seq notype_declarator ')'
3420: { expand_start_catch_block ($2, $3); }
3421: | '(' typed_typespecs after_type_declarator ')'
3422: { expand_start_catch_block ($2, $3); }
3423: */
3424: | '(' parm ')'
3425: { expand_start_catch_block (TREE_PURPOSE ($2),
3426: TREE_VALUE ($2)); }
3427: ;
3428:
3429: label_colon:
3430: IDENTIFIER ':'
3431: { tree label;
3432: do_label:
3433: label = define_label (input_filename, lineno, $1);
3434: if (label)
3435: expand_label (label);
3436: }
3437: | PTYPENAME ':'
3438: { goto do_label; }
3439: | TYPENAME ':'
3440: { goto do_label; }
3441: ;
3442:
3443: forhead.1:
3444: FOR '(' ';'
3445: { $$ = NULL_TREE; }
3446: | FOR '(' expr ';'
3447: { $$ = $3; }
3448: | FOR '(' '{' '}'
3449: { $$ = NULL_TREE; }
3450: ;
3451:
3452: forhead.2:
3453: FOR '(' decl
3454: { $$ = 0; }
3455: | FOR '(' error ';'
3456: { $$ = 0; }
3457: | FOR '(' '{' .pushlevel stmts '}'
3458: { $$ = 1; }
3459: | FOR '(' '{' .pushlevel error '}'
3460: { $$ = -1; }
3461: ;
3462:
3463: /* Either a type-qualifier or nothing. First thing in an `asm' statement. */
3464:
3465: maybe_type_qual:
3466: /* empty */
3467: { emit_line_note (input_filename, lineno);
3468: $$ = NULL_TREE; }
3469: | TYPE_QUAL
3470: { emit_line_note (input_filename, lineno); }
3471: ;
3472:
3473: xexpr:
3474: /* empty */
3475: { $$ = NULL_TREE; }
3476: | expr
3477: | error
3478: { $$ = NULL_TREE; }
3479: ;
3480:
3481: /* These are the operands other than the first string and colon
3482: in asm ("addextend %2,%1": "=dm" (x), "0" (y), "g" (*x)) */
3483: asm_operands: /* empty */
3484: { $$ = NULL_TREE; }
3485: | nonnull_asm_operands
3486: ;
3487:
3488: nonnull_asm_operands:
3489: asm_operand
3490: | nonnull_asm_operands ',' asm_operand
3491: { $$ = chainon ($$, $3); }
3492: ;
3493:
3494: asm_operand:
3495: STRING '(' expr ')'
3496: { $$ = build_tree_list ($$, $3); }
3497: ;
3498:
3499: asm_clobbers:
3500: STRING
3501: { $$ = tree_cons (NULL_TREE, $$, NULL_TREE); }
3502: | asm_clobbers ',' STRING
3503: { $$ = tree_cons (NULL_TREE, $3, $$); }
3504: ;
3505:
3506: /* This is what appears inside the parens in a function declarator.
3507: Its value is represented in the format that grokdeclarator expects.
3508:
3509: In C++, declaring a function with no parameters
3510: means that that function takes *no* parameters. */
3511:
3512: parmlist: /* empty */
3513: {
3514: if (strict_prototype)
3515: $$ = void_list_node;
3516: else
3517: $$ = NULL_TREE;
3518: }
3519: | complex_parmlist
3520: | type_id
3521: { $$ = tree_cons (NULL_TREE, $$, void_list_node);
3522: TREE_PARMLIST ($$) = 1; }
3523: ;
3524:
3525: /* This nonterminal does not include the common sequence '(' type_id ')',
3526: as it is ambiguous and must be disambiguated elsewhere. */
3527: complex_parmlist:
3528: parms
3529: {
3530: $$ = chainon ($$, void_list_node);
3531: TREE_PARMLIST ($$) = 1;
3532: }
3533: | parms_comma ELLIPSIS
3534: {
3535: TREE_PARMLIST ($$) = 1;
3536: }
3537: /* C++ allows an ellipsis without a separating ',' */
3538: | parms ELLIPSIS
3539: {
3540: TREE_PARMLIST ($$) = 1;
3541: }
3542: | type_id ELLIPSIS
3543: {
3544: $$ = build_tree_list (NULL_TREE, $$);
3545: TREE_PARMLIST ($$) = 1;
3546: }
3547: | ELLIPSIS
3548: {
3549: /* ARM $8.2.5 has this as a boxed-off comment. */
3550: if (pedantic)
3551: warning ("use of `...' without a first argument is non-portable");
3552: $$ = NULL_TREE;
3553: }
3554: | TYPENAME_ELLIPSIS
3555: {
3556: TREE_PARMLIST ($$) = 1;
3557: }
3558: | parms TYPENAME_ELLIPSIS
3559: {
3560: TREE_PARMLIST ($$) = 1;
3561: }
3562: | type_id TYPENAME_ELLIPSIS
3563: {
3564: $$ = build_tree_list (NULL_TREE, $$);
3565: TREE_PARMLIST ($$) = 1;
3566: }
3567: | parms ':'
3568: {
3569: /* This helps us recover from really nasty
3570: parse errors, for example, a missing right
3571: parenthesis. */
3572: yyerror ("possibly missing ')'");
3573: $$ = chainon ($$, void_list_node);
3574: TREE_PARMLIST ($$) = 1;
3575: yyungetc (':', 0);
3576: yychar = ')';
3577: }
3578: | type_id ':'
3579: {
3580: /* This helps us recover from really nasty
3581: parse errors, for example, a missing right
3582: parenthesis. */
3583: yyerror ("possibly missing ')'");
3584: $$ = tree_cons (NULL_TREE, $$, void_list_node);
3585: TREE_PARMLIST ($$) = 1;
3586: yyungetc (':', 0);
3587: yychar = ')';
3588: }
3589: ;
3590:
3591: /* A nonempty list of parameter declarations or type names. */
3592: parms:
3593: named_parm
3594: { $$ = build_tree_list (NULL_TREE, $$); }
3595: | parm '=' init
3596: { $$ = build_tree_list ($3, $$); }
3597: | parms_comma full_parm
3598: { $$ = chainon ($$, $2); }
3599: | parms_comma bad_parm
3600: { $$ = chainon ($$, build_tree_list (NULL_TREE, $2)); }
3601: | parms_comma bad_parm '=' init
3602: { $$ = chainon ($$, build_tree_list ($4, $2)); }
3603: ;
3604:
3605: parms_comma:
3606: parms ','
3607: | type_id ','
3608: { $$ = build_tree_list (NULL_TREE, $$); }
3609: ;
3610:
3611: /* A single parameter declaration or parameter type name,
3612: as found in a parmlist. The first four cases make up for 10%
3613: of the time spent parsing C++. We cannot use them because
3614: of `int id[]' which won't get parsed properly. */
3615: named_parm:
3616: /*
3617: typed_declspecs dont_see_typename '*' IDENTIFIER
3618: { $$ = build_tree_list ($$, build_parse_node (INDIRECT_REF, $4));
3619: see_typename (); }
3620: | typed_declspecs dont_see_typename '&' IDENTIFIER
3621: { $$ = build_tree_list ($$, build_parse_node (ADDR_EXPR, $4));
3622: see_typename (); }
3623: | TYPENAME IDENTIFIER
3624: { $$ = build_tree_list (get_decl_list ($$), $2); }
3625: | TYPESPEC IDENTIFIER
3626: { $$ = build_tree_list (get_decl_list ($$), $2); }
3627: | */
3628: /* Here we expand typed_declspecs inline to avoid mis-parsing of
3629: TYPESPEC IDENTIFIER. */
3630: typed_declspecs1 declarator
3631: { $$ = build_tree_list ($$, $2); }
3632: | typed_typespecs declarator
3633: { $$ = build_tree_list ($$, $2); }
3634: | typespec declarator
3635: { $$ = build_tree_list (get_decl_list ($$), $2); }
3636: | typed_declspecs1 absdcl
3637: { $$ = build_tree_list ($$, $2); }
3638: | typed_declspecs1 %prec EMPTY
3639: { $$ = build_tree_list ($$, NULL_TREE); }
3640: | declmods notype_declarator
3641: { $$ = build_tree_list ($$, $2); }
3642: ;
3643:
3644: full_parm:
3645: parm
3646: { $$ = build_tree_list (NULL_TREE, $$); }
3647: | parm '=' init
3648: { $$ = build_tree_list ($3, $$); }
3649: ;
3650:
3651: parm:
3652: named_parm
3653: | type_id
3654: ;
3655:
3656: see_typename: %prec EMPTY
3657: { see_typename (); }
3658: ;
3659:
3660: /*
3661: dont_see_typename: %prec EMPTY
3662: { dont_see_typename (); }
3663: ;
3664:
3665: try_for_typename:
3666: {
3667: if ($<ttype>-1 == error_mark_node)
3668: $$ = 0;
3669: else
3670: {
3671: $$ = 1;
3672: pushclass ($<ttype>-1, 1);
3673: }
3674: }
3675: ;
3676: */
3677:
3678: bad_parm:
3679: /* empty */ %prec EMPTY
3680: {
3681: warning ("type specifier omitted for parameter");
3682: $$ = build_tree_list (TREE_PURPOSE (TREE_VALUE ($<ttype>-1)), NULL_TREE);
3683: }
3684: | notype_declarator
3685: {
3686: warning ("type specifier omitted for parameter");
3687: $$ = build_tree_list (TREE_PURPOSE (TREE_VALUE ($<ttype>-1)), $$);
3688: }
3689: ;
3690:
3691: maybe_raises:
3692: %prec EMPTY /* empty */
3693: { $$ = NULL_TREE; }
3694: | THROW '(' ansi_raise_identifiers ')' %prec EMPTY
3695: { $$ = $3; }
3696: ;
3697:
3698: ansi_raise_identifier:
3699: type_id
3700: { $$ = build_decl_list (NULL_TREE, $$); }
3701: ;
3702:
3703: ansi_raise_identifiers:
3704: ansi_raise_identifier
3705: | ansi_raise_identifiers ',' ansi_raise_identifier
3706: {
3707: TREE_CHAIN ($3) = $$;
3708: $$ = $3;
3709: }
3710: ;
3711:
3712: conversion_declarator:
3713: /* empty */ %prec EMPTY
3714: { $$ = NULL_TREE; }
3715: | '*' type_quals conversion_declarator
3716: { $$ = make_pointer_declarator ($2, $3); }
3717: | '&' type_quals conversion_declarator
3718: { $$ = make_reference_declarator ($2, $3); }
3719: | ptr_to_mem type_quals conversion_declarator
3720: { tree arg = make_pointer_declarator ($2, $3);
3721: $$ = build_parse_node (SCOPE_REF, $1, arg);
3722: }
3723: ;
3724:
3725: operator: OPERATOR
3726: { got_scope = NULL_TREE; }
3727: ;
3728:
3729: operator_name:
3730: operator '*'
3731: { $$ = ansi_opname[MULT_EXPR]; }
3732: | operator '/'
3733: { $$ = ansi_opname[TRUNC_DIV_EXPR]; }
3734: | operator '%'
3735: { $$ = ansi_opname[TRUNC_MOD_EXPR]; }
3736: | operator '+'
3737: { $$ = ansi_opname[PLUS_EXPR]; }
3738: | operator '-'
3739: { $$ = ansi_opname[MINUS_EXPR]; }
3740: | operator '&'
3741: { $$ = ansi_opname[BIT_AND_EXPR]; }
3742: | operator '|'
3743: { $$ = ansi_opname[BIT_IOR_EXPR]; }
3744: | operator '^'
3745: { $$ = ansi_opname[BIT_XOR_EXPR]; }
3746: | operator '~'
3747: { $$ = ansi_opname[BIT_NOT_EXPR]; }
3748: | operator ','
3749: { $$ = ansi_opname[COMPOUND_EXPR]; }
3750: | operator ARITHCOMPARE
3751: { $$ = ansi_opname[$2]; }
3752: | operator '<'
3753: { $$ = ansi_opname[LT_EXPR]; }
3754: | operator '>'
3755: { $$ = ansi_opname[GT_EXPR]; }
3756: | operator EQCOMPARE
3757: { $$ = ansi_opname[$2]; }
3758: | operator ASSIGN
3759: { $$ = ansi_assopname[$2]; }
3760: | operator '='
3761: { $$ = ansi_opname [MODIFY_EXPR]; }
3762: | operator LSHIFT
3763: { $$ = ansi_opname[$2]; }
3764: | operator RSHIFT
3765: { $$ = ansi_opname[$2]; }
3766: | operator PLUSPLUS
3767: { $$ = ansi_opname[POSTINCREMENT_EXPR]; }
3768: | operator MINUSMINUS
3769: { $$ = ansi_opname[PREDECREMENT_EXPR]; }
3770: | operator ANDAND
3771: { $$ = ansi_opname[TRUTH_ANDIF_EXPR]; }
3772: | operator OROR
3773: { $$ = ansi_opname[TRUTH_ORIF_EXPR]; }
3774: | operator '!'
3775: { $$ = ansi_opname[TRUTH_NOT_EXPR]; }
3776: | operator '?' ':'
3777: { $$ = ansi_opname[COND_EXPR]; }
3778: | operator MIN_MAX
3779: { $$ = ansi_opname[$2]; }
3780: | operator POINTSAT %prec EMPTY
3781: { $$ = ansi_opname[COMPONENT_REF]; }
3782: | operator POINTSAT_STAR %prec EMPTY
3783: { $$ = ansi_opname[MEMBER_REF]; }
3784: | operator LEFT_RIGHT
3785: { $$ = ansi_opname[CALL_EXPR]; }
3786: | operator '[' ']'
3787: { $$ = ansi_opname[ARRAY_REF]; }
3788: | operator NEW %prec EMPTY
3789: { $$ = ansi_opname[NEW_EXPR]; }
3790: | operator DELETE %prec EMPTY
3791: { $$ = ansi_opname[DELETE_EXPR]; }
3792: | operator NEW '[' ']'
3793: { $$ = ansi_opname[VEC_NEW_EXPR]; }
3794: | operator DELETE '[' ']'
3795: { $$ = ansi_opname[VEC_DELETE_EXPR]; }
3796: /* Names here should be looked up in class scope ALSO. */
3797: | operator type_specifier_seq conversion_declarator
3798: { $$ = grokoptypename ($2, $3); }
3799: | operator error
3800: { $$ = ansi_opname[ERROR_MARK]; }
3801: ;
3802:
3803: %%
3804:
3805: #ifdef SPEW_DEBUG
3806: const char *
3807: debug_yytranslate (value)
3808: int value;
3809: {
3810: return yytname[YYTRANSLATE (value)];
3811: }
3812:
3813: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.