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