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