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