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