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