cgram.y revision 1.43 1 %{
2 /* $NetBSD: cgram.y,v 1.43 2009/05/01 22:03:36 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.43 2009/05/01 22:03:36 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 3
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 declspecs deftyp notype_init_decls T_SEMI opt_expr
1466 T_SEMI opt_expr T_RPARN {
1467 c99ism(325);
1468 for1(NULL, $7, $9);
1469 CLRWFLGS(__FILE__, __LINE__);
1470 }
1471 | T_FOR T_LPARN opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPARN {
1472 for1($3, $5, $7);
1473 CLRWFLGS(__FILE__, __LINE__);
1474 }
1475 ;
1476
1477 opt_expr:
1478 /* empty */ {
1479 $$ = NULL;
1480 }
1481 | expr {
1482 $$ = $1;
1483 }
1484 ;
1485
1486 jump_stmnt:
1487 goto identifier T_SEMI {
1488 dogoto(getsym($2));
1489 }
1490 | goto error T_SEMI {
1491 symtyp = FVFT;
1492 }
1493 | T_CONTINUE T_SEMI {
1494 docont();
1495 }
1496 | T_BREAK T_SEMI {
1497 dobreak();
1498 }
1499 | T_RETURN T_SEMI {
1500 doreturn(NULL);
1501 }
1502 | T_RETURN expr T_SEMI {
1503 doreturn($2);
1504 }
1505 ;
1506
1507 goto:
1508 T_GOTO {
1509 symtyp = FLAB;
1510 }
1511 ;
1512
1513 asm_stmnt:
1514 T_ASM T_LPARN read_until_rparn T_SEMI {
1515 setasm();
1516 }
1517 | T_ASM T_QUAL T_LPARN read_until_rparn T_SEMI {
1518 setasm();
1519 }
1520 | T_ASM error
1521 ;
1522
1523 read_until_rparn:
1524 /* empty */ {
1525 ignuptorp();
1526 }
1527 ;
1528
1529 declaration_list:
1530 declaration {
1531 CLRWFLGS(__FILE__, __LINE__);
1532 }
1533 | declaration_list declaration {
1534 CLRWFLGS(__FILE__, __LINE__);
1535 }
1536 ;
1537
1538 constant:
1539 expr %prec T_COMMA {
1540 $$ = $1;
1541 }
1542 ;
1543
1544 expr:
1545 expr T_MULT expr {
1546 $$ = build(MULT, $1, $3);
1547 }
1548 | expr T_DIVOP expr {
1549 $$ = build($2, $1, $3);
1550 }
1551 | expr T_ADDOP expr {
1552 $$ = build($2, $1, $3);
1553 }
1554 | expr T_SHFTOP expr {
1555 $$ = build($2, $1, $3);
1556 }
1557 | expr T_RELOP expr {
1558 $$ = build($2, $1, $3);
1559 }
1560 | expr T_EQOP expr {
1561 $$ = build($2, $1, $3);
1562 }
1563 | expr T_AND expr {
1564 $$ = build(AND, $1, $3);
1565 }
1566 | expr T_XOR expr {
1567 $$ = build(XOR, $1, $3);
1568 }
1569 | expr T_OR expr {
1570 $$ = build(OR, $1, $3);
1571 }
1572 | expr T_LOGAND expr {
1573 $$ = build(LOGAND, $1, $3);
1574 }
1575 | expr T_LOGOR expr {
1576 $$ = build(LOGOR, $1, $3);
1577 }
1578 | expr T_QUEST expr T_COLON expr {
1579 $$ = build(QUEST, $1, build(COLON, $3, $5));
1580 }
1581 | expr T_ASSIGN expr {
1582 $$ = build(ASSIGN, $1, $3);
1583 }
1584 | expr T_OPASS expr {
1585 $$ = build($2, $1, $3);
1586 }
1587 | expr T_COMMA expr {
1588 $$ = build(COMMA, $1, $3);
1589 }
1590 | term {
1591 $$ = $1;
1592 }
1593 ;
1594
1595 term:
1596 T_NAME {
1597 /* XXX really necessary? */
1598 if (yychar < 0)
1599 yychar = yylex();
1600 $$ = getnnode(getsym($1), yychar);
1601 }
1602 | string {
1603 $$ = getsnode($1);
1604 }
1605 | T_CON {
1606 $$ = getcnode(gettyp($1->v_tspec), $1);
1607 }
1608 | T_LPARN expr T_RPARN {
1609 if ($2 != NULL)
1610 $2->tn_parn = 1;
1611 $$ = $2;
1612 }
1613 | T_LPARN comp_stmnt_lbrace declaration_list expr_stmnt_list {
1614 blklev--;
1615 mblklev--;
1616 initsym = mktempsym(duptyp($4->tn_type));
1617 mblklev++;
1618 blklev++;
1619 gnuism(320);
1620 } comp_stmnt_rbrace T_RPARN {
1621 $$ = getnnode(initsym, 0);
1622 }
1623 | T_LPARN comp_stmnt_lbrace expr_stmnt_list {
1624 blklev--;
1625 mblklev--;
1626 initsym = mktempsym($3->tn_type);
1627 mblklev++;
1628 blklev++;
1629 gnuism(320);
1630 } comp_stmnt_rbrace T_RPARN {
1631 $$ = getnnode(initsym, 0);
1632 }
1633 | term T_INCDEC {
1634 $$ = build($2 == INC ? INCAFT : DECAFT, $1, NULL);
1635 }
1636 | T_INCDEC term {
1637 $$ = build($1 == INC ? INCBEF : DECBEF, $2, NULL);
1638 }
1639 | T_MULT term {
1640 $$ = build(STAR, $2, NULL);
1641 }
1642 | T_AND term {
1643 $$ = build(AMPER, $2, NULL);
1644 }
1645 | T_UNOP term {
1646 $$ = build($1, $2, NULL);
1647 }
1648 | T_ADDOP term {
1649 if (tflag && $1 == PLUS) {
1650 /* unary + is illegal in traditional C */
1651 warning(100);
1652 }
1653 $$ = build($1 == PLUS ? UPLUS : UMINUS, $2, NULL);
1654 }
1655 | term T_LBRACK expr T_RBRACK {
1656 $$ = build(STAR, build(PLUS, $1, $3), NULL);
1657 }
1658 | term T_LPARN T_RPARN {
1659 $$ = funccall($1, NULL);
1660 }
1661 | term T_LPARN func_arg_list T_RPARN {
1662 $$ = funccall($1, $3);
1663 }
1664 | term point_or_arrow T_NAME {
1665 if ($1 != NULL) {
1666 sym_t *msym;
1667 /* XXX strmemb should be integrated in build() */
1668 if ($2 == ARROW) {
1669 /* must to this before strmemb is called */
1670 $1 = cconv($1);
1671 }
1672 msym = strmemb($1, $2, getsym($3));
1673 $$ = build($2, $1, getnnode(msym, 0));
1674 } else {
1675 $$ = NULL;
1676 }
1677 }
1678 | T_REAL term {
1679 $$ = build(REAL, $2, NULL);
1680 }
1681 | T_IMAG term {
1682 $$ = build(IMAG, $2, NULL);
1683 }
1684 | T_REAL T_LPARN term T_RPARN {
1685 $$ = build(REAL, $3, NULL);
1686 }
1687 | T_IMAG T_LPARN term T_RPARN {
1688 $$ = build(IMAG, $3, NULL);
1689 }
1690 | T_SIZEOF term %prec T_SIZEOF {
1691 if (($$ = $2 == NULL ? NULL : bldszof($2->tn_type)) != NULL)
1692 chkmisc($2, 0, 0, 0, 0, 0, 1);
1693 }
1694 | T_SIZEOF T_LPARN type_name T_RPARN %prec T_SIZEOF {
1695 $$ = bldszof($3);
1696 }
1697 | T_LPARN type_name T_RPARN term %prec T_UNOP {
1698 $$ = cast($4, $2);
1699 }
1700 | T_LPARN type_name T_RPARN %prec T_UNOP {
1701 sym_t *tmp = mktempsym($2);
1702 idecl(tmp, 1, NULL);
1703 } init_lbrace init_expr_list init_rbrace {
1704 if (!Sflag)
1705 gnuism(319);
1706 $$ = getnnode(initsym, 0);
1707 }
1708 ;
1709
1710 string:
1711 T_STRING {
1712 $$ = $1;
1713 }
1714 | T_STRING string2 {
1715 $$ = catstrg($1, $2);
1716 }
1717 ;
1718
1719 string2:
1720 T_STRING {
1721 if (tflag) {
1722 /* concatenated strings are illegal in traditional C */
1723 warning(219);
1724 }
1725 $$ = $1;
1726 }
1727 | string2 T_STRING {
1728 $$ = catstrg($1, $2);
1729 }
1730 ;
1731
1732 func_arg_list:
1733 expr %prec T_COMMA {
1734 $$ = funcarg(NULL, $1);
1735 }
1736 | func_arg_list T_COMMA expr {
1737 $$ = funcarg($1, $3);
1738 }
1739 ;
1740
1741 point_or_arrow:
1742 T_STROP {
1743 symtyp = FMOS;
1744 $$ = $1;
1745 }
1746 ;
1747
1748 point:
1749 T_STROP {
1750 if ($1 != POINT)
1751 error(249, yytext);
1752 }
1753 ;
1754
1755 identifier:
1756 T_NAME {
1757 $$ = $1;
1758 }
1759 | T_TYPENAME {
1760 $$ = $1;
1761 }
1762 ;
1763
1764 %%
1765
1766 /* ARGSUSED */
1767 int
1768 yyerror(const char *msg)
1769 {
1770 error(249, yytext);
1771 if (++sytxerr >= 5)
1772 norecover();
1773 return (0);
1774 }
1775
1776 static __inline int uq_gt(uint64_t, uint64_t);
1777 static __inline int q_gt(int64_t, int64_t);
1778
1779 static __inline int
1780 uq_gt(uint64_t a, uint64_t b)
1781 {
1782
1783 return (a > b);
1784 }
1785
1786 static __inline int
1787 q_gt(int64_t a, int64_t b)
1788 {
1789
1790 return (a > b);
1791 }
1792
1793 #define q_lt(a, b) q_gt(b, a)
1794
1795 /*
1796 * Gets a node for a constant and returns the value of this constant
1797 * as integer.
1798 * Is the node not constant or too large for int or of type float,
1799 * a warning will be printed.
1800 *
1801 * toicon() should be used only inside declarations. If it is used in
1802 * expressions, it frees the memory used for the expression.
1803 */
1804 static int
1805 toicon(tnode_t *tn, int required)
1806 {
1807 int i;
1808 tspec_t t;
1809 val_t *v;
1810
1811 v = constant(tn, required);
1812
1813 /*
1814 * Abstract declarations are used inside expression. To free
1815 * the memory would be a fatal error.
1816 */
1817 if (dcs->d_ctx != ABSTRACT)
1818 tfreeblk();
1819
1820 if ((t = v->v_tspec) == FLOAT || t == DOUBLE || t == LDOUBLE) {
1821 i = (int)v->v_ldbl;
1822 /* integral constant expression expected */
1823 error(55);
1824 } else {
1825 i = (int)v->v_quad;
1826 if (isutyp(t)) {
1827 if (uq_gt((uint64_t)v->v_quad,
1828 (uint64_t)INT_MAX)) {
1829 /* integral constant too large */
1830 warning(56);
1831 }
1832 } else {
1833 if (q_gt(v->v_quad, (int64_t)INT_MAX) ||
1834 q_lt(v->v_quad, (int64_t)INT_MIN)) {
1835 /* integral constant too large */
1836 warning(56);
1837 }
1838 }
1839 }
1840 free(v);
1841 return (i);
1842 }
1843
1844 static void
1845 idecl(sym_t *decl, int initflg, sbuf_t *renaming)
1846 {
1847 char *s;
1848
1849 initerr = 0;
1850 initsym = decl;
1851
1852 switch (dcs->d_ctx) {
1853 case EXTERN:
1854 if (renaming != NULL) {
1855 if (decl->s_rename != NULL)
1856 LERROR("idecl()");
1857
1858 s = getlblk(1, renaming->sb_len + 1);
1859 (void)memcpy(s, renaming->sb_name, renaming->sb_len + 1);
1860 decl->s_rename = s;
1861 freeyyv(&renaming, T_NAME);
1862 }
1863 decl1ext(decl, initflg);
1864 break;
1865 case ARG:
1866 if (renaming != NULL) {
1867 /* symbol renaming can't be used on function arguments */
1868 error(310);
1869 freeyyv(&renaming, T_NAME);
1870 break;
1871 }
1872 (void)decl1arg(decl, initflg);
1873 break;
1874 case AUTO:
1875 if (renaming != NULL) {
1876 /* symbol renaming can't be used on automatic variables */
1877 error(311);
1878 freeyyv(&renaming, T_NAME);
1879 break;
1880 }
1881 decl1loc(decl, initflg);
1882 break;
1883 default:
1884 LERROR("idecl()");
1885 }
1886
1887 if (initflg && !initerr)
1888 prepinit();
1889 }
1890
1891 /*
1892 * Discard all input tokens up to and including the next
1893 * unmatched right paren
1894 */
1895 static void
1896 ignuptorp(void)
1897 {
1898 int level;
1899
1900 if (yychar < 0)
1901 yychar = yylex();
1902 freeyyv(&yylval, yychar);
1903
1904 level = 1;
1905 while (yychar != T_RPARN || --level > 0) {
1906 if (yychar == T_LPARN) {
1907 level++;
1908 } else if (yychar <= 0) {
1909 break;
1910 }
1911 freeyyv(&yylval, yychar = yylex());
1912 }
1913
1914 yyclearin;
1915 }
1916