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