Switch pkg_radd and pkg_search to appropriate CPU type path, i386 or amd64.
[dragonfly.git] / usr.bin / xlint / lint1 / cgram.y
blob2744035c944ca42ce262bd1b3d6e47dc9953e0d3
1 %{
2 /* $NetBSD: cgram.y,v 1.8 1995/10/02 17:31:35 jpo Exp $ */
4 /*
5 * Copyright (c) 1994, 1995 Jochen Pohl
6 * All Rights Reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by Jochen Pohl for
19 * The NetBSD Project.
20 * 4. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 * $NetBSD: cgram.y,v 1.8 1995/10/02 17:31:35 jpo Exp $
35 * $DragonFly: src/usr.bin/xlint/lint1/cgram.y,v 1.6 2004/07/07 12:26:51 asmodai Exp $
38 #include <stdlib.h>
39 #include <limits.h>
41 #include "lint1.h"
44 * Contains the level of current declaration. 0 is extern.
45 * Used for symbol table entries.
47 int blklev;
50 * level for memory allocation. Normaly the same as blklev.
51 * An exeption is the declaration of arguments in prototypes. Memory
52 * for these can't be freed after the declaration, but symbols must
53 * be removed from the symbol table after the declaration.
55 int mblklev;
57 static int toicon(tnode_t *);
58 static void idecl(sym_t *, int);
59 static void ignuptorp(void);
63 %union {
64 int y_int;
65 val_t *y_val;
66 sbuf_t *y_sb;
67 sym_t *y_sym;
68 op_t y_op;
69 scl_t y_scl;
70 tspec_t y_tspec;
71 tqual_t y_tqual;
72 type_t *y_type;
73 tnode_t *y_tnode;
74 strg_t *y_strg;
75 pqinf_t *y_pqinf;
78 %token T_LBRACE T_RBRACE T_LBRACK T_RBRACK T_LPARN T_RPARN
79 %token <y_op> T_STROP
80 %token <y_op> T_UNOP
81 %token <y_op> T_INCDEC
82 %token T_SIZEOF
83 %token <y_op> T_MULT
84 %token <y_op> T_DIVOP
85 %token <y_op> T_ADDOP
86 %token <y_op> T_SHFTOP
87 %token <y_op> T_RELOP
88 %token <y_op> T_EQOP
89 %token <y_op> T_AND
90 %token <y_op> T_XOR
91 %token <y_op> T_OR
92 %token <y_op> T_LOGAND
93 %token <y_op> T_LOGOR
94 %token T_QUEST
95 %token T_COLON
96 %token <y_op> T_ASSIGN
97 %token <y_op> T_OPASS
98 %token T_COMMA
99 %token T_SEMI
100 %token T_ELLIPSE
102 /* storage classes (extern, static, auto, register and typedef) */
103 %token <y_scl> T_SCLASS
105 /* types (char, int, short, long, unsigned, signed, float, double, void) */
106 %token <y_tspec> T_TYPE
108 /* qualifiers (const, volatile) */
109 %token <y_tqual> T_QUAL
111 /* struct or union */
112 %token <y_tspec> T_SOU
114 /* enum */
115 %token T_ENUM
117 /* remaining keywords */
118 %token T_CASE
119 %token T_DEFAULT
120 %token T_IF
121 %token T_ELSE
122 %token T_SWITCH
123 %token T_DO
124 %token T_WHILE
125 %token T_FOR
126 %token T_GOTO
127 %token T_CONTINUE
128 %token T_BREAK
129 %token T_RETURN
130 %token T_ASM
132 %left T_COMMA
133 %right T_ASSIGN T_OPASS
134 %right T_QUEST T_COLON
135 %left T_LOGOR
136 %left T_LOGAND
137 %left T_OR
138 %left T_XOR
139 %left T_AND
140 %left T_EQOP
141 %left T_RELOP
142 %left T_SHFTOP
143 %left T_ADDOP
144 %left T_MULT T_DIVOP
145 %right T_UNOP T_INCDEC T_SIZEOF
146 %left T_LPARN T_LBRACK T_STROP
148 %token <y_sb> T_NAME
149 %token <y_sb> T_TYPENAME
150 %token <y_val> T_CON
151 %token <y_strg> T_STRING
153 %type <y_sym> func_decl
154 %type <y_sym> notype_decl
155 %type <y_sym> type_decl
156 %type <y_type> typespec
157 %type <y_type> clrtyp_typespec
158 %type <y_type> notype_typespec
159 %type <y_type> struct_spec
160 %type <y_type> enum_spec
161 %type <y_sym> struct_tag
162 %type <y_sym> enum_tag
163 %type <y_tspec> struct
164 %type <y_sym> struct_declaration
165 %type <y_sb> identifier
166 %type <y_sym> member_declaration_list_with_rbrace
167 %type <y_sym> member_declaration_list
168 %type <y_sym> member_declaration
169 %type <y_sym> notype_member_decls
170 %type <y_sym> type_member_decls
171 %type <y_sym> notype_member_decl
172 %type <y_sym> type_member_decl
173 %type <y_tnode> constant
174 %type <y_sym> enum_declaration
175 %type <y_sym> enums_with_opt_comma
176 %type <y_sym> enums
177 %type <y_sym> enumerator
178 %type <y_sym> ename
179 %type <y_sym> notype_direct_decl
180 %type <y_sym> type_direct_decl
181 %type <y_pqinf> pointer
182 %type <y_pqinf> asterisk
183 %type <y_sym> param_decl
184 %type <y_sym> param_list
185 %type <y_sym> abs_decl_param_list
186 %type <y_sym> direct_param_decl
187 %type <y_sym> notype_param_decl
188 %type <y_sym> direct_notype_param_decl
189 %type <y_pqinf> type_qualifier_list
190 %type <y_pqinf> type_qualifier
191 %type <y_sym> identifier_list
192 %type <y_sym> abs_decl
193 %type <y_sym> direct_abs_decl
194 %type <y_sym> vararg_parameter_type_list
195 %type <y_sym> parameter_type_list
196 %type <y_sym> parameter_declaration
197 %type <y_tnode> expr
198 %type <y_tnode> term
199 %type <y_tnode> func_arg_list
200 %type <y_op> point_or_arrow
201 %type <y_type> type_name
202 %type <y_sym> abstract_declaration
203 %type <y_tnode> do_while_expr
204 %type <y_tnode> opt_expr
205 %type <y_strg> string
206 %type <y_strg> string2
211 program:
212 /* empty */ {
213 if (sflag) {
214 /* empty translation unit */
215 error(272);
216 } else if (!tflag) {
217 /* empty translation unit */
218 warning(272);
221 | translation_unit
224 translation_unit:
225 ext_decl
226 | translation_unit ext_decl
229 ext_decl:
230 func_def {
231 glclup(0);
232 clrwflgs();
234 | data_def {
235 glclup(0);
236 clrwflgs();
240 data_def:
241 T_SEMI {
242 if (sflag) {
243 /* syntax error: empty declaration */
244 error(0);
245 } else if (!tflag) {
246 /* syntax error: empty declaration */
247 warning(0);
250 | clrtyp deftyp notype_init_decls T_SEMI {
251 if (sflag) {
252 /* old style declaration; add "int" */
253 error(1);
254 } else if (!tflag) {
255 /* old style declaration; add "int" */
256 warning(1);
259 | declmods deftyp T_SEMI {
260 if (dcs->d_scl == TYPEDEF) {
261 /* typedef declares no type name */
262 warning(72);
263 } else {
264 /* empty declaration */
265 warning(2);
268 | declmods deftyp notype_init_decls T_SEMI
269 | declspecs deftyp T_SEMI {
270 if (dcs->d_scl == TYPEDEF) {
271 /* typedef declares no type name */
272 warning(72);
273 } else if (!dcs->d_nedecl) {
274 /* empty declaration */
275 warning(2);
278 | declspecs deftyp type_init_decls T_SEMI
279 | error T_SEMI {
280 globclup();
282 | error T_RBRACE {
283 globclup();
287 func_def:
288 func_decl {
289 if ($1->s_type->t_tspec != FUNC) {
290 /* syntax error */
291 error(249);
292 YYERROR;
294 if ($1->s_type->t_typedef) {
295 /* ()-less function definition */
296 error(64);
297 YYERROR;
299 funcdef($1);
300 blklev++;
301 pushdecl(ARG);
302 } opt_arg_declaration_list {
303 popdecl();
304 blklev--;
305 cluparg();
306 pushctrl(0);
307 } comp_stmnt {
308 funcend();
309 popctrl(0);
313 func_decl:
314 clrtyp deftyp notype_decl {
315 $$ = $3;
317 | declmods deftyp notype_decl {
318 $$ = $3;
320 | declspecs deftyp type_decl {
321 $$ = $3;
325 opt_arg_declaration_list:
326 /* empty */
327 | arg_declaration_list
330 arg_declaration_list:
331 arg_declaration
332 | arg_declaration_list arg_declaration
333 /* XXX or better "arg_declaration error" ? */
334 | error
338 * "arg_declaration" is separated from "declaration" because it
339 * needs other error handling.
342 arg_declaration:
343 declmods deftyp T_SEMI {
344 /* empty declaration */
345 warning(2);
347 | declmods deftyp notype_init_decls T_SEMI
348 | declspecs deftyp T_SEMI {
349 if (!dcs->d_nedecl) {
350 /* empty declaration */
351 warning(2);
352 } else {
353 tspec_t ts = dcs->d_type->t_tspec;
354 /* %s declared in argument declaration list */
355 warning(3, ts == STRUCT ? "struct" :
356 (ts == UNION ? "union" : "enum"));
359 | declspecs deftyp type_init_decls T_SEMI {
360 if (dcs->d_nedecl) {
361 tspec_t ts = dcs->d_type->t_tspec;
362 /* %s declared in argument declaration list */
363 warning(3, ts == STRUCT ? "struct" :
364 (ts == UNION ? "union" : "enum"));
367 | declmods error
368 | declspecs error
371 declaration:
372 declmods deftyp T_SEMI {
373 if (dcs->d_scl == TYPEDEF) {
374 /* typedef declares no type name */
375 warning(72);
376 } else {
377 /* empty declaration */
378 warning(2);
381 | declmods deftyp notype_init_decls T_SEMI
382 | declspecs deftyp T_SEMI {
383 if (dcs->d_scl == TYPEDEF) {
384 /* typedef declares no type name */
385 warning(72);
386 } else if (!dcs->d_nedecl) {
387 /* empty declaration */
388 warning(2);
391 | declspecs deftyp type_init_decls T_SEMI
392 | error T_SEMI
395 clrtyp:
397 clrtyp();
401 deftyp:
402 /* empty */ {
403 deftyp();
407 declspecs:
408 clrtyp_typespec {
409 addtype($1);
411 | declmods typespec {
412 addtype($2);
414 | declspecs declmod
415 | declspecs notype_typespec {
416 addtype($2);
420 declmods:
421 clrtyp T_QUAL {
422 addqual($2);
424 | clrtyp T_SCLASS {
425 addscl($2);
427 | declmods declmod
430 declmod:
431 T_QUAL {
432 addqual($1);
434 | T_SCLASS {
435 addscl($1);
439 clrtyp_typespec:
440 clrtyp notype_typespec {
441 $$ = $2;
443 | T_TYPENAME clrtyp {
444 $$ = getsym($1)->s_type;
448 typespec:
449 notype_typespec {
450 $$ = $1;
452 | T_TYPENAME {
453 $$ = getsym($1)->s_type;
457 notype_typespec:
458 T_TYPE {
459 $$ = gettyp($1);
461 | struct_spec {
462 popdecl();
463 $$ = $1;
465 | enum_spec {
466 popdecl();
467 $$ = $1;
471 struct_spec:
472 struct struct_tag {
474 * STDC requires that "struct a;" always introduces
475 * a new tag if "a" is not declared at current level
477 * yychar is valid because otherwise the parser would
478 * not been able to deceide if he must shift or reduce
480 $$ = mktag($2, $1, 0, yychar == T_SEMI);
482 | struct struct_tag {
483 dcs->d_tagtyp = mktag($2, $1, 1, 0);
484 } struct_declaration {
485 $$ = compltag(dcs->d_tagtyp, $4);
487 | struct {
488 dcs->d_tagtyp = mktag(NULL, $1, 1, 0);
489 } struct_declaration {
490 $$ = compltag(dcs->d_tagtyp, $3);
492 | struct error {
493 symtyp = FVFT;
494 $$ = gettyp(INT);
498 struct:
499 T_SOU {
500 symtyp = FTAG;
501 pushdecl($1 == STRUCT ? MOS : MOU);
502 dcs->d_offset = 0;
503 dcs->d_stralign = CHAR_BIT;
504 $$ = $1;
508 struct_tag:
509 identifier {
510 $$ = getsym($1);
514 struct_declaration:
515 struct_decl_lbrace member_declaration_list_with_rbrace {
516 $$ = $2;
520 struct_decl_lbrace:
521 T_LBRACE {
522 symtyp = FVFT;
526 member_declaration_list_with_rbrace:
527 member_declaration_list T_SEMI T_RBRACE {
528 $$ = $1;
530 | member_declaration_list T_RBRACE {
531 if (sflag) {
532 /* syntax req. ";" after last struct/union member */
533 error(66);
534 } else {
535 /* syntax req. ";" after last struct/union member */
536 warning(66);
538 $$ = $1;
540 | T_RBRACE {
541 $$ = NULL;
545 member_declaration_list:
546 member_declaration {
547 $$ = $1;
549 | member_declaration_list T_SEMI member_declaration {
550 $$ = lnklst($1, $3);
554 member_declaration:
555 noclass_declmods deftyp {
556 /* too late, i know, but getsym() compensates it */
557 symtyp = FMOS;
558 } notype_member_decls {
559 symtyp = FVFT;
560 $$ = $4;
562 | noclass_declspecs deftyp {
563 symtyp = FMOS;
564 } type_member_decls {
565 symtyp = FVFT;
566 $$ = $4;
568 | noclass_declmods deftyp {
569 /* struct or union member must be named */
570 warning(49);
571 $$ = NULL;
573 | noclass_declspecs deftyp {
574 /* struct or union member must be named */
575 warning(49);
576 $$ = NULL;
578 | error {
579 symtyp = FVFT;
580 $$ = NULL;
584 noclass_declspecs:
585 clrtyp_typespec {
586 addtype($1);
588 | noclass_declmods typespec {
589 addtype($2);
591 | noclass_declspecs T_QUAL {
592 addqual($2);
594 | noclass_declspecs notype_typespec {
595 addtype($2);
599 noclass_declmods:
600 clrtyp T_QUAL {
601 addqual($2);
603 | noclass_declmods T_QUAL {
604 addqual($2);
608 notype_member_decls:
609 notype_member_decl {
610 $$ = decl1str($1);
612 | notype_member_decls {
613 symtyp = FMOS;
614 } T_COMMA type_member_decl {
615 $$ = lnklst($1, decl1str($4));
619 type_member_decls:
620 type_member_decl {
621 $$ = decl1str($1);
623 | type_member_decls {
624 symtyp = FMOS;
625 } T_COMMA type_member_decl {
626 $$ = lnklst($1, decl1str($4));
630 notype_member_decl:
631 notype_decl {
632 $$ = $1;
634 | notype_decl T_COLON constant {
635 $$ = bitfield($1, toicon($3));
638 symtyp = FVFT;
639 } T_COLON constant {
640 $$ = bitfield(NULL, toicon($3));
644 type_member_decl:
645 type_decl {
646 $$ = $1;
648 | type_decl T_COLON constant {
649 $$ = bitfield($1, toicon($3));
652 symtyp = FVFT;
653 } T_COLON constant {
654 $$ = bitfield(NULL, toicon($3));
658 enum_spec:
659 enum enum_tag {
660 $$ = mktag($2, ENUM, 0, 0);
662 | enum enum_tag {
663 dcs->d_tagtyp = mktag($2, ENUM, 1, 0);
664 } enum_declaration {
665 $$ = compltag(dcs->d_tagtyp, $4);
667 | enum {
668 dcs->d_tagtyp = mktag(NULL, ENUM, 1, 0);
669 } enum_declaration {
670 $$ = compltag(dcs->d_tagtyp, $3);
672 | enum error {
673 symtyp = FVFT;
674 $$ = gettyp(INT);
678 enum:
679 T_ENUM {
680 symtyp = FTAG;
681 pushdecl(ENUMCON);
685 enum_tag:
686 identifier {
687 $$ = getsym($1);
691 enum_declaration:
692 enum_decl_lbrace enums_with_opt_comma T_RBRACE {
693 $$ = $2;
697 enum_decl_lbrace:
698 T_LBRACE {
699 symtyp = FVFT;
700 enumval = 0;
704 enums_with_opt_comma:
705 enums {
706 $$ = $1;
708 | enums T_COMMA {
709 if (sflag) {
710 /* trailing "," prohibited in enum declaration */
711 error(54);
712 } else {
713 /* trailing "," prohibited in enum declaration */
714 warning(54);
716 $$ = $1;
720 enums:
721 enumerator {
722 $$ = $1;
724 | enums T_COMMA enumerator {
725 $$ = lnklst($1, $3);
727 | error {
728 $$ = NULL;
732 enumerator:
733 ename {
734 $$ = ename($1, enumval, 1);
736 | ename T_ASSIGN constant {
737 $$ = ename($1, toicon($3), 0);
741 ename:
742 identifier {
743 $$ = getsym($1);
748 notype_init_decls:
749 notype_init_decl
750 | notype_init_decls T_COMMA type_init_decl
753 type_init_decls:
754 type_init_decl
755 | type_init_decls T_COMMA type_init_decl
758 notype_init_decl:
759 notype_decl opt_asm_spec {
760 idecl($1, 0);
761 chksz($1);
763 | notype_decl opt_asm_spec {
764 idecl($1, 1);
765 } T_ASSIGN initializer {
766 chksz($1);
770 type_init_decl:
771 type_decl opt_asm_spec {
772 idecl($1, 0);
773 chksz($1);
775 | type_decl opt_asm_spec {
776 idecl($1, 1);
777 } T_ASSIGN initializer {
778 chksz($1);
782 notype_decl:
783 notype_direct_decl {
784 $$ = $1;
786 | pointer notype_direct_decl {
787 $$ = addptr($2, $1);
791 notype_direct_decl:
792 T_NAME {
793 $$ = dname(getsym($1));
795 | T_LPARN type_decl T_RPARN {
796 $$ = $2;
798 | notype_direct_decl T_LBRACK T_RBRACK {
799 $$ = addarray($1, 0, 0);
801 | notype_direct_decl T_LBRACK constant T_RBRACK {
802 $$ = addarray($1, 1, toicon($3));
804 | notype_direct_decl param_list {
805 $$ = addfunc($1, $2);
806 popdecl();
807 blklev--;
811 type_decl:
812 type_direct_decl {
813 $$ = $1;
815 | pointer type_direct_decl {
816 $$ = addptr($2, $1);
820 type_direct_decl:
821 identifier {
822 $$ = dname(getsym($1));
824 | T_LPARN type_decl T_RPARN {
825 $$ = $2;
827 | type_direct_decl T_LBRACK T_RBRACK {
828 $$ = addarray($1, 0, 0);
830 | type_direct_decl T_LBRACK constant T_RBRACK {
831 $$ = addarray($1, 1, toicon($3));
833 | type_direct_decl param_list {
834 $$ = addfunc($1, $2);
835 popdecl();
836 blklev--;
841 * param_decl and notype_param_decl exist to avoid a conflict in
842 * argument lists. A typename enclosed in parens should always be
843 * treated as a typename, not an argument.
844 * "typedef int a; f(int (a));" is "typedef int a; f(int foo(a));"
845 * not "typedef int a; f(int a);"
847 param_decl:
848 direct_param_decl {
849 $$ = $1;
851 | pointer direct_param_decl {
852 $$ = addptr($2, $1);
856 direct_param_decl:
857 identifier {
858 $$ = dname(getsym($1));
860 | T_LPARN notype_param_decl T_RPARN {
861 $$ = $2;
863 | direct_param_decl T_LBRACK T_RBRACK {
864 $$ = addarray($1, 0, 0);
866 | direct_param_decl T_LBRACK constant T_RBRACK {
867 $$ = addarray($1, 1, toicon($3));
869 | direct_param_decl param_list {
870 $$ = addfunc($1, $2);
871 popdecl();
872 blklev--;
876 notype_param_decl:
877 direct_notype_param_decl {
878 $$ = $1;
880 | pointer direct_notype_param_decl {
881 $$ = addptr($2, $1);
885 direct_notype_param_decl:
886 T_NAME {
887 $$ = dname(getsym($1));
889 | T_LPARN notype_param_decl T_RPARN {
890 $$ = $2;
892 | direct_notype_param_decl T_LBRACK T_RBRACK {
893 $$ = addarray($1, 0, 0);
895 | direct_notype_param_decl T_LBRACK constant T_RBRACK {
896 $$ = addarray($1, 1, toicon($3));
898 | direct_notype_param_decl param_list {
899 $$ = addfunc($1, $2);
900 popdecl();
901 blklev--;
905 pointer:
906 asterisk {
907 $$ = $1;
909 | asterisk type_qualifier_list {
910 $$ = mergepq($1, $2);
912 | asterisk pointer {
913 $$ = mergepq($1, $2);
915 | asterisk type_qualifier_list pointer {
916 $$ = mergepq(mergepq($1, $2), $3);
920 asterisk:
921 T_MULT {
922 $$ = xcalloc(1, sizeof (pqinf_t));
923 $$->p_pcnt = 1;
927 type_qualifier_list:
928 type_qualifier {
929 $$ = $1;
931 | type_qualifier_list type_qualifier {
932 $$ = mergepq($1, $2);
936 type_qualifier:
937 T_QUAL {
938 $$ = xcalloc(1, sizeof (pqinf_t));
939 if ($1 == CONST) {
940 $$->p_const = 1;
941 } else {
942 $$->p_volatile = 1;
947 param_list:
948 id_list_lparn identifier_list T_RPARN {
949 $$ = $2;
951 | abs_decl_param_list {
952 $$ = $1;
956 id_list_lparn:
957 T_LPARN {
958 blklev++;
959 pushdecl(PARG);
963 identifier_list:
964 T_NAME {
965 $$ = iname(getsym($1));
967 | identifier_list T_COMMA T_NAME {
968 $$ = lnklst($1, iname(getsym($3)));
970 | identifier_list error {
971 $$ = $1;
975 abs_decl_param_list:
976 abs_decl_lparn T_RPARN {
977 $$ = NULL;
979 | abs_decl_lparn vararg_parameter_type_list T_RPARN {
980 dcs->d_proto = 1;
981 $$ = $2;
983 | abs_decl_lparn error T_RPARN {
984 $$ = NULL;
988 abs_decl_lparn:
989 T_LPARN {
990 blklev++;
991 pushdecl(PARG);
995 vararg_parameter_type_list:
996 parameter_type_list {
997 $$ = $1;
999 | parameter_type_list T_COMMA T_ELLIPSE {
1000 dcs->d_vararg = 1;
1001 $$ = $1;
1003 | T_ELLIPSE {
1004 if (sflag) {
1005 /* ANSI C requires formal parameter before "..." */
1006 error(84);
1007 } else if (!tflag) {
1008 /* ANSI C requires formal parameter before "..." */
1009 warning(84);
1011 dcs->d_vararg = 1;
1012 $$ = NULL;
1016 parameter_type_list:
1017 parameter_declaration opt_asm_spec {
1018 $$ = $1;
1020 | parameter_type_list T_COMMA parameter_declaration opt_asm_spec {
1021 $$ = lnklst($1, $3);
1025 parameter_declaration:
1026 declmods deftyp {
1027 $$ = decl1arg(aname(), 0);
1029 | declspecs deftyp {
1030 $$ = decl1arg(aname(), 0);
1032 | declmods deftyp notype_param_decl {
1033 $$ = decl1arg($3, 0);
1036 * param_decl is needed because of following conflict:
1037 * "typedef int a; f(int (a));" could be parsed as
1038 * "function with argument a of type int", or
1039 * "function with an abstract argument of type function".
1040 * This grammar realizes the second case.
1042 | declspecs deftyp param_decl {
1043 $$ = decl1arg($3, 0);
1045 | declmods deftyp abs_decl {
1046 $$ = decl1arg($3, 0);
1048 | declspecs deftyp abs_decl {
1049 $$ = decl1arg($3, 0);
1053 opt_asm_spec:
1054 /* empty */
1055 | T_ASM T_LPARN T_STRING T_RPARN {
1056 freeyyv(&$3, T_STRING);
1060 initializer:
1061 init_expr
1064 init_expr:
1065 expr %prec T_COMMA {
1066 mkinit($1);
1068 | init_lbrace init_expr_list init_rbrace
1069 | init_lbrace init_expr_list T_COMMA init_rbrace
1070 | error
1073 init_expr_list:
1074 init_expr %prec T_COMMA
1075 | init_expr_list T_COMMA init_expr
1078 init_lbrace:
1079 T_LBRACE {
1080 initlbr();
1084 init_rbrace:
1085 T_RBRACE {
1086 initrbr();
1090 type_name:
1092 pushdecl(ABSTRACT);
1093 } abstract_declaration {
1094 popdecl();
1095 $$ = $2->s_type;
1099 abstract_declaration:
1100 noclass_declmods deftyp {
1101 $$ = decl1abs(aname());
1103 | noclass_declspecs deftyp {
1104 $$ = decl1abs(aname());
1106 | noclass_declmods deftyp abs_decl {
1107 $$ = decl1abs($3);
1109 | noclass_declspecs deftyp abs_decl {
1110 $$ = decl1abs($3);
1114 abs_decl:
1115 pointer {
1116 $$ = addptr(aname(), $1);
1118 | direct_abs_decl {
1119 $$ = $1;
1121 | pointer direct_abs_decl {
1122 $$ = addptr($2, $1);
1126 direct_abs_decl:
1127 T_LPARN abs_decl T_RPARN {
1128 $$ = $2;
1130 | T_LBRACK T_RBRACK {
1131 $$ = addarray(aname(), 0, 0);
1133 | T_LBRACK constant T_RBRACK {
1134 $$ = addarray(aname(), 1, toicon($2));
1136 | direct_abs_decl T_LBRACK T_RBRACK {
1137 $$ = addarray($1, 0, 0);
1139 | direct_abs_decl T_LBRACK constant T_RBRACK {
1140 $$ = addarray($1, 1, toicon($3));
1142 | abs_decl_param_list {
1143 $$ = addfunc(aname(), $1);
1144 popdecl();
1145 blklev--;
1147 | direct_abs_decl abs_decl_param_list {
1148 $$ = addfunc($1, $2);
1149 popdecl();
1150 blklev--;
1154 stmnt:
1155 labeled_stmnt
1156 | expr_stmnt
1157 | comp_stmnt
1158 | selection_stmnt
1159 | iteration_stmnt
1160 | jump_stmnt {
1161 ftflg = 0;
1163 | asm_stmnt
1166 labeled_stmnt:
1167 label stmnt
1170 label:
1171 identifier T_COLON {
1172 symtyp = FLAB;
1173 label(T_NAME, getsym($1), NULL);
1175 | T_CASE constant T_COLON {
1176 label(T_CASE, NULL, $2);
1177 ftflg = 1;
1179 | T_DEFAULT T_COLON {
1180 label(T_DEFAULT, NULL, NULL);
1181 ftflg = 1;
1185 comp_stmnt:
1186 compstmnt_lbrace declaration_list opt_stmnt_list compstmnt_rbrace
1187 | compstmnt_lbrace opt_stmnt_list compstmnt_rbrace
1190 compstmnt_lbrace:
1191 T_LBRACE {
1192 blklev++;
1193 mblklev++;
1194 pushdecl(AUTO);
1198 compstmnt_rbrace:
1199 T_RBRACE {
1200 popdecl();
1201 freeblk();
1202 mblklev--;
1203 blklev--;
1204 ftflg = 0;
1208 opt_stmnt_list:
1209 /* empty */
1210 | stmnt_list
1213 stmnt_list:
1214 stmnt {
1215 clrwflgs();
1217 | stmnt_list stmnt {
1218 clrwflgs();
1220 | stmnt_list error T_SEMI {
1221 clrwflgs();
1225 expr_stmnt:
1226 expr T_SEMI {
1227 expr($1, 0, 0);
1228 ftflg = 0;
1230 | T_SEMI {
1231 ftflg = 0;
1235 selection_stmnt:
1236 if_without_else {
1237 if2();
1238 if3(0);
1240 | if_without_else T_ELSE {
1241 if2();
1242 } stmnt {
1243 if3(1);
1245 | if_without_else T_ELSE error {
1246 if3(0);
1248 | switch_expr stmnt {
1249 switch2();
1251 | switch_expr error {
1252 switch2();
1256 if_without_else:
1257 if_expr stmnt
1258 | if_expr error
1261 if_expr:
1262 T_IF T_LPARN expr T_RPARN {
1263 if1($3);
1264 clrwflgs();
1268 switch_expr:
1269 T_SWITCH T_LPARN expr T_RPARN {
1270 switch1($3);
1271 clrwflgs();
1275 iteration_stmnt:
1276 while_expr stmnt {
1277 while2();
1279 | while_expr error {
1280 while2();
1282 | do stmnt do_while_expr {
1283 do2($3);
1284 ftflg = 0;
1286 | do error {
1287 do2(NULL);
1289 | for_exprs stmnt {
1290 for2();
1292 | for_exprs error {
1293 for2();
1297 while_expr:
1298 T_WHILE T_LPARN expr T_RPARN {
1299 while1($3);
1300 clrwflgs();
1305 T_DO {
1306 do1();
1310 do_while_expr:
1311 T_WHILE T_LPARN expr T_RPARN T_SEMI {
1312 $$ = $3;
1316 for_exprs:
1317 T_FOR T_LPARN opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPARN {
1318 for1($3, $5, $7);
1319 clrwflgs();
1323 opt_expr:
1324 /* empty */ {
1325 $$ = NULL;
1327 | expr {
1328 $$ = $1;
1332 jump_stmnt:
1333 goto identifier T_SEMI {
1334 dogoto(getsym($2));
1336 | goto error T_SEMI {
1337 symtyp = FVFT;
1339 | T_CONTINUE T_SEMI {
1340 docont();
1342 | T_BREAK T_SEMI {
1343 dobreak();
1345 | T_RETURN T_SEMI {
1346 doreturn(NULL);
1348 | T_RETURN expr T_SEMI {
1349 doreturn($2);
1353 goto:
1354 T_GOTO {
1355 symtyp = FLAB;
1359 asm_stmnt:
1360 T_ASM T_LPARN read_until_rparn T_SEMI {
1361 setasm();
1363 | T_ASM T_QUAL T_LPARN read_until_rparn T_SEMI {
1364 setasm();
1366 | T_ASM error
1369 read_until_rparn:
1370 /* empty */ {
1371 ignuptorp();
1375 declaration_list:
1376 declaration {
1377 clrwflgs();
1379 | declaration_list declaration {
1380 clrwflgs();
1384 constant:
1385 expr %prec T_COMMA {
1386 $$ = $1;
1390 expr:
1391 expr T_MULT expr {
1392 $$ = build(MULT, $1, $3);
1394 | expr T_DIVOP expr {
1395 $$ = build($2, $1, $3);
1397 | expr T_ADDOP expr {
1398 $$ = build($2, $1, $3);
1400 | expr T_SHFTOP expr {
1401 $$ = build($2, $1, $3);
1403 | expr T_RELOP expr {
1404 $$ = build($2, $1, $3);
1406 | expr T_EQOP expr {
1407 $$ = build($2, $1, $3);
1409 | expr T_AND expr {
1410 $$ = build(AND, $1, $3);
1412 | expr T_XOR expr {
1413 $$ = build(XOR, $1, $3);
1415 | expr T_OR expr {
1416 $$ = build(OR, $1, $3);
1418 | expr T_LOGAND expr {
1419 $$ = build(LOGAND, $1, $3);
1421 | expr T_LOGOR expr {
1422 $$ = build(LOGOR, $1, $3);
1424 | expr T_QUEST expr T_COLON expr {
1425 $$ = build(QUEST, $1, build(COLON, $3, $5));
1427 | expr T_ASSIGN expr {
1428 $$ = build(ASSIGN, $1, $3);
1430 | expr T_OPASS expr {
1431 $$ = build($2, $1, $3);
1433 | expr T_COMMA expr {
1434 $$ = build(COMMA, $1, $3);
1436 | term {
1437 $$ = $1;
1441 term:
1442 T_NAME {
1443 /* XXX realy neccessary? */
1444 if (yychar < 0)
1445 yychar = yylex();
1446 $$ = getnnode(getsym($1), yychar);
1448 | string {
1449 $$ = getsnode($1);
1451 | T_CON {
1452 $$ = getcnode(gettyp($1->v_tspec), $1);
1454 | T_LPARN expr T_RPARN {
1455 if ($2 != NULL)
1456 $2->tn_parn = 1;
1457 $$ = $2;
1459 | term T_INCDEC {
1460 $$ = build($2 == INC ? INCAFT : DECAFT, $1, NULL);
1462 | T_INCDEC term {
1463 $$ = build($1 == INC ? INCBEF : DECBEF, $2, NULL);
1465 | T_MULT term {
1466 $$ = build(STAR, $2, NULL);
1468 | T_AND term {
1469 $$ = build(AMPER, $2, NULL);
1471 | T_UNOP term {
1472 $$ = build($1, $2, NULL);
1474 | T_ADDOP term {
1475 if (tflag && $1 == PLUS) {
1476 /* unary + is illegal in traditional C */
1477 warning(100);
1479 $$ = build($1 == PLUS ? UPLUS : UMINUS, $2, NULL);
1481 | term T_LBRACK expr T_RBRACK {
1482 $$ = build(STAR, build(PLUS, $1, $3), NULL);
1484 | term T_LPARN T_RPARN {
1485 $$ = funccall($1, NULL);
1487 | term T_LPARN func_arg_list T_RPARN {
1488 $$ = funccall($1, $3);
1490 | term point_or_arrow T_NAME {
1491 if ($1 != NULL) {
1492 sym_t *msym;
1493 /* XXX strmemb should be integrated in build() */
1494 if ($2 == ARROW) {
1495 /* must to this before strmemb is called */
1496 $1 = cconv($1);
1498 msym = strmemb($1, $2, getsym($3));
1499 $$ = build($2, $1, getnnode(msym, 0));
1500 } else {
1501 $$ = NULL;
1504 | T_SIZEOF term %prec T_SIZEOF {
1505 if (($$ = $2 == NULL ? NULL : bldszof($2->tn_type)) != NULL)
1506 chkmisc($2, 0, 0, 0, 0, 0, 1);
1508 | T_SIZEOF T_LPARN type_name T_RPARN %prec T_SIZEOF {
1509 $$ = bldszof($3);
1511 | T_LPARN type_name T_RPARN term %prec T_UNOP {
1512 $$ = cast($4, $2);
1516 string:
1517 T_STRING {
1518 $$ = $1;
1520 | T_STRING string2 {
1521 $$ = catstrg($1, $2);
1525 string2:
1526 T_STRING {
1527 if (tflag) {
1528 /* concatenated strings are illegal in traditional C */
1529 warning(219);
1531 $$ = $1;
1533 | string2 T_STRING {
1534 $$ = catstrg($1, $2);
1538 func_arg_list:
1539 expr %prec T_COMMA {
1540 $$ = funcarg(NULL, $1);
1542 | func_arg_list T_COMMA expr {
1543 $$ = funcarg($1, $3);
1547 point_or_arrow:
1548 T_STROP {
1549 symtyp = FMOS;
1550 $$ = $1;
1554 identifier:
1555 T_NAME {
1556 $$ = $1;
1558 | T_TYPENAME {
1559 $$ = $1;
1565 /* ARGSUSED */
1567 yyerror(char *msg)
1569 error(249);
1570 if (++sytxerr >= 5)
1571 norecover();
1572 return (0);
1576 * Gets a node for a constant and returns the value of this constant
1577 * as integer.
1578 * Is the node not constant or too large for int or of type float,
1579 * a warning will be printed.
1581 * toicon() should be used only inside declarations. If it is used in
1582 * expressions, it frees the memory used for the expression.
1584 static int
1585 toicon(tnode_t *tn)
1587 int i;
1588 tspec_t t;
1589 val_t *v;
1591 v = constant(tn);
1594 * Abstract declarations are used inside expression. To free
1595 * the memory would be a fatal error.
1597 if (dcs->d_ctx != ABSTRACT)
1598 tfreeblk();
1600 if ((t = v->v_tspec) == FLOAT || t == DOUBLE || t == LDOUBLE) {
1601 i = (int)v->v_ldbl;
1602 /* integral constant expression expected */
1603 error(55);
1604 } else {
1605 i = (int)v->v_quad;
1606 if (isutyp(t)) {
1607 if ((u_quad_t)v->v_quad > INT_MAX) {
1608 /* integral constant too large */
1609 warning(56);
1611 } else {
1612 #ifdef XXX_BROKEN_GCC
1613 if (v->v_quad > INT_MAX) {
1614 /* integral constant too large */
1615 warning(56);
1617 else if (v->v_quad < INT_MIN) {
1618 /* integral constant too large */
1619 warning(56);
1621 #else
1622 if (v->v_quad > INT_MAX || v->v_quad < INT_MIN) {
1623 /* integral constant too large */
1624 warning(56);
1626 #endif
1629 free(v);
1630 return (i);
1633 static void
1634 idecl(sym_t *decl, int initflg)
1636 initerr = 0;
1637 initsym = decl;
1639 switch (dcs->d_ctx) {
1640 case EXTERN:
1641 decl1ext(decl, initflg);
1642 break;
1643 case ARG:
1644 (void)decl1arg(decl, initflg);
1645 break;
1646 case AUTO:
1647 decl1loc(decl, initflg);
1648 break;
1649 default:
1650 lerror("idecl()");
1653 if (initflg && !initerr)
1654 prepinit();
1658 * Discard all input tokens up to and including the next
1659 * unmatched right paren
1661 void
1662 ignuptorp(void)
1664 int level;
1666 if (yychar < 0)
1667 yychar = yylex();
1668 freeyyv(&yylval, yychar);
1670 level = 1;
1671 while (yychar != T_RPARN || --level > 0) {
1672 if (yychar == T_LPARN) {
1673 level++;
1674 } else if (yychar <= 0) {
1675 break;
1677 freeyyv(&yylval, yychar = yylex());
1680 yyclearin;