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