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