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