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