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