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