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