cgram.y revision 1.64 1 %{
2 /* $NetBSD: cgram.y,v 1.64 2014/04/21 18:57:20 christos Exp $ */
3
4 /*
5 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
6 * Copyright (c) 1994, 1995 Jochen Pohl
7 * All Rights Reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by Jochen Pohl for
20 * The NetBSD Project.
21 * 4. The name of the author may not be used to endorse or promote products
22 * derived from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36 #include <sys/cdefs.h>
37 #if defined(__RCSID) && !defined(lint)
38 __RCSID("$NetBSD: cgram.y,v 1.64 2014/04/21 18:57:20 christos Exp $");
39 #endif
40
41 #include <stdlib.h>
42 #include <string.h>
43 #include <limits.h>
44
45 #include "lint1.h"
46
47 extern char *yytext;
48 /*
49 * Contains the level of current declaration. 0 is extern.
50 * Used for symbol table entries.
51 */
52 int blklev;
53
54 /*
55 * level for memory allocation. Normaly the same as blklev.
56 * An exception is the declaration of arguments in prototypes. Memory
57 * for these can't be freed after the declaration, but symbols must
58 * be removed from the symbol table after the declaration.
59 */
60 int mblklev;
61
62 /*
63 * Save the no-warns state and restore it to avoid the problem where
64 * if (expr) { stmt } / * NOLINT * / stmt;
65 */
66 static int olwarn = LWARN_BAD;
67
68 static int toicon(tnode_t *, int);
69 static void idecl(sym_t *, int, sbuf_t *);
70 static void ignuptorp(void);
71
72 #ifdef DEBUG
73 static inline void CLRWFLGS(const char *file, size_t line);
74 static inline void CLRWFLGS(const char *file, size_t line)
75 {
76 printf("%s, %d: clear flags %s %zu\n", curr_pos.p_file,
77 curr_pos.p_line, file, line);
78 clrwflgs();
79 olwarn = LWARN_BAD;
80 }
81
82 static inline void SAVE(const char *file, size_t line);
83 static inline void SAVE(const char *file, size_t line)
84 {
85 if (olwarn != LWARN_BAD)
86 abort();
87 printf("%s, %d: save flags %s %zu = %d\n", curr_pos.p_file,
88 curr_pos.p_line, file, line, lwarn);
89 olwarn = lwarn;
90 }
91
92 static inline void RESTORE(const char *file, size_t line);
93 static inline void RESTORE(const char *file, size_t line)
94 {
95 if (olwarn != LWARN_BAD) {
96 lwarn = olwarn;
97 printf("%s, %d: restore flags %s %zu = %d\n", curr_pos.p_file,
98 curr_pos.p_line, file, line, lwarn);
99 olwarn = LWARN_BAD;
100 } else
101 CLRWFLGS(file, line);
102 }
103 #else
104 #define CLRWFLGS(f, l) clrwflgs(), olwarn = LWARN_BAD
105 #define SAVE(f, l) olwarn = lwarn
106 #define RESTORE(f, l) (void)(olwarn == LWARN_BAD ? (clrwflgs(), 0) : (lwarn = olwarn))
107 #endif
108 %}
109
110 %expect 75
111
112 %union {
113 int y_int;
114 val_t *y_val;
115 sbuf_t *y_sb;
116 sym_t *y_sym;
117 op_t y_op;
118 scl_t y_scl;
119 tspec_t y_tspec;
120 tqual_t y_tqual;
121 type_t *y_type;
122 tnode_t *y_tnode;
123 range_t y_range;
124 strg_t *y_strg;
125 pqinf_t *y_pqinf;
126 };
127
128 %token T_LBRACE T_RBRACE T_LBRACK T_RBRACK T_LPARN T_RPARN
129 %token <y_op> T_STROP
130 %token <y_op> T_UNOP
131 %token <y_op> T_INCDEC
132 %token T_SIZEOF
133 %token T_TYPEOF
134 %token T_EXTENSION
135 %token T_ALIGNOF
136 %token <y_op> T_MULT
137 %token <y_op> T_DIVOP
138 %token <y_op> T_ADDOP
139 %token <y_op> T_SHFTOP
140 %token <y_op> T_RELOP
141 %token <y_op> T_EQOP
142 %token <y_op> T_AND
143 %token <y_op> T_XOR
144 %token <y_op> T_OR
145 %token <y_op> T_LOGAND
146 %token <y_op> T_LOGOR
147 %token T_QUEST
148 %token T_COLON
149 %token <y_op> T_ASSIGN
150 %token <y_op> T_OPASS
151 %token T_COMMA
152 %token T_SEMI
153 %token T_ELLIPSE
154 %token T_REAL
155 %token T_IMAG
156
157 /* storage classes (extern, static, auto, register and typedef) */
158 %token <y_scl> T_SCLASS
159
160 /* types (char, int, short, long, unsigned, signed, float, double, void) */
161 %token <y_tspec> T_TYPE
162
163 /* qualifiers (const, volatile) */
164 %token <y_tqual> T_QUAL
165
166 /* struct or union */
167 %token <y_tspec> T_SOU
168
169 /* enum */
170 %token T_ENUM
171
172 /* remaining keywords */
173 %token T_CASE
174 %token T_DEFAULT
175 %token T_IF
176 %token T_ELSE
177 %token T_SWITCH
178 %token T_DO
179 %token T_WHILE
180 %token T_FOR
181 %token T_GOTO
182 %token T_CONTINUE
183 %token T_BREAK
184 %token T_RETURN
185 %token T_ASM
186 %token T_SYMBOLRENAME
187 %token T_PACKED
188 /* Type Attributes */
189 %token <y_type> T_ATTRIBUTE
190 %token <y_type> T_AT_ALIGNED
191 %token <y_type> T_AT_DEPRECATED
192 %token <y_type> T_AT_NORETURN
193 %token <y_type> T_AT_MAY_ALIAS
194 %token <y_type> T_AT_PACKED
195 %token <y_type> T_AT_PURE
196 %token <y_type> T_AT_TUINION
197 %token <y_type> T_AT_TUNION
198 %token <y_type> T_AT_UNUSED
199 %token <y_type> T_AT_FORMAT
200 %token <y_type> T_AT_FORMAT_PRINTF
201 %token <y_type> T_AT_FORMAT_SCANF
202 %token <y_type> T_AT_FORMAT_STRFTIME
203
204
205
206 %left T_COMMA
207 %right T_ASSIGN T_OPASS
208 %right T_QUEST T_COLON
209 %left T_LOGOR
210 %left T_LOGAND
211 %left T_OR
212 %left T_XOR
213 %left T_AND
214 %left T_EQOP
215 %left T_RELOP
216 %left T_SHFTOP
217 %left T_ADDOP
218 %left T_MULT T_DIVOP
219 %right T_UNOP T_INCDEC T_SIZEOF T_ALIGNOF T_REAL T_IMAG
220 %left T_LPARN T_LBRACK T_STROP
221
222 %token <y_sb> T_NAME
223 %token <y_sb> T_TYPENAME
224 %token <y_val> T_CON
225 %token <y_strg> T_STRING
226
227 %type <y_sym> func_decl
228 %type <y_sym> notype_decl
229 %type <y_sym> type_decl
230 %type <y_type> typespec
231 %type <y_type> clrtyp_typespec
232 %type <y_type> notype_typespec
233 %type <y_type> struct_spec
234 %type <y_type> enum_spec
235 %type <y_type> type_attribute
236 %type <y_type> type_attribute_spec
237 %type <y_sym> struct_tag
238 %type <y_sym> enum_tag
239 %type <y_tspec> struct
240 %type <y_sym> struct_declaration
241 %type <y_sb> identifier
242 %type <y_sym> member_declaration_list_with_rbrace
243 %type <y_sym> member_declaration_list
244 %type <y_sym> member_declaration
245 %type <y_sym> notype_member_decls
246 %type <y_sym> type_member_decls
247 %type <y_sym> notype_member_decl
248 %type <y_sym> type_member_decl
249 %type <y_tnode> constant
250 %type <y_sym> enum_declaration
251 %type <y_sym> enums_with_opt_comma
252 %type <y_sym> enums
253 %type <y_sym> enumerator
254 %type <y_sym> ename
255 %type <y_sym> notype_direct_decl
256 %type <y_sym> type_direct_decl
257 %type <y_pqinf> pointer
258 %type <y_pqinf> asterisk
259 %type <y_sym> param_decl
260 %type <y_sym> param_list
261 %type <y_sym> abs_decl_param_list
262 %type <y_sym> direct_param_decl
263 %type <y_sym> notype_param_decl
264 %type <y_sym> direct_notype_param_decl
265 %type <y_pqinf> type_qualifier_list
266 %type <y_pqinf> type_qualifier
267 %type <y_sym> identifier_list
268 %type <y_sym> abs_decl
269 %type <y_sym> direct_abs_decl
270 %type <y_sym> vararg_parameter_type_list
271 %type <y_sym> parameter_type_list
272 %type <y_sym> parameter_declaration
273 %type <y_tnode> expr
274 %type <y_tnode> expr_stmnt_val
275 %type <y_tnode> expr_stmnt_list
276 %type <y_tnode> term
277 %type <y_tnode> func_arg_list
278 %type <y_op> point_or_arrow
279 %type <y_type> type_name
280 %type <y_sym> abstract_declaration
281 %type <y_tnode> do_while_expr
282 %type <y_tnode> opt_expr
283 %type <y_strg> string
284 %type <y_strg> string2
285 %type <y_sb> opt_asm_or_symbolrename
286 %type <y_range> range
287 %type <y_range> lorange
288
289
290 %%
291
292 program:
293 /* empty */ {
294 if (sflag) {
295 /* empty translation unit */
296 error(272);
297 } else if (!tflag) {
298 /* empty translation unit */
299 warning(272);
300 }
301 }
302 | translation_unit
303 ;
304
305 translation_unit:
306 ext_decl
307 | translation_unit ext_decl
308 ;
309
310 ext_decl:
311 asm_stmnt
312 | func_def {
313 glclup(0);
314 CLRWFLGS(__FILE__, __LINE__);
315 }
316 | data_def {
317 glclup(0);
318 CLRWFLGS(__FILE__, __LINE__);
319 }
320 ;
321
322 data_def:
323 T_SEMI {
324 if (sflag) {
325 /* syntax error: empty declaration */
326 error(0);
327 } else if (!tflag) {
328 /* syntax error: empty declaration */
329 warning(0);
330 }
331 }
332 | clrtyp deftyp notype_init_decls T_SEMI {
333 if (sflag) {
334 /* old style declaration; add "int" */
335 error(1);
336 } else if (!tflag) {
337 /* old style declaration; add "int" */
338 warning(1);
339 }
340 }
341 | declmods deftyp T_SEMI {
342 if (dcs->d_scl == TYPEDEF) {
343 /* typedef declares no type name */
344 warning(72);
345 } else {
346 /* empty declaration */
347 warning(2);
348 }
349 }
350 | declmods deftyp notype_init_decls T_SEMI
351 | declspecs deftyp T_SEMI {
352 if (dcs->d_scl == TYPEDEF) {
353 /* typedef declares no type name */
354 warning(72);
355 } else if (!dcs->d_nedecl) {
356 /* empty declaration */
357 warning(2);
358 }
359 }
360 | declspecs deftyp type_init_decls T_SEMI
361 | error T_SEMI {
362 globclup();
363 }
364 | error T_RBRACE {
365 globclup();
366 }
367 ;
368
369 func_def:
370 func_decl {
371 if ($1->s_type->t_tspec != FUNC) {
372 /* syntax error */
373 error(249, yytext);
374 YYERROR;
375 }
376 if ($1->s_type->t_typedef) {
377 /* ()-less function definition */
378 error(64);
379 YYERROR;
380 }
381 funcdef($1);
382 blklev++;
383 pushdecl(ARG);
384 if (lwarn == LWARN_NONE)
385 $1->s_used = 1;
386 } opt_arg_declaration_list {
387 popdecl();
388 blklev--;
389 cluparg();
390 pushctrl(0);
391 } comp_stmnt {
392 funcend();
393 popctrl(0);
394 }
395 ;
396
397 func_decl:
398 clrtyp deftyp notype_decl {
399 $$ = $3;
400 }
401 | declmods deftyp notype_decl {
402 $$ = $3;
403 }
404 | declspecs deftyp type_decl {
405 $$ = $3;
406 }
407 ;
408
409 opt_arg_declaration_list:
410 /* empty */
411 | arg_declaration_list
412 ;
413
414 arg_declaration_list:
415 arg_declaration
416 | arg_declaration_list arg_declaration
417 /* XXX or better "arg_declaration error" ? */
418 | error
419 ;
420
421 /*
422 * "arg_declaration" is separated from "declaration" because it
423 * needs other error handling.
424 */
425
426 arg_declaration:
427 declmods deftyp T_SEMI {
428 /* empty declaration */
429 warning(2);
430 }
431 | declmods deftyp notype_init_decls T_SEMI
432 | declspecs deftyp T_SEMI {
433 if (!dcs->d_nedecl) {
434 /* empty declaration */
435 warning(2);
436 } else {
437 tspec_t ts = dcs->d_type->t_tspec;
438 /* %s declared in argument declaration list */
439 warning(3, ts == STRUCT ? "struct" :
440 (ts == UNION ? "union" : "enum"));
441 }
442 }
443 | declspecs deftyp type_init_decls T_SEMI {
444 if (dcs->d_nedecl) {
445 tspec_t ts = dcs->d_type->t_tspec;
446 /* %s declared in argument declaration list */
447 warning(3, ts == STRUCT ? "struct" :
448 (ts == UNION ? "union" : "enum"));
449 }
450 }
451 | declmods error
452 | declspecs error
453 ;
454
455 declaration:
456 declmods deftyp T_SEMI {
457 if (dcs->d_scl == TYPEDEF) {
458 /* typedef declares no type name */
459 warning(72);
460 } else {
461 /* empty declaration */
462 warning(2);
463 }
464 }
465 | declmods deftyp notype_init_decls T_SEMI
466 | declspecs deftyp T_SEMI {
467 if (dcs->d_scl == TYPEDEF) {
468 /* typedef declares no type name */
469 warning(72);
470 } else if (!dcs->d_nedecl) {
471 /* empty declaration */
472 warning(2);
473 }
474 }
475 | declspecs deftyp type_init_decls T_SEMI
476 | error T_SEMI
477 ;
478
479 type_attribute_format_type:
480 T_AT_FORMAT_PRINTF
481 | T_AT_FORMAT_SCANF
482 | T_AT_FORMAT_STRFTIME
483 ;
484
485 type_attribute_spec:
486 T_AT_DEPRECATED
487 | T_AT_ALIGNED T_LPARN constant T_RPARN
488 | T_AT_MAY_ALIAS
489 | T_AT_NORETURN
490 | T_AT_PACKED {
491 addpacked();
492 }
493 | T_AT_PURE
494 | T_AT_TUNION
495 | T_AT_FORMAT T_LPARN type_attribute_format_type T_COMMA
496 constant T_COMMA constant T_RPARN
497 | T_AT_UNUSED
498 | T_QUAL {
499 if ($1 != CONST)
500 yyerror("Bad attribute");
501 }
502 ;
503
504 type_attribute:
505 T_ATTRIBUTE T_LPARN T_LPARN {
506 attron = 1;
507 } type_attribute_spec {
508 attron = 0;
509 } T_RPARN T_RPARN
510 | T_PACKED {
511 addpacked();
512 }
513 ;
514
515 clrtyp:
516 {
517 clrtyp();
518 }
519 ;
520
521 deftyp:
522 /* empty */ {
523 deftyp();
524 }
525 ;
526
527 declspecs:
528 clrtyp_typespec {
529 addtype($1);
530 }
531 | declmods typespec {
532 addtype($2);
533 }
534 | type_attribute declspecs
535 | declspecs type_attribute
536 | declspecs declmod
537 | declspecs notype_typespec {
538 addtype($2);
539 }
540 ;
541
542 declmods:
543 clrtyp T_QUAL {
544 addqual($2);
545 }
546 | clrtyp T_SCLASS {
547 addscl($2);
548 }
549 | declmods declmod
550 ;
551
552 declmod:
553 T_QUAL {
554 addqual($1);
555 }
556 | T_SCLASS {
557 addscl($1);
558 }
559 ;
560
561 clrtyp_typespec:
562 clrtyp notype_typespec {
563 $$ = $2;
564 }
565 | T_TYPENAME clrtyp {
566 $$ = getsym($1)->s_type;
567 }
568 ;
569
570 typespec:
571 notype_typespec {
572 $$ = $1;
573 }
574 | T_TYPENAME {
575 $$ = getsym($1)->s_type;
576 }
577 ;
578
579 notype_typespec:
580 T_TYPE {
581 $$ = gettyp($1);
582 }
583 | T_TYPEOF term {
584 $$ = $2->tn_type;
585 }
586 | struct_spec {
587 popdecl();
588 $$ = $1;
589 }
590 | enum_spec {
591 popdecl();
592 $$ = $1;
593 }
594 ;
595
596 struct_spec:
597 struct struct_tag {
598 /*
599 * STDC requires that "struct a;" always introduces
600 * a new tag if "a" is not declared at current level
601 *
602 * yychar is valid because otherwise the parser would
603 * not been able to decide if he must shift or reduce
604 */
605 $$ = mktag($2, $1, 0, yychar == T_SEMI);
606 }
607 | struct struct_tag {
608 dcs->d_tagtyp = mktag($2, $1, 1, 0);
609 } struct_declaration {
610 $$ = compltag(dcs->d_tagtyp, $4);
611 }
612 | struct {
613 dcs->d_tagtyp = mktag(NULL, $1, 1, 0);
614 } struct_declaration {
615 $$ = compltag(dcs->d_tagtyp, $3);
616 }
617 | struct error {
618 symtyp = FVFT;
619 $$ = gettyp(INT);
620 }
621 ;
622
623 struct:
624 struct type_attribute
625 | T_SOU {
626 symtyp = FTAG;
627 pushdecl($1 == STRUCT ? MOS : MOU);
628 dcs->d_offset = 0;
629 dcs->d_stralign = CHAR_BIT;
630 $$ = $1;
631 }
632 ;
633
634 struct_tag:
635 identifier {
636 $$ = getsym($1);
637 }
638 ;
639
640 struct_declaration:
641 struct_decl_lbrace member_declaration_list_with_rbrace {
642 $$ = $2;
643 }
644 ;
645
646 struct_decl_lbrace:
647 T_LBRACE {
648 symtyp = FVFT;
649 }
650 ;
651
652 member_declaration_list_with_rbrace:
653 member_declaration_list T_SEMI T_RBRACE {
654 $$ = $1;
655 }
656 | member_declaration_list T_RBRACE {
657 if (sflag) {
658 /* syntax req. ";" after last struct/union member */
659 error(66);
660 } else {
661 /* syntax req. ";" after last struct/union member */
662 warning(66);
663 }
664 $$ = $1;
665 }
666 | T_RBRACE {
667 $$ = NULL;
668 }
669 ;
670
671 member_declaration_list:
672 member_declaration {
673 $$ = $1;
674 }
675 | member_declaration_list T_SEMI member_declaration {
676 $$ = lnklst($1, $3);
677 }
678 ;
679
680 member_declaration:
681 noclass_declmods deftyp {
682 /* too late, i know, but getsym() compensates it */
683 symtyp = FMOS;
684 } notype_member_decls {
685 symtyp = FVFT;
686 $$ = $4;
687 }
688 | noclass_declspecs deftyp {
689 symtyp = FMOS;
690 } type_member_decls {
691 symtyp = FVFT;
692 $$ = $4;
693 }
694 | noclass_declmods deftyp {
695 /* struct or union member must be named */
696 warning(49);
697 $$ = NULL;
698 }
699 | noclass_declspecs deftyp {
700 /* struct or union member must be named */
701 warning(49);
702 $$ = NULL;
703 }
704 | error {
705 symtyp = FVFT;
706 $$ = NULL;
707 }
708 ;
709
710 noclass_declspecs:
711 clrtyp_typespec {
712 addtype($1);
713 }
714 | type_attribute noclass_declspecs
715 | noclass_declmods typespec {
716 addtype($2);
717 }
718 | noclass_declspecs T_QUAL {
719 addqual($2);
720 }
721 | noclass_declspecs notype_typespec {
722 addtype($2);
723 }
724 | noclass_declspecs type_attribute
725 ;
726
727 noclass_declmods:
728 clrtyp T_QUAL {
729 addqual($2);
730 }
731 | noclass_declmods T_QUAL {
732 addqual($2);
733 }
734 ;
735
736 notype_member_decls:
737 notype_member_decl {
738 $$ = decl1str($1);
739 }
740 | notype_member_decls {
741 symtyp = FMOS;
742 } T_COMMA type_member_decl {
743 $$ = lnklst($1, decl1str($4));
744 }
745 ;
746
747 type_member_decls:
748 type_member_decl {
749 $$ = decl1str($1);
750 }
751 | type_member_decls {
752 symtyp = FMOS;
753 } T_COMMA type_member_decl {
754 $$ = lnklst($1, decl1str($4));
755 }
756 ;
757
758 notype_member_decl:
759 notype_decl {
760 $$ = $1;
761 }
762 | notype_decl T_COLON constant {
763 $$ = bitfield($1, toicon($3, 1));
764 }
765 | {
766 symtyp = FVFT;
767 } T_COLON constant {
768 $$ = bitfield(NULL, toicon($3, 1));
769 }
770 ;
771
772 type_member_decl:
773 type_decl {
774 $$ = $1;
775 }
776 | type_decl T_COLON constant {
777 $$ = bitfield($1, toicon($3, 1));
778 }
779 | {
780 symtyp = FVFT;
781 } T_COLON constant {
782 $$ = bitfield(NULL, toicon($3, 1));
783 }
784 ;
785
786 enum_spec:
787 enum enum_tag {
788 $$ = mktag($2, ENUM, 0, 0);
789 }
790 | enum enum_tag {
791 dcs->d_tagtyp = mktag($2, ENUM, 1, 0);
792 } enum_declaration {
793 $$ = compltag(dcs->d_tagtyp, $4);
794 }
795 | enum {
796 dcs->d_tagtyp = mktag(NULL, ENUM, 1, 0);
797 } enum_declaration {
798 $$ = compltag(dcs->d_tagtyp, $3);
799 }
800 | enum error {
801 symtyp = FVFT;
802 $$ = gettyp(INT);
803 }
804 ;
805
806 enum:
807 T_ENUM {
808 symtyp = FTAG;
809 pushdecl(ENUMCON);
810 }
811 ;
812
813 enum_tag:
814 identifier {
815 $$ = getsym($1);
816 }
817 ;
818
819 enum_declaration:
820 enum_decl_lbrace enums_with_opt_comma T_RBRACE {
821 $$ = $2;
822 }
823 ;
824
825 enum_decl_lbrace:
826 T_LBRACE {
827 symtyp = FVFT;
828 enumval = 0;
829 }
830 ;
831
832 enums_with_opt_comma:
833 enums {
834 $$ = $1;
835 }
836 | enums T_COMMA {
837 if (sflag) {
838 /* trailing "," prohibited in enum declaration */
839 error(54);
840 } else {
841 /* trailing "," prohibited in enum declaration */
842 c99ism(54);
843 }
844 $$ = $1;
845 }
846 ;
847
848 enums:
849 enumerator {
850 $$ = $1;
851 }
852 | enums T_COMMA enumerator {
853 $$ = lnklst($1, $3);
854 }
855 | error {
856 $$ = NULL;
857 }
858 ;
859
860 enumerator:
861 ename {
862 $$ = ename($1, enumval, 1);
863 }
864 | ename T_ASSIGN constant {
865 $$ = ename($1, toicon($3, 1), 0);
866 }
867 ;
868
869 ename:
870 identifier {
871 $$ = getsym($1);
872 }
873 ;
874
875
876 notype_init_decls:
877 notype_init_decl
878 | notype_init_decls T_COMMA type_init_decl
879 ;
880
881 type_init_decls:
882 type_init_decl
883 | type_init_decls T_COMMA type_init_decl
884 ;
885
886 notype_init_decl:
887 notype_decl opt_asm_or_symbolrename {
888 idecl($1, 0, $2);
889 chksz($1);
890 }
891 | notype_decl opt_asm_or_symbolrename {
892 idecl($1, 1, $2);
893 } T_ASSIGN initializer {
894 chksz($1);
895 }
896 ;
897
898 type_init_decl:
899 type_decl opt_asm_or_symbolrename {
900 idecl($1, 0, $2);
901 chksz($1);
902 }
903 | type_decl opt_asm_or_symbolrename {
904 idecl($1, 1, $2);
905 } T_ASSIGN initializer {
906 chksz($1);
907 }
908 ;
909
910 notype_decl:
911 notype_direct_decl {
912 $$ = $1;
913 }
914 | pointer notype_direct_decl {
915 $$ = addptr($2, $1);
916 }
917 ;
918
919 notype_direct_decl:
920 T_NAME {
921 $$ = dname(getsym($1));
922 }
923 | T_LPARN type_decl T_RPARN {
924 $$ = $2;
925 }
926 | type_attribute notype_direct_decl {
927 $$ = $2;
928 }
929 | notype_direct_decl T_LBRACK T_RBRACK {
930 $$ = addarray($1, 0, 0);
931 }
932 | notype_direct_decl T_LBRACK constant T_RBRACK {
933 $$ = addarray($1, 1, toicon($3, 0));
934 }
935 | notype_direct_decl param_list opt_asm_or_symbolrename {
936 $$ = addfunc($1, $2);
937 popdecl();
938 blklev--;
939 }
940 | notype_direct_decl type_attribute
941 ;
942
943 type_decl:
944 type_direct_decl {
945 $$ = $1;
946 }
947 | pointer type_direct_decl {
948 $$ = addptr($2, $1);
949 }
950 ;
951
952 type_direct_decl:
953 identifier {
954 $$ = dname(getsym($1));
955 }
956 | T_LPARN type_decl T_RPARN {
957 $$ = $2;
958 }
959 | type_attribute type_direct_decl {
960 $$ = $2;
961 }
962 | type_direct_decl T_LBRACK T_RBRACK {
963 $$ = addarray($1, 0, 0);
964 }
965 | type_direct_decl T_LBRACK constant T_RBRACK {
966 $$ = addarray($1, 1, toicon($3, 0));
967 }
968 | type_direct_decl param_list opt_asm_or_symbolrename {
969 $$ = addfunc($1, $2);
970 popdecl();
971 blklev--;
972 }
973 | type_direct_decl type_attribute
974 ;
975
976 /*
977 * param_decl and notype_param_decl exist to avoid a conflict in
978 * argument lists. A typename enclosed in parens should always be
979 * treated as a typename, not an argument.
980 * "typedef int a; f(int (a));" is "typedef int a; f(int foo(a));"
981 * not "typedef int a; f(int a);"
982 */
983 param_decl:
984 direct_param_decl {
985 $$ = $1;
986 }
987 | pointer direct_param_decl {
988 $$ = addptr($2, $1);
989 }
990 ;
991
992 direct_param_decl:
993 identifier {
994 $$ = dname(getsym($1));
995 }
996 | T_LPARN notype_param_decl T_RPARN {
997 $$ = $2;
998 }
999 | direct_param_decl T_LBRACK T_RBRACK {
1000 $$ = addarray($1, 0, 0);
1001 }
1002 | direct_param_decl T_LBRACK constant T_RBRACK {
1003 $$ = addarray($1, 1, toicon($3, 0));
1004 }
1005 | direct_param_decl param_list opt_asm_or_symbolrename {
1006 $$ = addfunc($1, $2);
1007 popdecl();
1008 blklev--;
1009 }
1010 ;
1011
1012 notype_param_decl:
1013 direct_notype_param_decl {
1014 $$ = $1;
1015 }
1016 | pointer direct_notype_param_decl {
1017 $$ = addptr($2, $1);
1018 }
1019 ;
1020
1021 direct_notype_param_decl:
1022 T_NAME {
1023 $$ = dname(getsym($1));
1024 }
1025 | T_LPARN notype_param_decl T_RPARN {
1026 $$ = $2;
1027 }
1028 | direct_notype_param_decl T_LBRACK T_RBRACK {
1029 $$ = addarray($1, 0, 0);
1030 }
1031 | direct_notype_param_decl T_LBRACK constant T_RBRACK {
1032 $$ = addarray($1, 1, toicon($3, 0));
1033 }
1034 | direct_notype_param_decl param_list opt_asm_or_symbolrename {
1035 $$ = addfunc($1, $2);
1036 popdecl();
1037 blklev--;
1038 }
1039 ;
1040
1041 pointer:
1042 asterisk {
1043 $$ = $1;
1044 }
1045 | asterisk type_qualifier_list {
1046 $$ = mergepq($1, $2);
1047 }
1048 | asterisk pointer {
1049 $$ = mergepq($1, $2);
1050 }
1051 | asterisk type_qualifier_list pointer {
1052 $$ = mergepq(mergepq($1, $2), $3);
1053 }
1054 ;
1055
1056 asterisk:
1057 T_MULT {
1058 $$ = xcalloc(1, sizeof (pqinf_t));
1059 $$->p_pcnt = 1;
1060 }
1061 ;
1062
1063 type_qualifier_list:
1064 type_qualifier {
1065 $$ = $1;
1066 }
1067 | type_qualifier_list type_qualifier {
1068 $$ = mergepq($1, $2);
1069 }
1070 ;
1071
1072 type_qualifier:
1073 T_QUAL {
1074 $$ = xcalloc(1, sizeof (pqinf_t));
1075 if ($1 == CONST) {
1076 $$->p_const = 1;
1077 } else {
1078 $$->p_volatile = 1;
1079 }
1080 }
1081 ;
1082
1083 param_list:
1084 id_list_lparn identifier_list T_RPARN {
1085 $$ = $2;
1086 }
1087 | abs_decl_param_list {
1088 $$ = $1;
1089 }
1090 ;
1091
1092 id_list_lparn:
1093 T_LPARN {
1094 blklev++;
1095 pushdecl(PARG);
1096 }
1097 ;
1098
1099 identifier_list:
1100 T_NAME {
1101 $$ = iname(getsym($1));
1102 }
1103 | identifier_list T_COMMA T_NAME {
1104 $$ = lnklst($1, iname(getsym($3)));
1105 }
1106 | identifier_list error {
1107 $$ = $1;
1108 }
1109 ;
1110
1111 abs_decl_param_list:
1112 abs_decl_lparn T_RPARN {
1113 $$ = NULL;
1114 }
1115 | abs_decl_lparn vararg_parameter_type_list T_RPARN {
1116 dcs->d_proto = 1;
1117 $$ = $2;
1118 }
1119 | abs_decl_lparn error T_RPARN {
1120 $$ = NULL;
1121 }
1122 ;
1123
1124 abs_decl_lparn:
1125 T_LPARN {
1126 blklev++;
1127 pushdecl(PARG);
1128 }
1129 ;
1130
1131 vararg_parameter_type_list:
1132 parameter_type_list {
1133 $$ = $1;
1134 }
1135 | parameter_type_list T_COMMA T_ELLIPSE {
1136 dcs->d_vararg = 1;
1137 $$ = $1;
1138 }
1139 | T_ELLIPSE {
1140 if (sflag) {
1141 /* ANSI C requires formal parameter before "..." */
1142 error(84);
1143 } else if (!tflag) {
1144 /* ANSI C requires formal parameter before "..." */
1145 warning(84);
1146 }
1147 dcs->d_vararg = 1;
1148 $$ = NULL;
1149 }
1150 ;
1151
1152 parameter_type_list:
1153 parameter_declaration {
1154 $$ = $1;
1155 }
1156 | parameter_type_list T_COMMA parameter_declaration {
1157 $$ = lnklst($1, $3);
1158 }
1159 ;
1160
1161 parameter_declaration:
1162 declmods deftyp {
1163 $$ = decl1arg(aname(), 0);
1164 }
1165 | declspecs deftyp {
1166 $$ = decl1arg(aname(), 0);
1167 }
1168 | declmods deftyp notype_param_decl {
1169 $$ = decl1arg($3, 0);
1170 }
1171 /*
1172 * param_decl is needed because of following conflict:
1173 * "typedef int a; f(int (a));" could be parsed as
1174 * "function with argument a of type int", or
1175 * "function with an abstract argument of type function".
1176 * This grammar realizes the second case.
1177 */
1178 | declspecs deftyp param_decl {
1179 $$ = decl1arg($3, 0);
1180 }
1181 | declmods deftyp abs_decl {
1182 $$ = decl1arg($3, 0);
1183 }
1184 | declspecs deftyp abs_decl {
1185 $$ = decl1arg($3, 0);
1186 }
1187 ;
1188
1189 opt_asm_or_symbolrename: /* expect only one */
1190 /* empty */ {
1191 $$ = NULL;
1192 }
1193 | T_ASM T_LPARN T_STRING T_RPARN {
1194 freeyyv(&$3, T_STRING);
1195 $$ = NULL;
1196 }
1197 | T_SYMBOLRENAME T_LPARN T_NAME T_RPARN {
1198 $$ = $3;
1199 }
1200 ;
1201
1202 initializer:
1203 init_expr
1204 ;
1205
1206 init_expr:
1207 expr %prec T_COMMA {
1208 mkinit($1);
1209 }
1210 | init_by_name init_expr %prec T_COMMA
1211 | init_lbrace init_rbrace
1212 | init_lbrace init_expr_list init_rbrace
1213 | init_lbrace init_expr_list T_COMMA init_rbrace
1214 | error
1215 ;
1216
1217 init_expr_list:
1218 init_expr %prec T_COMMA
1219 | init_expr_list T_COMMA init_expr
1220 ;
1221
1222 lorange:
1223 constant T_ELLIPSE {
1224 $$.lo = toicon($1, 1);
1225 }
1226 ;
1227 range:
1228 constant {
1229 $$.lo = toicon($1, 1);
1230 $$.hi = $$.lo + 1;
1231 }
1232 | lorange constant {
1233 $$.lo = $1.lo;
1234 $$.hi = toicon($2, 1);
1235 }
1236 ;
1237
1238 init_by_name:
1239 T_LBRACK range T_RBRACK T_ASSIGN {
1240 if (!Sflag)
1241 warning(321);
1242 }
1243 | point identifier T_ASSIGN {
1244 if (!Sflag)
1245 warning(313);
1246 memberpush($2);
1247 }
1248 | identifier T_COLON {
1249 gnuism(315);
1250 memberpush($1);
1251 }
1252 ;
1253
1254 init_lbrace:
1255 T_LBRACE {
1256 initlbr();
1257 }
1258 ;
1259
1260 init_rbrace:
1261 T_RBRACE {
1262 initrbr();
1263 }
1264 ;
1265
1266 type_name:
1267 {
1268 pushdecl(ABSTRACT);
1269 } abstract_declaration {
1270 popdecl();
1271 $$ = $2->s_type;
1272 }
1273 ;
1274
1275 abstract_declaration:
1276 noclass_declmods deftyp {
1277 $$ = decl1abs(aname());
1278 }
1279 | noclass_declspecs deftyp {
1280 $$ = decl1abs(aname());
1281 }
1282 | noclass_declmods deftyp abs_decl {
1283 $$ = decl1abs($3);
1284 }
1285 | noclass_declspecs deftyp abs_decl {
1286 $$ = decl1abs($3);
1287 }
1288 ;
1289
1290 abs_decl:
1291 pointer {
1292 $$ = addptr(aname(), $1);
1293 }
1294 | direct_abs_decl {
1295 $$ = $1;
1296 }
1297 | pointer direct_abs_decl {
1298 $$ = addptr($2, $1);
1299 }
1300 ;
1301
1302 direct_abs_decl:
1303 T_LPARN abs_decl T_RPARN {
1304 $$ = $2;
1305 }
1306 | T_LBRACK T_RBRACK {
1307 $$ = addarray(aname(), 0, 0);
1308 }
1309 | T_LBRACK constant T_RBRACK {
1310 $$ = addarray(aname(), 1, toicon($2, 0));
1311 }
1312 | type_attribute direct_abs_decl {
1313 $$ = $2;
1314 }
1315 | direct_abs_decl T_LBRACK T_RBRACK {
1316 $$ = addarray($1, 0, 0);
1317 }
1318 | direct_abs_decl T_LBRACK constant T_RBRACK {
1319 $$ = addarray($1, 1, toicon($3, 0));
1320 }
1321 | abs_decl_param_list opt_asm_or_symbolrename {
1322 $$ = addfunc(aname(), $1);
1323 popdecl();
1324 blklev--;
1325 }
1326 | direct_abs_decl abs_decl_param_list opt_asm_or_symbolrename {
1327 $$ = addfunc($1, $2);
1328 popdecl();
1329 blklev--;
1330 }
1331 | direct_abs_decl type_attribute
1332 ;
1333
1334 non_expr_stmnt:
1335 labeled_stmnt
1336 | comp_stmnt
1337 | selection_stmnt
1338 | iteration_stmnt
1339 | jump_stmnt {
1340 ftflg = 0;
1341 }
1342 | asm_stmnt
1343
1344 stmnt:
1345 expr_stmnt
1346 | non_expr_stmnt
1347 ;
1348
1349 labeled_stmnt:
1350 label stmnt
1351 ;
1352
1353 label:
1354 T_NAME T_COLON {
1355 symtyp = FLAB;
1356 label(T_NAME, getsym($1), NULL);
1357 }
1358 | T_CASE constant T_COLON {
1359 label(T_CASE, NULL, $2);
1360 ftflg = 1;
1361 }
1362 | T_CASE constant T_ELLIPSE constant T_COLON {
1363 /* XXX: We don't fill all cases */
1364 label(T_CASE, NULL, $2);
1365 ftflg = 1;
1366 }
1367 | T_DEFAULT T_COLON {
1368 label(T_DEFAULT, NULL, NULL);
1369 ftflg = 1;
1370 }
1371 ;
1372
1373 stmnt_d_list:
1374 stmnt_list
1375 | stmnt_d_list declaration_list stmnt_list {
1376 if (!Sflag)
1377 c99ism(327);
1378 }
1379 ;
1380
1381 comp_stmnt:
1382 comp_stmnt_lbrace comp_stmnt_rbrace
1383 | comp_stmnt_lbrace stmnt_d_list comp_stmnt_rbrace
1384 | comp_stmnt_lbrace declaration_list comp_stmnt_rbrace
1385 | comp_stmnt_lbrace declaration_list stmnt_d_list comp_stmnt_rbrace
1386 ;
1387
1388 comp_stmnt_lbrace:
1389 T_LBRACE {
1390 blklev++;
1391 mblklev++;
1392 pushdecl(AUTO);
1393 }
1394 ;
1395
1396 comp_stmnt_rbrace:
1397 T_RBRACE {
1398 popdecl();
1399 freeblk();
1400 mblklev--;
1401 blklev--;
1402 ftflg = 0;
1403 }
1404 ;
1405
1406 stmnt_list:
1407 stmnt
1408 | stmnt_list stmnt {
1409 RESTORE(__FILE__, __LINE__);
1410 }
1411 | stmnt_list error T_SEMI
1412 ;
1413
1414 expr_stmnt:
1415 expr T_SEMI {
1416 expr($1, 0, 0, 1);
1417 ftflg = 0;
1418 }
1419 | T_SEMI {
1420 ftflg = 0;
1421 }
1422 ;
1423
1424 /*
1425 * The following two productions are used to implement
1426 * ({ [[decl-list] stmt-list] }).
1427 * XXX: This is not well tested.
1428 */
1429 expr_stmnt_val:
1430 expr T_SEMI {
1431 /* XXX: We should really do that only on the last name */
1432 if ($1->tn_op == NAME)
1433 $1->tn_sym->s_used = 1;
1434 $$ = $1;
1435 expr($1, 0, 0, 0);
1436 ftflg = 0;
1437 }
1438 | non_expr_stmnt {
1439 $$ = getnode();
1440 $$->tn_type = gettyp(VOID);
1441 }
1442 ;
1443
1444 expr_stmnt_list:
1445 expr_stmnt_val
1446 | expr_stmnt_list expr_stmnt_val {
1447 $$ = $2;
1448 }
1449 ;
1450
1451 selection_stmnt:
1452 if_without_else {
1453 SAVE(__FILE__, __LINE__);
1454 if2();
1455 if3(0);
1456 }
1457 | if_without_else T_ELSE {
1458 SAVE(__FILE__, __LINE__);
1459 if2();
1460 } stmnt {
1461 CLRWFLGS(__FILE__, __LINE__);
1462 if3(1);
1463 }
1464 | if_without_else T_ELSE error {
1465 CLRWFLGS(__FILE__, __LINE__);
1466 if3(0);
1467 }
1468 | switch_expr stmnt {
1469 CLRWFLGS(__FILE__, __LINE__);
1470 switch2();
1471 }
1472 | switch_expr error {
1473 CLRWFLGS(__FILE__, __LINE__);
1474 switch2();
1475 }
1476 ;
1477
1478 if_without_else:
1479 if_expr stmnt
1480 | if_expr error
1481 ;
1482
1483 if_expr:
1484 T_IF T_LPARN expr T_RPARN {
1485 if1($3);
1486 CLRWFLGS(__FILE__, __LINE__);
1487 }
1488 ;
1489
1490 switch_expr:
1491 T_SWITCH T_LPARN expr T_RPARN {
1492 switch1($3);
1493 CLRWFLGS(__FILE__, __LINE__);
1494 }
1495 ;
1496
1497 do_stmnt:
1498 do stmnt {
1499 CLRWFLGS(__FILE__, __LINE__);
1500 }
1501 ;
1502
1503 iteration_stmnt:
1504 while_expr stmnt {
1505 CLRWFLGS(__FILE__, __LINE__);
1506 while2();
1507 }
1508 | while_expr error {
1509 CLRWFLGS(__FILE__, __LINE__);
1510 while2();
1511 }
1512 | do_stmnt do_while_expr {
1513 do2($2);
1514 ftflg = 0;
1515 }
1516 | do error {
1517 CLRWFLGS(__FILE__, __LINE__);
1518 do2(NULL);
1519 }
1520 | for_exprs stmnt {
1521 CLRWFLGS(__FILE__, __LINE__);
1522 for2();
1523 }
1524 | for_exprs error {
1525 CLRWFLGS(__FILE__, __LINE__);
1526 for2();
1527 }
1528 ;
1529
1530 while_expr:
1531 T_WHILE T_LPARN expr T_RPARN {
1532 while1($3);
1533 CLRWFLGS(__FILE__, __LINE__);
1534 }
1535 ;
1536
1537 do:
1538 T_DO {
1539 do1();
1540 }
1541 ;
1542
1543 do_while_expr:
1544 T_WHILE T_LPARN expr T_RPARN T_SEMI {
1545 $$ = $3;
1546 }
1547 ;
1548
1549 for_exprs:
1550 T_FOR T_LPARN declspecs deftyp notype_init_decls T_SEMI opt_expr
1551 T_SEMI opt_expr T_RPARN {
1552 c99ism(325);
1553 for1(NULL, $7, $9);
1554 CLRWFLGS(__FILE__, __LINE__);
1555 }
1556 | T_FOR T_LPARN opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPARN {
1557 for1($3, $5, $7);
1558 CLRWFLGS(__FILE__, __LINE__);
1559 }
1560 ;
1561
1562 opt_expr:
1563 /* empty */ {
1564 $$ = NULL;
1565 }
1566 | expr {
1567 $$ = $1;
1568 }
1569 ;
1570
1571 jump_stmnt:
1572 goto identifier T_SEMI {
1573 dogoto(getsym($2));
1574 }
1575 | goto error T_SEMI {
1576 symtyp = FVFT;
1577 }
1578 | T_CONTINUE T_SEMI {
1579 docont();
1580 }
1581 | T_BREAK T_SEMI {
1582 dobreak();
1583 }
1584 | T_RETURN T_SEMI {
1585 doreturn(NULL);
1586 }
1587 | T_RETURN expr T_SEMI {
1588 doreturn($2);
1589 }
1590 ;
1591
1592 goto:
1593 T_GOTO {
1594 symtyp = FLAB;
1595 }
1596 ;
1597
1598 asm_stmnt:
1599 T_ASM T_LPARN read_until_rparn T_SEMI {
1600 setasm();
1601 }
1602 | T_ASM T_QUAL T_LPARN read_until_rparn T_SEMI {
1603 setasm();
1604 }
1605 | T_ASM error
1606 ;
1607
1608 read_until_rparn:
1609 /* empty */ {
1610 ignuptorp();
1611 }
1612 ;
1613
1614 declaration_list:
1615 declaration {
1616 CLRWFLGS(__FILE__, __LINE__);
1617 }
1618 | declaration_list declaration {
1619 CLRWFLGS(__FILE__, __LINE__);
1620 }
1621 ;
1622
1623 constant:
1624 expr %prec T_COMMA {
1625 $$ = $1;
1626 }
1627 ;
1628
1629 expr:
1630 expr T_MULT expr {
1631 $$ = build(MULT, $1, $3);
1632 }
1633 | expr T_DIVOP expr {
1634 $$ = build($2, $1, $3);
1635 }
1636 | expr T_ADDOP expr {
1637 $$ = build($2, $1, $3);
1638 }
1639 | expr T_SHFTOP expr {
1640 $$ = build($2, $1, $3);
1641 }
1642 | expr T_RELOP expr {
1643 $$ = build($2, $1, $3);
1644 }
1645 | expr T_EQOP expr {
1646 $$ = build($2, $1, $3);
1647 }
1648 | expr T_AND expr {
1649 $$ = build(AND, $1, $3);
1650 }
1651 | expr T_XOR expr {
1652 $$ = build(XOR, $1, $3);
1653 }
1654 | expr T_OR expr {
1655 $$ = build(OR, $1, $3);
1656 }
1657 | expr T_LOGAND expr {
1658 $$ = build(LOGAND, $1, $3);
1659 }
1660 | expr T_LOGOR expr {
1661 $$ = build(LOGOR, $1, $3);
1662 }
1663 | expr T_QUEST expr T_COLON expr {
1664 $$ = build(QUEST, $1, build(COLON, $3, $5));
1665 }
1666 | expr T_ASSIGN expr {
1667 $$ = build(ASSIGN, $1, $3);
1668 }
1669 | expr T_OPASS expr {
1670 $$ = build($2, $1, $3);
1671 }
1672 | expr T_COMMA expr {
1673 $$ = build(COMMA, $1, $3);
1674 }
1675 | term {
1676 $$ = $1;
1677 }
1678 ;
1679
1680 term:
1681 T_NAME {
1682 /* XXX really necessary? */
1683 if (yychar < 0)
1684 yychar = yylex();
1685 $$ = getnnode(getsym($1), yychar);
1686 }
1687 | string {
1688 $$ = getsnode($1);
1689 }
1690 | T_CON {
1691 $$ = getcnode(gettyp($1->v_tspec), $1);
1692 }
1693 | T_LPARN expr T_RPARN {
1694 if ($2 != NULL)
1695 $2->tn_parn = 1;
1696 $$ = $2;
1697 }
1698 | T_LPARN comp_stmnt_lbrace declaration_list expr_stmnt_list {
1699 blklev--;
1700 mblklev--;
1701 initsym = mktempsym(duptyp($4->tn_type));
1702 mblklev++;
1703 blklev++;
1704 gnuism(320);
1705 } comp_stmnt_rbrace T_RPARN {
1706 $$ = getnnode(initsym, 0);
1707 }
1708 | T_LPARN comp_stmnt_lbrace expr_stmnt_list {
1709 blklev--;
1710 mblklev--;
1711 initsym = mktempsym($3->tn_type);
1712 mblklev++;
1713 blklev++;
1714 gnuism(320);
1715 } comp_stmnt_rbrace T_RPARN {
1716 $$ = getnnode(initsym, 0);
1717 }
1718 | term T_INCDEC {
1719 $$ = build($2 == INC ? INCAFT : DECAFT, $1, NULL);
1720 }
1721 | T_INCDEC term {
1722 $$ = build($1 == INC ? INCBEF : DECBEF, $2, NULL);
1723 }
1724 | T_MULT term {
1725 $$ = build(STAR, $2, NULL);
1726 }
1727 | T_AND term {
1728 $$ = build(AMPER, $2, NULL);
1729 }
1730 | T_UNOP term {
1731 $$ = build($1, $2, NULL);
1732 }
1733 | T_ADDOP term {
1734 if (tflag && $1 == PLUS) {
1735 /* unary + is illegal in traditional C */
1736 warning(100);
1737 }
1738 $$ = build($1 == PLUS ? UPLUS : UMINUS, $2, NULL);
1739 }
1740 | term T_LBRACK expr T_RBRACK {
1741 $$ = build(STAR, build(PLUS, $1, $3), NULL);
1742 }
1743 | term T_LPARN T_RPARN {
1744 $$ = funccall($1, NULL);
1745 }
1746 | term T_LPARN func_arg_list T_RPARN {
1747 $$ = funccall($1, $3);
1748 }
1749 | term point_or_arrow T_NAME {
1750 if ($1 != NULL) {
1751 sym_t *msym;
1752 /* XXX strmemb should be integrated in build() */
1753 if ($2 == ARROW) {
1754 /* must to this before strmemb is called */
1755 $1 = cconv($1);
1756 }
1757 msym = strmemb($1, $2, getsym($3));
1758 $$ = build($2, $1, getnnode(msym, 0));
1759 } else {
1760 $$ = NULL;
1761 }
1762 }
1763 | T_REAL term {
1764 $$ = build(REAL, $2, NULL);
1765 }
1766 | T_IMAG term {
1767 $$ = build(IMAG, $2, NULL);
1768 }
1769 | T_EXTENSION term {
1770 $$ = $2;
1771 }
1772 | T_REAL T_LPARN term T_RPARN {
1773 $$ = build(REAL, $3, NULL);
1774 }
1775 | T_IMAG T_LPARN term T_RPARN {
1776 $$ = build(IMAG, $3, NULL);
1777 }
1778 | T_SIZEOF term %prec T_SIZEOF {
1779 if (($$ = $2 == NULL ? NULL : bldszof($2->tn_type)) != NULL)
1780 chkmisc($2, 0, 0, 0, 0, 0, 1);
1781 }
1782 | T_SIZEOF T_LPARN type_name T_RPARN %prec T_SIZEOF {
1783 $$ = bldszof($3);
1784 }
1785 | T_ALIGNOF T_LPARN type_name T_RPARN %prec T_ALIGNOF {
1786 $$ = bldalof($3);
1787 }
1788 | T_LPARN type_name T_RPARN term %prec T_UNOP {
1789 $$ = cast($4, $2);
1790 }
1791 | T_LPARN type_name T_RPARN %prec T_UNOP {
1792 sym_t *tmp = mktempsym($2);
1793 idecl(tmp, 1, NULL);
1794 } init_lbrace init_expr_list init_rbrace {
1795 if (!Sflag)
1796 gnuism(319);
1797 $$ = getnnode(initsym, 0);
1798 }
1799 ;
1800
1801 string:
1802 T_STRING {
1803 $$ = $1;
1804 }
1805 | T_STRING string2 {
1806 $$ = catstrg($1, $2);
1807 }
1808 ;
1809
1810 string2:
1811 T_STRING {
1812 if (tflag) {
1813 /* concatenated strings are illegal in traditional C */
1814 warning(219);
1815 }
1816 $$ = $1;
1817 }
1818 | string2 T_STRING {
1819 $$ = catstrg($1, $2);
1820 }
1821 ;
1822
1823 func_arg_list:
1824 expr %prec T_COMMA {
1825 $$ = funcarg(NULL, $1);
1826 }
1827 | func_arg_list T_COMMA expr {
1828 $$ = funcarg($1, $3);
1829 }
1830 ;
1831
1832 point_or_arrow:
1833 T_STROP {
1834 symtyp = FMOS;
1835 $$ = $1;
1836 }
1837 ;
1838
1839 point:
1840 T_STROP {
1841 if ($1 != POINT) {
1842 error(249, yytext);
1843 }
1844 }
1845 ;
1846
1847 identifier:
1848 T_NAME {
1849 $$ = $1;
1850 }
1851 | T_TYPENAME {
1852 $$ = $1;
1853 }
1854 ;
1855
1856 %%
1857
1858 /* ARGSUSED */
1859 int
1860 yyerror(const char *msg)
1861 {
1862 error(249, yytext);
1863 if (++sytxerr >= 5)
1864 norecover();
1865 return (0);
1866 }
1867
1868 static __inline int uq_gt(uint64_t, uint64_t);
1869 static __inline int q_gt(int64_t, int64_t);
1870
1871 static __inline int
1872 uq_gt(uint64_t a, uint64_t b)
1873 {
1874
1875 return (a > b);
1876 }
1877
1878 static __inline int
1879 q_gt(int64_t a, int64_t b)
1880 {
1881
1882 return (a > b);
1883 }
1884
1885 #define q_lt(a, b) q_gt(b, a)
1886
1887 /*
1888 * Gets a node for a constant and returns the value of this constant
1889 * as integer.
1890 * Is the node not constant or too large for int or of type float,
1891 * a warning will be printed.
1892 *
1893 * toicon() should be used only inside declarations. If it is used in
1894 * expressions, it frees the memory used for the expression.
1895 */
1896 static int
1897 toicon(tnode_t *tn, int required)
1898 {
1899 int i;
1900 tspec_t t;
1901 val_t *v;
1902
1903 v = constant(tn, required);
1904
1905 /*
1906 * Abstract declarations are used inside expression. To free
1907 * the memory would be a fatal error.
1908 */
1909 if (dcs->d_ctx != ABSTRACT)
1910 tfreeblk();
1911
1912 if ((t = v->v_tspec) == FLOAT || t == DOUBLE || t == LDOUBLE) {
1913 i = (int)v->v_ldbl;
1914 /* integral constant expression expected */
1915 error(55);
1916 } else {
1917 i = (int)v->v_quad;
1918 if (isutyp(t)) {
1919 if (uq_gt((uint64_t)v->v_quad,
1920 (uint64_t)TARG_INT_MAX)) {
1921 /* integral constant too large */
1922 warning(56);
1923 }
1924 } else {
1925 if (q_gt(v->v_quad, (int64_t)TARG_INT_MAX) ||
1926 q_lt(v->v_quad, (int64_t)TARG_INT_MIN)) {
1927 /* integral constant too large */
1928 warning(56);
1929 }
1930 }
1931 }
1932 free(v);
1933 return (i);
1934 }
1935
1936 static void
1937 idecl(sym_t *decl, int initflg, sbuf_t *renaming)
1938 {
1939 char *s;
1940
1941 initerr = 0;
1942 initsym = decl;
1943
1944 switch (dcs->d_ctx) {
1945 case EXTERN:
1946 if (renaming != NULL) {
1947 if (decl->s_rename != NULL)
1948 LERROR("idecl()");
1949
1950 s = getlblk(1, renaming->sb_len + 1);
1951 (void)memcpy(s, renaming->sb_name, renaming->sb_len + 1);
1952 decl->s_rename = s;
1953 freeyyv(&renaming, T_NAME);
1954 }
1955 decl1ext(decl, initflg);
1956 break;
1957 case ARG:
1958 if (renaming != NULL) {
1959 /* symbol renaming can't be used on function arguments */
1960 error(310);
1961 freeyyv(&renaming, T_NAME);
1962 break;
1963 }
1964 (void)decl1arg(decl, initflg);
1965 break;
1966 case AUTO:
1967 if (renaming != NULL) {
1968 /* symbol renaming can't be used on automatic variables */
1969 error(311);
1970 freeyyv(&renaming, T_NAME);
1971 break;
1972 }
1973 decl1loc(decl, initflg);
1974 break;
1975 default:
1976 LERROR("idecl()");
1977 }
1978
1979 if (initflg && !initerr)
1980 prepinit();
1981 }
1982
1983 /*
1984 * Discard all input tokens up to and including the next
1985 * unmatched right paren
1986 */
1987 static void
1988 ignuptorp(void)
1989 {
1990 int level;
1991
1992 if (yychar < 0)
1993 yychar = yylex();
1994 freeyyv(&yylval, yychar);
1995
1996 level = 1;
1997 while (yychar != T_RPARN || --level > 0) {
1998 if (yychar == T_LPARN) {
1999 level++;
2000 } else if (yychar <= 0) {
2001 break;
2002 }
2003 freeyyv(&yylval, yychar = yylex());
2004 }
2005
2006 yyclearin;
2007 }
2008