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