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