1/* Id: cgram.y,v 1.2 2012/01/04 19:04:08 ragge Exp */ 2/* $NetBSD: cgram.y,v 1.1.1.1 2012/01/11 20:33:17 plunky Exp $ */ 3 4/* 5 * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se). 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29/* 30 * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. 31 * 32 * Redistribution and use in source and binary forms, with or without 33 * modification, are permitted provided that the following conditions 34 * are met: 35 * 36 * Redistributions of source code and documentation must retain the above 37 * copyright notice, this list of conditions and the following disclaimer. 38 * Redistributions in binary form must reproduce the above copyright 39 * notice, this list of conditions and the following disclaimer in the 40 * documentation and/or other materials provided with the distribution. 41 * All advertising materials mentioning features or use of this software 42 * must display the following acknowledgement: 43 * This product includes software developed or owned by Caldera 44 * International, Inc. 45 * Neither the name of Caldera International, Inc. nor the names of other 46 * contributors may be used to endorse or promote products derived from 47 * this software without specific prior written permission. 48 * 49 * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA 50 * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR 51 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 52 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 53 * DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE 54 * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 55 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 56 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 57 * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT, 58 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 59 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 60 * POSSIBILITY OF SUCH DAMAGE. 61 */ 62 63/* 64 * Comments for this grammar file. Ragge 021123 65 * 66 * ANSI support required rewrite of the function header and declaration 67 * rules almost totally. 68 * 69 * The lex/yacc shared keywords are now split from the keywords used 70 * in the rest of the compiler, to simplify use of other frontends. 71 */ 72 73/* 74 * At last count, there were 5 shift/reduce and no reduce/reduce conflicts 75 * Four are accounted for; 76 * One is "dangling else" 77 * Two is in attribute parsing 78 * One is in ({ }) parsing 79 */ 80 81/* 82 * Token used in C lex/yacc communications. 83 */ 84%token C_STRING /* a string constant */ 85%token C_ICON /* an integer constant */ 86%token C_FCON /* a floating point constant */ 87%token C_NAME /* an identifier */ 88%token C_TYPENAME /* a typedef'd name */ 89%token C_ANDAND /* && */ 90%token C_OROR /* || */ 91%token C_GOTO /* unconditional goto */ 92%token C_RETURN /* return from function */ 93%token C_TYPE /* a type */ 94%token C_CLASS /* a storage class */ 95%token C_ASOP /* assignment ops */ 96%token C_RELOP /* <=, <, >=, > */ 97%token C_EQUOP /* ==, != */ 98%token C_DIVOP /* /, % */ 99%token C_SHIFTOP /* <<, >> */ 100%token C_INCOP /* ++, -- */ 101%token C_UNOP /* !, ~ */ 102%token C_STROP /* ., -> */ 103%token C_STRUCT 104%token C_IF 105%token C_ELSE 106%token C_SWITCH 107%token C_BREAK 108%token C_CONTINUE 109%token C_WHILE 110%token C_DO 111%token C_FOR 112%token C_DEFAULT 113%token C_CASE 114%token C_SIZEOF 115%token C_ALIGNOF 116%token C_ENUM 117%token C_ELLIPSIS 118%token C_QUALIFIER 119%token C_FUNSPEC 120%token C_ASM 121%token NOMATCH 122%token C_TYPEOF /* COMPAT_GCC */ 123%token C_ATTRIBUTE /* COMPAT_GCC */ 124%token PCC_OFFSETOF 125%token GCC_DESIG 126%token CXX_NAMESPACE 127%token CXX_DUALCC 128%token CXX_TEMPLATE 129%token CXX_USING 130%token CXX_TYPENAME 131%token CXX_CASTS 132%token CXX_THROW 133%token CXX_MORENM 134%token CXX_NEW 135%token CXX_DELETE 136%token CXX_CLASS 137 138/* 139 * Precedence 140 */ 141%left ',' 142%right '=' C_ASOP 143%right '?' ':' 144%left C_OROR 145%left C_ANDAND 146%left '|' 147%left '^' 148%left '&' 149%left C_EQUOP 150%left C_RELOP 151%left C_SHIFTOP 152%left '+' '-' 153%left '*' C_DIVOP 154%right C_UNOP 155%right C_INCOP C_SIZEOF 156%left '[' '(' C_STROP 157%{ 158# include "pass1.h" 159# include <stdarg.h> 160# include <string.h> 161# include <stdlib.h> 162 163int fun_inline; /* Reading an inline function */ 164int oldstyle; /* Current function being defined */ 165static struct symtab *xnf; 166extern int enummer, tvaloff, inattr; 167extern struct rstack *rpole; 168static int widestr, alwinl; 169NODE *cftnod; 170static int attrwarn = 1; 171 172#define NORETYP SNOCREAT /* no return type, save in unused field in symtab */ 173 174 NODE *bdty(int op, ...); 175static void fend(struct symtab *); 176static struct symtab *fundef(NODE *tp, NODE *p); 177static void olddecl(NODE *p, NODE *a); 178static struct symtab *init_declarator(NODE *tn, NODE *p, int assign, NODE *a); 179static void resetbc(int mask); 180static void swend(void); 181static void addcase(NODE *p); 182#ifdef GCC_COMPAT 183static void gcccase(NODE *p, NODE *); 184#endif 185static void adddef(void); 186static void savebc(void); 187static void swstart(int, TWORD); 188static void genswitch(int, TWORD, struct swents **, int); 189static char *mkpstr(char *str); 190static struct symtab *clbrace(NODE *); 191static NODE *cmop(NODE *l, NODE *r); 192static NODE *xcmop(NODE *out, NODE *in, NODE *str); 193static void mkxasm(char *str, NODE *p); 194static NODE *xasmop(char *str, NODE *p); 195static int maxstlen(char *str); 196static char *stradd(char *old, char *new); 197static NODE *biop(int op, NODE *l, NODE *r); 198static void flend(void); 199static char * simname(char *s); 200#ifdef GCC_COMPAT 201static NODE *tyof(NODE *); /* COMPAT_GCC */ 202static NODE *voidcon(void); /* COMPAT_GCC */ 203#endif 204static NODE *funargs(NODE *p); 205static void oldargs(NODE *p); 206static void uawarn(NODE *p, char *s); 207static int con_e(NODE *p); 208static void dainit(NODE *d, NODE *a); 209static NODE *tymfix(NODE *p); 210static NODE *namekill(NODE *p, int clr); 211static NODE *aryfix(NODE *p); 212 213#define TYMFIX(inp) { \ 214 NODE *pp = inp; \ 215 inp = tymerge(pp->n_left, pp->n_right); \ 216 nfree(pp->n_left); nfree(pp); } 217/* 218 * State for saving current switch state (when nested switches). 219 */ 220struct savbc { 221 struct savbc *next; 222 int brklab; 223 int contlab; 224 int flostat; 225 int swx; 226} *savbc, *savctx; 227 228%} 229 230%union { 231 int intval; 232 NODE *nodep; 233 struct symtab *symp; 234 struct rstack *rp; 235 char *strp; 236} 237 238 /* define types */ 239%start edf 240 241%type <intval> ifelprefix ifprefix whprefix forprefix doprefix switchpart 242 xbegin 243%type <nodep> e .e term enum_dcl struct_dcl cast_type declarator 244 elist type_sq cf_spec merge_attribs 245 parameter_declaration abstract_declarator initializer 246 parameter_type_list parameter_list addrlbl 247 declaration_specifiers designation 248 specifier_qualifier_list merge_specifiers 249 identifier_list arg_param_list type_qualifier_list 250 designator_list designator xasm oplist oper cnstr 251 typeof attribute attribute_specifier /* COMPAT_GCC */ 252 attribute_list attr_spec_list attr_var /* COMPAT_GCC */ 253 new_ma new_type_sq new_ds nmrec 254%type <strp> string C_STRING GCC_DESIG nsname CXX_MORENM 255%type <rp> str_head 256%type <symp> xnfdeclarator clbrace enum_head funtype 257 258%type <intval> C_STRUCT C_RELOP C_DIVOP C_SHIFTOP 259 C_ANDAND C_OROR C_STROP C_INCOP C_UNOP C_ASOP C_EQUOP 260 261%type <nodep> C_TYPE C_QUALIFIER C_ICON C_FCON C_CLASS 262%type <strp> C_NAME C_TYPENAME 263%% 264 265edf: ext_def_list 266 | { ftnend(); } 267 ; 268 269ext_def_list: ext_def_list external_def 270 | external_def 271 ; 272 273external_def: funtype kr_args compoundstmt { fend($1); } 274 | declaration { blevel = 0; symclear(0); } 275 | namespace 276 | extlink 277 | blockdcl 278 | ';' 279 | error { blevel = 0; } 280 ; 281 282funtype: /* no type given */ declarator { 283 $$ = fundef(mkty(INT, 0, 0), $1); 284 cftnsp->sflags |= NORETYP; 285 } 286 | declaration_specifiers declarator { $$ = fundef($1,$2); } 287 ; 288 289kr_args: /* empty */ 290 | arg_dcl_list 291 ; 292 293blockdcl: simple_decl 294 | asmstatement 295 | ns_alias 296 | using_x 297 ; 298 299using_x: CXX_USING tnopt ccopt nested_name_sp ';' { werror("using"); } 300 | CXX_USING CXX_NAMESPACE ccopt nested_name_sp ';' { werror("using2"); } 301 ; 302 303tnopt: CXX_TYPENAME { } 304 | { } 305 ; 306 307ns_alias: CXX_NAMESPACE C_NAME '=' qual_ns_sp ';' { werror("ns_alias");} 308 ; 309 310qual_ns_sp: ccopt nested_name_sp 311 ; 312 313nested_name_sp: nmtnm 314 | nmtnm CXX_DUALCC nested_name_sp 315 | nmtnm CXX_DUALCC CXX_TEMPLATE nested_name_sp 316 ; 317 318nmtnm: C_NAME 319 | C_TYPENAME 320 ; 321 322ccopt: CXX_DUALCC 323 | { } 324 ; 325 326simple_decl: ')' NOMATCH { uerror("simple-declaration"); } 327 ; 328 329namespace: CXX_NAMESPACE nsname attr_var nsbeg ns_body '}' { POPSYM(); } 330 ; 331 332nsname: C_NAME 333 | { $$ = NULL; } 334 ; 335 336ns_body: ext_def_list 337 | { } 338 ; 339 340nsbeg: '{' { dclns($<nodep>0, $<strp>-1); } 341 ; 342 343extlink: C_CLASS C_STRING eb '{' ext_def_list '}' { elnk = LINK_DEF; } 344 | C_CLASS C_STRING eb '{' '}' { elnk = LINK_DEF; } 345 | C_CLASS C_STRING eb declaration { elnk = LINK_DEF; } 346 ; 347 348eb: { 349 NODE *p = $<nodep>-1; 350 char *s = $<strp>0; 351 if (p->n_type != EXTERN) 352 uerror("'extern' expected"); 353 if (strcmp(s, "\"C\"") != 0 && strcmp(s, "\"c\"")) 354 uerror("unknown linkage %s", s); 355 nfree(p); 356 elnk = LINK_C; 357 } 358 ; 359/* 360 * Returns a node pointer or NULL, if no types at all given. 361 * Type trees are checked for correctness and merged into one 362 * type node in typenode(). 363 */ 364declaration_specifiers: 365 merge_attribs { $$ = typenode($1); } 366 ; 367 368merge_attribs: type_sq { $$ = $1; } 369 | type_sq merge_attribs { $$ = cmop($2, $1); } 370 | cf_spec { $$ = $1; } 371 | cf_spec merge_attribs { $$ = cmop($2, $1); } 372 ; 373 374type_sq: C_TYPE { $$ = $1; } 375 | C_TYPENAME { 376 struct symtab *sp = lookup($1, 0); 377 if (sp->stype == ENUMTY) { 378 sp->stype = strmemb(sp->sap)->stype; 379 } 380 $$ = mkty(sp->stype, sp->sdf, sp->sap); 381 $$->n_sp = sp; 382 } 383 | struct_dcl { $$ = $1; } 384 | enum_dcl { $$ = $1; } 385 | C_QUALIFIER { $$ = $1; } 386 | attribute_specifier { $$ = biop(ATTRIB, $1, 0); } 387 | typeof { $$ = $1; } 388 ; 389 390cf_spec: C_CLASS { $$ = $1; } 391 | C_FUNSPEC { fun_inline = 1; /* XXX - hack */ 392 $$ = block(QUALIFIER, NIL, NIL, 0, 0, 0); } 393 ; 394 395typeof: C_TYPEOF '(' e ')' { $$ = tyof(eve($3)); } 396 | C_TYPEOF '(' cast_type ')' { TYMFIX($3); $$ = tyof($3); } 397 ; 398 399new_ma: new_type_sq 400 | new_type_sq new_ma { $$ = cmop($2, $1); } 401 | cf_spec { $$ = $1; } 402 | cf_spec new_ma { $$ = cmop($2, $1); } 403 ; 404 405new_ds: new_ma { $$ = typenode($1); } 406 ; 407 408new_type_sq: C_TYPE { $$ = $1; } 409 | C_TYPENAME { 410 struct symtab *sp = lookup($1, 0); 411 if (sp->stype == ENUMTY) { 412 sp->stype = strmemb(sp->sap)->stype; 413 } 414 $$ = mkty(sp->stype, sp->sdf, sp->sap); 415 $$->n_sp = sp; 416 } 417 | struct_dcl { $$ = $1; } 418 | enum_dcl { $$ = $1; } 419 | C_QUALIFIER { $$ = $1; } 420 ; 421 422attribute_specifier : 423 C_ATTRIBUTE '(' '(' attribute_list ')' ')' { $$ = $4; } 424 /*COMPAT_GCC*/ ; 425 426attribute_list: attribute 427 | attribute ',' attribute_list { $$ = cmop($3, $1); } 428 ; 429 430attribute: { 431#ifdef GCC_COMPAT 432 $$ = voidcon(); 433#endif 434 } 435 | C_NAME { $$ = bdty(NAME, $1); } 436 | C_NAME '(' elist ')' { 437 $$ = bdty($3 == NIL ? UCALL : CALL, bdty(NAME, $1), $3); 438 } 439 ; 440 441/* 442 * Adds a pointer list to front of the declarators. 443 */ 444declarator: '*' declarator { $$ = bdty(UMUL, $2); } 445 | '*' type_qualifier_list declarator { 446 $$ = $2; 447 $$->n_left = $3; 448 } 449 | nmrec C_NAME { $$ = biop(NMLIST, $1, bdty(NAME, $2)); } 450 | C_NAME { $$ = bdty(NAME, $1); } 451 | '(' attr_spec_list declarator ')' { 452 $$ = $3; 453 $$->n_ap = attr_add($$->n_ap, gcc_attr_parse($2)); 454 } 455 | '(' declarator ')' { $$ = $2; } 456 | declarator '[' e ']' { $$ = biop(LB, $1, $3); } 457 | declarator '[' C_CLASS e ']' { 458 if ($3->n_type != STATIC) 459 uerror("bad class keyword"); 460 tfree($3); /* XXX - handle */ 461 $$ = biop(LB, $1, $4); 462 } 463 | declarator '[' ']' { $$ = biop(LB, $1, bcon(NOOFFSET)); } 464 | declarator '[' '*' ']' { $$ = biop(LB, $1, bcon(NOOFFSET)); } 465 | declarator '(' parameter_type_list ')' { 466 $$ = bdty(CALL, $1, $3); 467 } 468 | declarator '(' identifier_list ')' { 469 $$ = bdty(CALL, $1, $3); 470 oldstyle = 1; 471 } 472 | declarator '(' ')' { $$ = bdty(UCALL, $1); } 473 ; 474 475type_qualifier_list: 476 C_QUALIFIER { $$ = $1; $$->n_op = UMUL; } 477 | type_qualifier_list C_QUALIFIER { 478 $$ = $1; 479 $$->n_qual |= $2->n_qual; 480 nfree($2); 481 } 482 | attribute_specifier { 483 $$ = block(UMUL, NIL, NIL, 0, 0, gcc_attr_parse($1)); 484 } 485 | type_qualifier_list attribute_specifier { 486 $1->n_ap = attr_add($1->n_ap, gcc_attr_parse($2)); 487 } 488 ; 489 490identifier_list: C_NAME { $$ = bdty(NAME, $1); oldargs($$); } 491 | identifier_list ',' C_NAME { 492 $$ = cmop($1, bdty(NAME, $3)); 493 oldargs($$->n_right); 494 } 495 ; 496 497/* 498 * Returns as parameter_list, but can add an additional ELLIPSIS node. 499 */ 500parameter_type_list: 501 parameter_list { $$ = $1; } 502 | parameter_list ',' C_ELLIPSIS { 503 $$ = cmop($1, biop(ELLIPSIS, NIL, NIL)); 504 } 505 ; 506 507/* 508 * Returns a linked lists of nodes of op CM with parameters on 509 * its right and additional CM nodes of its left pointer. 510 * No CM nodes if only one parameter. 511 */ 512parameter_list: parameter_declaration { $$ = $1; } 513 | parameter_declaration '&' { $$ = $1; } 514 | parameter_list ',' parameter_declaration { 515 $$ = cmop($1, $3); 516 } 517 ; 518 519/* 520 * Returns a node pointer to the declaration. 521 */ 522parameter_declaration: 523 declaration_specifiers declarator attr_var { 524 if ($1->n_lval != SNULL && $1->n_lval != REGISTER) 525 uerror("illegal parameter class"); 526 $$ = block(TYMERGE, $1, $2, INT, 0, gcc_attr_parse($3)); 527 } 528 | declaration_specifiers abstract_declarator { 529 $$ = block(TYMERGE, $1, $2, INT, 0, 0); 530 } 531 | declaration_specifiers { 532 $$ = block(TYMERGE, $1, bdty(NAME, NULL), INT, 0, 0); 533 } 534 ; 535 536abstract_declarator: 537 '*' { $$ = bdty(UMUL, bdty(NAME, NULL)); } 538 | '*' type_qualifier_list { 539 $$ = $2; 540 $$->n_left = bdty(NAME, NULL); 541 } 542 | '*' abstract_declarator { $$ = bdty(UMUL, $2); } 543 | '*' type_qualifier_list abstract_declarator { 544 $$ = $2; 545 $$->n_left = $3; 546 } 547 | '(' abstract_declarator ')' { $$ = $2; } 548 | '[' ']' attr_var { 549 $$ = block(LB, bdty(NAME, NULL), bcon(NOOFFSET), 550 INT, 0, gcc_attr_parse($3)); 551 } 552 | '[' e ']' attr_var { 553 $$ = block(LB, bdty(NAME, NULL), $2, 554 INT, 0, gcc_attr_parse($4)); 555 } 556 | abstract_declarator '[' ']' attr_var { 557 $$ = block(LB, $1, bcon(NOOFFSET), 558 INT, 0, gcc_attr_parse($4)); 559 } 560 | abstract_declarator '[' e ']' attr_var { 561 $$ = block(LB, $1, $3, INT, 0, gcc_attr_parse($5)); 562 } 563 | '(' ')' { $$ = bdty(UCALL, bdty(NAME, NULL)); } 564 | '(' ib2 parameter_type_list ')' { 565 $$ = bdty(CALL, bdty(NAME, NULL), $3); 566 } 567 | abstract_declarator '(' ')' { 568 $$ = bdty(UCALL, $1); 569 } 570 | abstract_declarator '(' ib2 parameter_type_list ')' { 571 $$ = bdty(CALL, $1, $4); 572 } 573 ; 574 575ib2: { } 576 ; 577/* 578 * K&R arg declaration, between ) and { 579 */ 580arg_dcl_list: arg_declaration 581 | arg_dcl_list arg_declaration 582 ; 583 584 585arg_declaration: declaration_specifiers arg_param_list ';' { 586 nfree($1); 587 } 588 ; 589 590arg_param_list: declarator attr_var { 591 olddecl(block(TYMERGE, ccopy($<nodep>0), $1, 592 INT, 0, 0), $2); 593 } 594 | arg_param_list ',' declarator attr_var { 595 olddecl(block(TYMERGE, ccopy($<nodep>0), $3, 596 INT, 0, 0), $4); 597 } 598 ; 599 600/* 601 * Declarations in beginning of blocks. 602 */ 603block_item_list: block_item 604 | block_item_list block_item 605 ; 606 607block_item: declaration 608 | statement 609 ; 610 611/* 612 * Here starts the old YACC code. 613 */ 614 615/* 616 * Variables are declared in init_declarator. 617 */ 618declaration: declaration_specifiers ';' { tfree($1); fun_inline = 0; } 619 | declaration_specifiers init_declarator_list ';' { 620 tfree($1); 621 fun_inline = 0; 622 } 623 ; 624 625/* 626 * Normal declaration of variables. curtype contains the current type node. 627 * Returns nothing, variables are declared in init_declarator. 628 */ 629init_declarator_list: 630 init_declarator { symclear(blevel); } 631 | init_declarator_list ',' attr_var { $<nodep>$ = $<nodep>0; } init_declarator { 632 uawarn($3, "init_declarator"); 633 symclear(blevel); 634 } 635 ; 636 637enum_dcl: enum_head '{' moe_list optcomma '}' { $$ = enumdcl($1); } 638 | C_ENUM C_NAME { $$ = enumref($2); } 639 ; 640 641enum_head: C_ENUM { $$ = enumhd(NULL); } 642 | C_ENUM C_NAME { $$ = enumhd($2); } 643 ; 644 645moe_list: moe 646 | moe_list ',' moe 647 ; 648 649moe: C_NAME { moedef($1); } 650 | C_TYPENAME { moedef($1); } 651 | C_NAME '=' e { enummer = con_e($3); moedef($1); } 652 | C_TYPENAME '=' e { enummer = con_e($3); moedef($1); } 653 ; 654 655struct_dcl: str_head '{' struct_dcl_list '}' { 656 NODE *p; 657 658 $$ = dclstruct($1); 659 if (pragma_allpacked) { 660 p = bdty(CALL, bdty(NAME, "packed"), 661 bcon(pragma_allpacked)); 662 $$->n_ap = attr_add($$->n_ap,gcc_attr_parse(p)); } 663 } 664 | C_STRUCT attr_var C_NAME { 665 $$ = rstruct($3,$1); 666 uawarn($2, "struct_dcl"); 667 } 668 | C_STRUCT attr_var nmrec C_NAME { 669 $$ = cxxrstruct($1,$2,$3,$4); 670 uawarn($2, "struct_dcl"); 671 } 672 /*COMPAT_GCC*/ | str_head '{' '}' { $$ = dclstruct($1); } 673 ; 674 675attr_var: { 676 NODE *q, *p; 677 678 p = pragma_aligned ? bdty(CALL, bdty(NAME, "aligned"), 679 bcon(pragma_aligned)) : NIL; 680 if (pragma_packed) { 681 q = bdty(NAME, "packed"); 682 p = (p == NIL ? q : cmop(p, q)); 683 } 684 pragma_aligned = pragma_packed = 0; 685 $$ = p; 686 } 687 /*COMPAT_GCC*/ | attr_spec_list 688 ; 689 690attr_spec_list: attribute_specifier 691 | attr_spec_list attribute_specifier { $$ = cmop($1, $2); } 692 ; 693 694str_head: C_STRUCT attr_var { $$ = bstruct(NULL, $1, $2); } 695 | C_STRUCT attr_var C_NAME { $$ = bstruct($3, $1, $2); } 696 ; 697 698struct_dcl_list: struct_declaration 699 | struct_dcl_list struct_declaration 700 ; 701 702struct_declaration: 703 declaration_specifiers struct_declarator_list optsemi { 704 tfree($1); 705 } 706 | C_NAME ':' { /* cxxaccess($1); */ } 707 ; 708 709optsemi: ';' { } 710 | optsemi ';' { werror("extra ; in struct"); } 711 ; 712 713specifier_qualifier_list: 714 merge_specifiers { $$ = typenode($1); } 715 ; 716 717merge_specifiers: type_sq merge_specifiers { $$ = cmop($2, $1); } 718 | type_sq { $$ = $1; } 719 ; 720 721struct_declarator_list: 722 struct_declarator { symclear(blevel); } 723 | struct_declarator_list ',' { $<nodep>$=$<nodep>0; } 724 struct_declarator { symclear(blevel); } 725 ; 726 727struct_declarator: declarator attr_var { 728 NODE *p; 729 730 $1 = aryfix($1); 731 p = tymerge($<nodep>0, tymfix($1)); 732 if ($2) 733 p->n_ap = attr_add(p->n_ap, gcc_attr_parse($2)); 734 soumemb(p, (char *)$1->n_sp, $<nodep>0->n_lval); 735 tfree(p); 736 } 737 | ':' e { 738 int ie = con_e($2); 739 if (fldchk(ie)) 740 ie = 1; 741 falloc(NULL, ie, $<nodep>0); 742 } 743 | declarator ':' e { 744 int ie = con_e($3); 745 if (fldchk(ie)) 746 ie = 1; 747 if ($1->n_op == NAME) { 748 /* XXX - tymfix() may alter $1 */ 749 tymerge($<nodep>0, tymfix($1)); 750 soumemb($1, (char *)$1->n_sp, FIELD | ie); 751 nfree($1); 752 } else 753 uerror("illegal declarator"); 754 } 755 | declarator ':' e attr_spec_list { 756 int ie = con_e($3); 757 if (fldchk(ie)) 758 ie = 1; 759 if ($1->n_op == NAME) { 760 /* XXX - tymfix() may alter $1 */ 761 tymerge($<nodep>0, tymfix($1)); 762 if ($4) 763 $1->n_ap = attr_add($1->n_ap, 764 gcc_attr_parse($4)); 765 soumemb($1, (char *)$1->n_sp, FIELD | ie); 766 nfree($1); 767 } else 768 uerror("illegal declarator"); 769 } 770 | /* unnamed member */ { 771 NODE *p = $<nodep>0; 772 char *c = permalloc(10); 773 774 if (p->n_type != STRTY && p->n_type != UNIONTY) 775 uerror("bad unnamed member type"); 776 snprintf(c, 10, "*%dFAKE", getlab()); 777 soumemb(p, c, 0); 778 } 779 ; 780 781 /* always preceeded by attributes */ 782xnfdeclarator: declarator attr_var { 783 $$ = xnf = init_declarator($<nodep>0, $1, 1, $2); 784 } 785 | declarator C_ASM '(' string ')' { 786 pragma_renamed = newstring($4, strlen($4)); 787 $$ = xnf = init_declarator($<nodep>0, $1, 1, NULL); 788 } 789 ; 790 791/* 792 * Handles declarations and assignments. 793 * Returns nothing. 794 */ 795init_declarator: declarator attr_var { init_declarator($<nodep>0, $1, 0, $2);} 796 | declarator C_ASM '(' string ')' attr_var { 797#ifdef GCC_COMPAT 798 pragma_renamed = newstring($4, strlen($4)); 799 init_declarator($<nodep>0, $1, 0, $6); 800#else 801 werror("gcc extension"); 802 init_declarator($<nodep>0, $1, 0, $6); 803#endif 804 } 805 | xnfdeclarator '=' e { 806 if ($1->sclass == STATIC || $1->sclass == EXTDEF) 807 statinit++; 808 simpleinit($1, eve($3)); 809 if ($1->sclass == STATIC || $1->sclass == EXTDEF) 810 statinit--; 811 xnf = NULL; 812 } 813 | xnfdeclarator '=' begbr init_list optcomma '}' { 814 endinit(0); 815 xnf = NULL; 816 } 817 /*COMPAT_GCC*/ | xnfdeclarator '=' begbr '}' { endinit(0); xnf = NULL; } 818 | xnfdeclarator '=' addrlbl { simpleinit($1, $3); xnf = NULL; } 819 ; 820 821begbr: '{' { beginit($<symp>-1); } 822 ; 823 824initializer: e %prec ',' { $$ = eve($1); } 825 | addrlbl { $$ = $1; } 826 | ibrace init_list optcomma '}' { $$ = NULL; } 827 | ibrace '}' { asginit(bcon(0)); $$ = NULL; } 828 ; 829 830init_list: designation initializer { dainit($1, $2); } 831 | init_list ',' designation initializer { dainit($3, $4); } 832 ; 833 834designation: designator_list '=' { desinit($1); $$ = NIL; } 835 | GCC_DESIG { desinit(bdty(NAME, $1)); $$ = NIL; } 836 | '[' e C_ELLIPSIS e ']' '=' { $$ = biop(CM, $2, $4); } 837 | { $$ = NIL; } 838 ; 839 840designator_list: designator { $$ = $1; } 841 | designator_list designator { $$ = $2; $$->n_left = $1; } 842 ; 843 844designator: '[' e ']' { 845 int ie = con_e($2); 846 if (ie < 0) { 847 uerror("designator must be non-negative"); 848 ie = 0; 849 } 850 $$ = biop(LB, NIL, bcon(ie)); 851 } 852 | C_STROP C_TYPENAME { 853 if ($1 != DOT) 854 uerror("invalid designator"); 855 $$ = bdty(NAME, $2); 856 } 857 | C_STROP C_NAME { 858 if ($1 != DOT) 859 uerror("invalid designator"); 860 $$ = bdty(NAME, $2); 861 } 862 ; 863 864optcomma : /* VOID */ 865 | ',' 866 ; 867 868ibrace: '{' { ilbrace(); } 869 ; 870 871/* STATEMENTS */ 872 873compoundstmt: begin block_item_list '}' { flend(); } 874 | begin '}' { flend(); } 875 ; 876 877begin: '{' { 878 struct savbc *bc = tmpalloc(sizeof(struct savbc)); 879 if (blevel == 1) { 880#ifdef STABS 881 if (gflag) 882 stabs_line(lineno); 883#endif 884 dclargs(); 885 } 886#ifdef STABS 887 if (gflag && blevel > 1) 888 stabs_lbrac(blevel+1); 889#endif 890 ++blevel; 891 oldstyle = 0; 892 bc->contlab = autooff; 893 bc->next = savctx; 894 savctx = bc; 895 if (!isinlining && sspflag && blevel == 2) 896 sspstart(); 897 } 898 ; 899 900statement: e ';' { /* fwalk($1, eprint, 0); */ ecomp(eve($1)); symclear(blevel); } 901 | compoundstmt 902 | ifprefix statement { plabel($1); reached = 1; } 903 | ifelprefix statement { 904 if ($1 != NOLAB) { 905 plabel( $1); 906 reached = 1; 907 } 908 } 909 | whprefix statement { 910 branch(contlab); 911 plabel( brklab ); 912 if( (flostat&FBRK) || !(flostat&FLOOP)) 913 reached = 1; 914 else 915 reached = 0; 916 resetbc(0); 917 } 918 | doprefix statement C_WHILE '(' e ')' ';' { 919 plabel(contlab); 920 if (flostat & FCONT) 921 reached = 1; 922 if (reached) 923 cbranch(buildtree(NE, eve($5), bcon(0)), 924 bcon($1)); 925 else 926 tfree(eve($5)); 927 plabel( brklab); 928 reached = 1; 929 resetbc(0); 930 } 931 | forprefix .e ')' statement 932 { plabel( contlab ); 933 if( flostat&FCONT ) reached = 1; 934 if( $2 ) ecomp( $2 ); 935 branch($1); 936 plabel( brklab ); 937 if( (flostat&FBRK) || !(flostat&FLOOP) ) reached = 1; 938 else reached = 0; 939 resetbc(0); 940 symclear(blevel); /* if declaration inside for() */ 941 } 942 | switchpart statement 943 { if( reached ) branch( brklab ); 944 plabel( $1 ); 945 swend(); 946 plabel( brklab); 947 if( (flostat&FBRK) || !(flostat&FDEF) ) reached = 1; 948 resetbc(FCONT); 949 } 950 | C_BREAK ';' { 951 if (brklab == NOLAB) 952 uerror("illegal break"); 953 else if (reached) 954 branch(brklab); 955 flostat |= FBRK; 956 reached = 0; 957 } 958 | C_CONTINUE ';' { 959 if (contlab == NOLAB) 960 uerror("illegal continue"); 961 else 962 branch(contlab); 963 flostat |= FCONT; 964 goto rch; 965 } 966 | C_RETURN ';' { 967 branch(retlab); 968 if (cftnsp->stype != VOID && 969 (cftnsp->sflags & NORETYP) == 0 && 970 cftnsp->stype != VOID+FTN) 971 uerror("return value required"); 972 rch: 973 if (!reached) 974 warner(Wunreachable_code, NULL); 975 reached = 0; 976 } 977 | C_RETURN e ';' { 978 NODE *p, *q; 979 980 p = nametree(cftnsp); 981 p->n_type = DECREF(p->n_type); 982 q = eve($2); 983#ifndef NO_COMPLEX 984 if (ANYCX(q) || ANYCX(p)) 985 q = cxret(q, p); 986#endif 987 p = buildtree(RETURN, p, q); 988 if (p->n_type == VOID) { 989 ecomp(p->n_right); 990 } else { 991 if (cftnod == NIL) 992 cftnod = tempnode(0, p->n_type, 993 p->n_df, p->n_ap); 994 ecomp(buildtree(ASSIGN, 995 ccopy(cftnod), p->n_right)); 996 } 997 tfree(p->n_left); 998 nfree(p); 999 branch(retlab); 1000 reached = 0; 1001 } 1002 | C_GOTO C_NAME ';' { gotolabel($2); goto rch; } 1003 | C_GOTO '*' e ';' { ecomp(biop(GOTO, eve($3), NIL)); } 1004 | asmstatement ';' 1005 | ';' 1006 | error ';' 1007 | error '}' 1008 | label statement 1009 ; 1010 1011asmstatement: C_ASM mvol '(' string ')' { send_passt(IP_ASM, mkpstr($4)); } 1012 | C_ASM mvol '(' string xasm ')' { mkxasm($4, $5); } 1013 ; 1014 1015mvol: /* empty */ 1016 | C_QUALIFIER { nfree($1); } 1017 ; 1018 1019xasm: ':' oplist { $$ = xcmop($2, NIL, NIL); } 1020 | ':' oplist ':' oplist { $$ = xcmop($2, $4, NIL); } 1021 | ':' oplist ':' oplist ':' cnstr { $$ = xcmop($2, $4, $6); } 1022 ; 1023 1024oplist: /* nothing */ { $$ = NIL; } 1025 | oper { $$ = $1; } 1026 ; 1027 1028oper: string '(' e ')' { $$ = xasmop($1, eve($3)); } 1029 | oper ',' string '(' e ')' { 1030 $$ = cmop($1, xasmop($3, eve($5))); 1031 } 1032 ; 1033 1034cnstr: string { $$ = xasmop($1, bcon(0)); } 1035 | cnstr ',' string { $$ = cmop($1, xasmop($3, bcon(0))); } 1036 ; 1037 1038label: C_NAME ':' attr_var { deflabel($1, $3); reached = 1; } 1039 | C_TYPENAME ':' attr_var { deflabel($1, $3); reached = 1; } 1040 | C_CASE e ':' { addcase(eve($2)); reached = 1; } 1041/* COMPAT_GCC */| C_CASE e C_ELLIPSIS e ':' { 1042#ifdef GCC_COMPAT 1043 gcccase(eve($2), eve($4)); reached = 1; 1044#endif 1045 } 1046 | C_DEFAULT ':' { reached = 1; adddef(); flostat |= FDEF; } 1047 ; 1048 1049doprefix: C_DO { 1050 savebc(); 1051 brklab = getlab(); 1052 contlab = getlab(); 1053 plabel( $$ = getlab()); 1054 reached = 1; 1055 } 1056 ; 1057ifprefix: C_IF '(' e ')' { 1058 cbranch(buildtree(NOT, eve($3), NIL), bcon($$ = getlab())); 1059 reached = 1; 1060 } 1061 ; 1062ifelprefix: ifprefix statement C_ELSE { 1063 if (reached) 1064 branch($$ = getlab()); 1065 else 1066 $$ = NOLAB; 1067 plabel( $1); 1068 reached = 1; 1069 } 1070 ; 1071 1072whprefix: C_WHILE '(' e ')' { 1073 savebc(); 1074 $3 = eve($3); 1075 if ($3->n_op == ICON && $3->n_lval != 0) 1076 flostat = FLOOP; 1077 plabel( contlab = getlab()); 1078 reached = 1; 1079 brklab = getlab(); 1080 if (flostat == FLOOP) 1081 tfree($3); 1082 else 1083 cbranch(buildtree(NOT, $3, NIL), bcon(brklab)); 1084 } 1085 ; 1086forprefix: C_FOR '(' .e ';' .e ';' { 1087 if ($3) 1088 ecomp($3); 1089 savebc(); 1090 contlab = getlab(); 1091 brklab = getlab(); 1092 plabel( $$ = getlab()); 1093 reached = 1; 1094 if ($5) 1095 cbranch(buildtree(NOT, $5, NIL), bcon(brklab)); 1096 else 1097 flostat |= FLOOP; 1098 } 1099 | C_FOR '(' { ++blevel; } declaration .e ';' { 1100 blevel--; 1101 savebc(); 1102 contlab = getlab(); 1103 brklab = getlab(); 1104 plabel( $$ = getlab()); 1105 reached = 1; 1106 if ($5) 1107 cbranch(buildtree(NOT, $5, NIL), bcon(brklab)); 1108 else 1109 flostat |= FLOOP; 1110 } 1111 ; 1112 1113switchpart: C_SWITCH '(' e ')' { 1114 NODE *p; 1115 int num; 1116 TWORD t; 1117 1118 savebc(); 1119 brklab = getlab(); 1120 $3 = eve($3); 1121 if (!ISINTEGER($3->n_type)) { 1122 uerror("switch expression must have integer " 1123 "type"); 1124 t = INT; 1125 } else { 1126 $3 = intprom($3); 1127 t = $3->n_type; 1128 } 1129 p = tempnode(0, t, 0, 0); 1130 num = regno(p); 1131 ecomp(buildtree(ASSIGN, p, $3)); 1132 branch( $$ = getlab()); 1133 swstart(num, t); 1134 reached = 0; 1135 } 1136 ; 1137/* EXPRESSIONS */ 1138.e: e { $$ = eve($1); } 1139 | { $$=0; } 1140 ; 1141 1142elist: { $$ = NIL; } 1143 | e %prec ',' 1144 | elist ',' e { $$ = biop(CM, $1, $3); } 1145 | elist ',' cast_type { /* hack for stdarg */ 1146 TYMFIX($3); 1147 $3->n_op = TYPE; 1148 $$ = biop(CM, $1, $3); 1149 } 1150 ; 1151 1152/* 1153 * Precedence order of operators. 1154 */ 1155e: e ',' e { $$ = biop(COMOP, $1, $3); } 1156 | e '=' e { $$ = biop(ASSIGN, $1, $3); } 1157 | e C_ASOP e { $$ = biop($2, $1, $3); } 1158 | e '?' e ':' e { 1159 $$=biop(QUEST, $1, biop(COLON, $3, $5)); 1160 } 1161 | e '?' ':' e { 1162 NODE *p = tempnode(0, $1->n_type, $1->n_df, $1->n_ap); 1163 $$ = biop(COLON, ccopy(p), $4); 1164 $$=biop(QUEST, biop(ASSIGN, p, $1), $$); 1165 } 1166 | e C_OROR e { $$ = biop($2, $1, $3); } 1167 | e C_ANDAND e { $$ = biop($2, $1, $3); } 1168 | e '|' e { $$ = biop(OR, $1, $3); } 1169 | e '^' e { $$ = biop(ER, $1, $3); } 1170 | e '&' e { $$ = biop(AND, $1, $3); } 1171 | e C_EQUOP e { $$ = biop($2, $1, $3); } 1172 | e C_RELOP e { $$ = biop($2, $1, $3); } 1173 | e C_SHIFTOP e { $$ = biop($2, $1, $3); } 1174 | e '+' e { $$ = biop(PLUS, $1, $3); } 1175 | e '-' e { $$ = biop(MINUS, $1, $3); } 1176 | e C_DIVOP e { $$ = biop($2, $1, $3); } 1177 | e '*' e { $$ = biop(MUL, $1, $3); } 1178 | e '=' addrlbl { $$ = biop(ASSIGN, $1, $3); } 1179 | term 1180 ; 1181 1182xbegin: begin { 1183 $$ = getlab(); getlab(); getlab(); 1184 branch($$); plabel(($$)+1); } 1185 ; 1186 1187addrlbl: C_ANDAND C_NAME { 1188#ifdef GCC_COMPAT 1189 struct symtab *s = lookup($2, SLBLNAME); 1190 if (s->soffset == 0) 1191 s->soffset = -getlab(); 1192 $$ = buildtree(ADDROF, nametree(s), NIL); 1193#else 1194 uerror("gcc extension"); 1195#endif 1196 } 1197 ; 1198 1199term: term C_INCOP { $$ = biop($2, $1, bcon(1)); } 1200 | '*' term { $$ = biop(UMUL, $2, NIL); } 1201 | '&' term { $$ = biop(ADDROF, $2, NIL); } 1202 | '-' term { $$ = biop(UMINUS, $2, NIL ); } 1203 | '+' term { $$ = biop(PLUS, $2, bcon(0)); } 1204 | CXX_CASTS C_RELOP cast_type C_RELOP '(' e ')' { 1205 tfree($6); 1206 tfree($3); 1207 $$ = bcon(0); 1208 werror("CXX_CASTS unhandled"); 1209 } 1210 | C_UNOP term { $$ = biop($1, $2, NIL); } 1211 | C_INCOP term { 1212 $$ = biop($1 == INCR ? PLUSEQ : MINUSEQ, $2, bcon(1)); 1213 } 1214 | C_SIZEOF xa term { $$ = biop(SZOF, $3, bcon(0)); inattr = $<intval>2; } 1215 | '(' cast_type ')' term %prec C_INCOP { 1216 TYMFIX($2); 1217 $$ = biop(CAST, $2, $4); 1218 } 1219 | C_SIZEOF xa '(' cast_type ')' %prec C_SIZEOF { 1220 $$ = biop(SZOF, $4, bcon(1)); 1221 inattr = $<intval>2; 1222 } 1223 | C_ALIGNOF xa '(' cast_type ')' { 1224 int al; 1225 TYMFIX($4); 1226 al = talign($4->n_type, $4->n_ap); 1227 $$ = bcon(al/SZCHAR); 1228 inattr = $<intval>2; 1229 tfree($4); 1230 } 1231 | '(' cast_type ')' clbrace init_list optcomma '}' { 1232 endinit(0); 1233 $$ = bdty(NAME, $4); 1234 $$->n_op = CLOP; 1235 } 1236 | '(' cast_type ')' clbrace '}' { 1237 endinit(0); 1238 $$ = bdty(NAME, $4); 1239 $$->n_op = CLOP; 1240 } 1241 | term '[' e ']' { 1242 if ($1->n_op == NEWKW) { 1243 $1->n_left = biop(LB, $1->n_left, $3); 1244 } else 1245 $$ = biop(LB, $1, $3); 1246 } 1247 | C_NAME '(' elist ')' { 1248#if 0 1249 if ($3) tfree($3); 1250 $$ = bcon(0); 1251#else 1252 $$ = biop($3 ? CALL : UCALL, bdty(NAME, $1), $3); 1253#endif 1254 } 1255 | term '(' elist ')' { $$ = biop($3 ? CALL : UCALL, $1, $3); } 1256 | term C_STROP C_NAME { $$ = biop($2, $1, bdty(NAME, $3)); } 1257 | term C_STROP C_TYPENAME { $$ = biop($2, $1, bdty(NAME, $3));} 1258 | C_NAME %prec C_SIZEOF /* below ( */{ $$ = bdty(NAME, $1); } 1259 | nmrec C_NAME %prec C_SIZEOF { 1260 $$ = biop(NMLIST, $1, bdty(NAME, $2)); 1261 } 1262 | PCC_OFFSETOF '(' cast_type ',' term ')' { 1263 TYMFIX($3); 1264 $3->n_type = INCREF($3->n_type); 1265 $3 = biop(CAST, $3, bcon(0)); 1266 if ($5->n_op == NAME) { 1267 $$ = biop(STREF, $3, $5); 1268 } else { 1269 NODE *p = $5; 1270 while (p->n_left->n_op != NAME) 1271 p = p->n_left; 1272 p->n_left = biop(STREF, $3, p->n_left); 1273 $$ = $5; 1274 } 1275 $$ = biop(ADDROF, $$, NIL); 1276 $3 = block(NAME, NIL, NIL, ENUNSIGN(INTPTR), 0, 0); 1277 $$ = biop(CAST, $3, $$); 1278 } 1279 | C_ICON { $$ = $1; } 1280 | C_FCON { $$ = $1; } 1281 | string { $$ = bdty(STRING, $1, widestr); } 1282 | '(' e ')' { $$=$2; } 1283 | '(' xbegin block_item_list e ';' '}' ')' { 1284 /* XXX - check recursive ({ }) statements */ 1285 branch(($2)+2); 1286 plabel($2); 1287 $$ = buildtree(COMOP, 1288 biop(GOTO, bcon(($2)+1), NIL), eve($4)); 1289 flend(); 1290 } 1291 | '(' xbegin block_item_list '}' ')' { 1292 /* XXX - check recursive ({ }) statements */ 1293 branch(($2)+2); 1294 plabel($2); 1295 $$ = buildtree(COMOP, 1296 biop(GOTO, bcon(($2)+1), NIL), voidcon()); 1297 flend(); 1298 } 1299 | CXX_NEW new_ds { $$ = biop(NEWKW, $2, bcon(0)); } 1300 | CXX_NEW '(' cast_type ')' { $$ = 0; uerror("new cast"); } 1301 | CXX_DELETE term %prec '-' { 1302 $$ = biop(DELETE, $2, bcon(NM_DEL)); 1303 } 1304 | CXX_DELETE '[' ']' term %prec '-' { 1305 $$ = biop(DELETE, $4, bcon(NM_DLA)); 1306 } 1307 ; 1308 1309nmrec: CXX_MORENM { $$ = bdty(NAME, $1); } 1310 | CXX_MORENM nmrec { $$ = biop(NMLIST, $2, bdty(NAME, $1)); } 1311 ; 1312 1313xa: { $<intval>$ = inattr; inattr = 0; } 1314 ; 1315 1316clbrace: '{' { NODE *q = $<nodep>-1; TYMFIX(q); $$ = clbrace(q); } 1317 ; 1318 1319string: C_STRING { widestr = 0; $$ = stradd("", $1); } 1320 | string C_STRING { $$ = stradd($1, $2); } 1321 ; 1322 1323cast_type: specifier_qualifier_list { 1324 $$ = biop(TYMERGE, $1, bdty(NAME, NULL)); 1325 } 1326 | specifier_qualifier_list abstract_declarator { 1327 $$ = biop(TYMERGE, $1, aryfix($2)); 1328 } 1329 ; 1330 1331%% 1332 1333NODE * 1334mkty(TWORD t, union dimfun *d, struct attr *sue) 1335{ 1336 return block(TYPE, NIL, NIL, t, d, sue); 1337} 1338 1339NODE * 1340bdty(int op, ...) 1341{ 1342 va_list ap; 1343 int val; 1344 register NODE *q; 1345 1346 va_start(ap, op); 1347 q = biop(op, NIL, NIL); 1348 1349 switch (op) { 1350 case UMUL: 1351 case UCALL: 1352 q->n_left = va_arg(ap, NODE *); 1353 q->n_rval = 0; 1354 break; 1355 1356 case CALL: 1357 q->n_left = va_arg(ap, NODE *); 1358 q->n_right = va_arg(ap, NODE *); 1359 break; 1360 1361 case LB: 1362 q->n_left = va_arg(ap, NODE *); 1363 if ((val = va_arg(ap, int)) <= 0) { 1364 uerror("array size must be positive"); 1365 val = 1; 1366 } 1367 q->n_right = bcon(val); 1368 break; 1369 1370 case NAME: 1371 q->n_sp = va_arg(ap, struct symtab *); /* XXX survive tymerge */ 1372 break; 1373 1374 case STRING: 1375 q->n_name = va_arg(ap, char *); 1376 q->n_lval = va_arg(ap, int); 1377 break; 1378 1379 default: 1380 cerror("bad bdty"); 1381 } 1382 va_end(ap); 1383 1384 return q; 1385} 1386 1387static void 1388flend(void) 1389{ 1390 if (!isinlining && sspflag && blevel == 2) 1391 sspend(); 1392#ifdef STABS 1393 if (gflag && blevel > 2) 1394 stabs_rbrac(blevel); 1395#endif 1396 --blevel; 1397 if( blevel == 1 ) 1398 blevel = 0; 1399 symclear(blevel); /* Clean ut the symbol table */ 1400 if (autooff > maxautooff) 1401 maxautooff = autooff; 1402 autooff = savctx->contlab; 1403 savctx = savctx->next; 1404} 1405 1406static void 1407savebc(void) 1408{ 1409 struct savbc *bc = tmpalloc(sizeof(struct savbc)); 1410 1411 bc->brklab = brklab; 1412 bc->contlab = contlab; 1413 bc->flostat = flostat; 1414 bc->next = savbc; 1415 savbc = bc; 1416 flostat = 0; 1417} 1418 1419static void 1420resetbc(int mask) 1421{ 1422 flostat = savbc->flostat | (flostat&mask); 1423 contlab = savbc->contlab; 1424 brklab = savbc->brklab; 1425 savbc = savbc->next; 1426} 1427 1428struct swdef { 1429 struct swdef *next; /* Next in list */ 1430 int deflbl; /* Label for "default" */ 1431 struct swents *ents; /* Linked sorted list of case entries */ 1432 int nents; /* # of entries in list */ 1433 int num; /* Node value will end up in */ 1434 TWORD type; /* Type of switch expression */ 1435} *swpole; 1436 1437/* 1438 * add case to switch 1439 */ 1440static void 1441addcase(NODE *p) 1442{ 1443 struct swents **put, *w, *sw = tmpalloc(sizeof(struct swents)); 1444 CONSZ val; 1445 1446 p = optim(rmpconv(p)); /* change enum to ints */ 1447 if (p->n_op != ICON || p->n_sp != NULL) { 1448 uerror( "non-constant case expression"); 1449 return; 1450 } 1451 if (swpole == NULL) { 1452 uerror("case not in switch"); 1453 return; 1454 } 1455 1456 if (DEUNSIGN(swpole->type) != DEUNSIGN(p->n_type)) { 1457 val = p->n_lval; 1458 p = makety(p, swpole->type, 0, 0, 0); 1459 if (p->n_op != ICON) 1460 cerror("could not cast case value to type of switch " 1461 "expression"); 1462 if (p->n_lval != val) 1463 werror("case expression truncated"); 1464 } 1465 sw->sval = p->n_lval; 1466 tfree(p); 1467 put = &swpole->ents; 1468 if (ISUNSIGNED(swpole->type)) { 1469 for (w = swpole->ents; 1470 w != NULL && (U_CONSZ)w->sval < (U_CONSZ)sw->sval; 1471 w = w->next) 1472 put = &w->next; 1473 } else { 1474 for (w = swpole->ents; w != NULL && w->sval < sw->sval; 1475 w = w->next) 1476 put = &w->next; 1477 } 1478 if (w != NULL && w->sval == sw->sval) { 1479 uerror("duplicate case in switch"); 1480 return; 1481 } 1482 plabel(sw->slab = getlab()); 1483 *put = sw; 1484 sw->next = w; 1485 swpole->nents++; 1486} 1487 1488#ifdef GCC_COMPAT 1489void 1490gcccase(NODE *ln, NODE *hn) 1491{ 1492 CONSZ i, l, h; 1493 1494 l = icons(optim(ln)); 1495 h = icons(optim(hn)); 1496 1497 if (h < l) 1498 i = l, l = h, h = i; 1499 1500 for (i = l; i <= h; i++) 1501 addcase(xbcon(i, NULL, hn->n_type)); 1502} 1503#endif 1504 1505/* 1506 * add default case to switch 1507 */ 1508static void 1509adddef(void) 1510{ 1511 if (swpole == NULL) 1512 uerror("default not inside switch"); 1513 else if (swpole->deflbl != 0) 1514 uerror("duplicate default in switch"); 1515 else 1516 plabel( swpole->deflbl = getlab()); 1517} 1518 1519static void 1520swstart(int num, TWORD type) 1521{ 1522 struct swdef *sw = tmpalloc(sizeof(struct swdef)); 1523 1524 sw->deflbl = sw->nents = 0; 1525 sw->ents = NULL; 1526 sw->next = swpole; 1527 sw->num = num; 1528 sw->type = type; 1529 swpole = sw; 1530} 1531 1532/* 1533 * end a switch block 1534 */ 1535static void 1536swend(void) 1537{ 1538 struct swents *sw, **swp; 1539 int i; 1540 1541 sw = tmpalloc(sizeof(struct swents)); 1542 swp = tmpalloc(sizeof(struct swents *) * (swpole->nents+1)); 1543 1544 sw->slab = swpole->deflbl; 1545 swp[0] = sw; 1546 1547 for (i = 1; i <= swpole->nents; i++) { 1548 swp[i] = swpole->ents; 1549 swpole->ents = swpole->ents->next; 1550 } 1551 genswitch(swpole->num, swpole->type, swp, swpole->nents); 1552 1553 swpole = swpole->next; 1554} 1555 1556/* 1557 * num: tempnode the value of the switch expression is in 1558 * type: type of the switch expression 1559 * 1560 * p points to an array of structures, each consisting 1561 * of a constant value and a label. 1562 * The first is >=0 if there is a default label; 1563 * its value is the label number 1564 * The entries p[1] to p[n] are the nontrivial cases 1565 * n is the number of case statements (length of list) 1566 */ 1567static void 1568genswitch(int num, TWORD type, struct swents **p, int n) 1569{ 1570 NODE *r, *q; 1571 int i; 1572 1573 if (mygenswitch(num, type, p, n)) 1574 return; 1575 1576 /* simple switch code */ 1577 for (i = 1; i <= n; ++i) { 1578 /* already in 1 */ 1579 r = tempnode(num, type, 0, 0); 1580 q = xbcon(p[i]->sval, NULL, type); 1581 r = buildtree(NE, r, clocal(q)); 1582 cbranch(buildtree(NOT, r, NIL), bcon(p[i]->slab)); 1583 } 1584 if (p[0]->slab > 0) 1585 branch(p[0]->slab); 1586} 1587 1588/* 1589 * Declare a variable or prototype. 1590 */ 1591static struct symtab * 1592init_declarator(NODE *tn, NODE *p, int assign, NODE *a) 1593{ 1594 int class = tn->n_lval; 1595 struct symtab *sp; 1596 1597 p = aryfix(p); 1598 if (p->n_op == NMLIST) { 1599 tymerge(tn, p->n_right); 1600 } else 1601 p = tymerge(tn, p); 1602 if (a) { 1603 struct attr *ap = gcc_attr_parse(a); 1604 p->n_ap = attr_add(p->n_ap, ap); 1605 } 1606 1607 sp = cxxdeclvar(p); 1608 1609 if (fun_inline && ISFTN(p->n_type)) 1610 sp->sflags |= SINLINE; 1611 1612 if (ISFTN(p->n_type) == 0) { 1613 if (assign) { 1614 defid(p, class); 1615 sp = p->n_sp; 1616 sp->sflags |= SASG; 1617 if (sp->sflags & SDYNARRAY) 1618 uerror("can't initialize dynamic arrays"); 1619 lcommdel(sp); 1620 } else 1621 nidcl(p, class); 1622 } else { 1623 extern NODE *parlink; 1624 if (assign) 1625 uerror("cannot initialise function"); 1626 defid(p, uclass(class)); 1627 sp = p->n_sp; 1628 if (parlink) { 1629 /* dynamic sized arrays in prototypes */ 1630 tfree(parlink); /* Free delayed tree */ 1631 parlink = NIL; 1632 } 1633 } 1634 tfree(p); 1635 return sp; 1636} 1637 1638/* 1639 * Declare old-stype function arguments. 1640 */ 1641static void 1642oldargs(NODE *p) 1643{ 1644 blevel++; 1645 p->n_op = TYPE; 1646 p->n_type = FARG; 1647 p->n_sp = lookup((char *)p->n_sp, 0);/* XXX */ 1648 defid(p, PARAM); 1649 blevel--; 1650} 1651 1652/* 1653 * Set NAME nodes to a null name and index of LB nodes to NOOFFSET 1654 * unless clr is one, in that case preserve variable name. 1655 */ 1656static NODE * 1657namekill(NODE *p, int clr) 1658{ 1659 NODE *q; 1660 int o = p->n_op; 1661 1662 switch (coptype(o)) { 1663 case LTYPE: 1664 if (o == NAME) { 1665 if (clr) 1666 p->n_sp = NULL; 1667 else 1668 p->n_sp = lookup((char *)p->n_sp, 0);/* XXX */ 1669 } 1670 break; 1671 1672 case UTYPE: 1673 p->n_left = namekill(p->n_left, clr); 1674 break; 1675 1676 case BITYPE: 1677 p->n_left = namekill(p->n_left, clr); 1678 if (o == LB) { 1679 if (clr) { 1680 tfree(p->n_right); 1681 p->n_right = bcon(NOOFFSET); 1682 } else 1683 p->n_right = eve(p->n_right); 1684 } else if (o == CALL) 1685 p->n_right = namekill(p->n_right, 1); 1686 else 1687 p->n_right = namekill(p->n_right, clr); 1688 if (o == TYMERGE) { 1689 q = tymerge(p->n_left, p->n_right); 1690 q->n_ap = attr_add(q->n_ap, p->n_ap); 1691 tfree(p->n_left); 1692 nfree(p); 1693 p = q; 1694 } 1695 break; 1696 } 1697 return p; 1698} 1699 1700/* 1701 * Declare function arguments. 1702 */ 1703static NODE * 1704funargs(NODE *p) 1705{ 1706 extern NODE *arrstk[10]; 1707 1708 if (p->n_op == ELLIPSIS) 1709 return p; 1710 1711 p = namekill(p, 0); 1712 if (ISFTN(p->n_type)) 1713 p->n_type = INCREF(p->n_type); 1714 if (ISARY(p->n_type)) { 1715 p->n_type += (PTR-ARY); 1716 if (p->n_df->ddim == -1) 1717 tfree(arrstk[0]), arrstk[0] = NIL; 1718 p->n_df++; 1719 } 1720 if (p->n_type == VOID && p->n_sp->sname == NULL) 1721 return p; /* sanitycheck later */ 1722 else if (p->n_sp->sname == NULL) 1723 ; /* uerror("argument missing"); */ 1724 else 1725 defid(p, PARAM); 1726 return p; 1727} 1728 1729static NODE * 1730listfw(NODE *p, NODE * (*f)(NODE *)) 1731{ 1732 if (p->n_op == CM) { 1733 p->n_left = listfw(p->n_left, f); 1734 p->n_right = (*f)(p->n_right); 1735 } else 1736 p = (*f)(p); 1737 return p; 1738} 1739 1740 1741/* 1742 * Declare a function. 1743 */ 1744static struct symtab * 1745fundef(NODE *tp, NODE *p) 1746{ 1747 extern int prolab; 1748 struct symtab *s, *nsthis; 1749 NODE *q, *typ; 1750 int class = tp->n_lval, oclass, ctval; 1751 char *c; 1752 1753 /* 1754 * We discard all names except for those needed for 1755 * parameter declaration. While doing that, also change 1756 * non-constant array sizes to unknown. 1757 */ 1758 ctval = tvaloff; 1759 for (q = p; coptype(q->n_op) != LTYPE && 1760 q->n_left->n_op != NAME && 1761 q->n_left->n_op != NMLIST; q = q->n_left) { 1762 if (q->n_op == CALL) 1763 q->n_right = namekill(q->n_right, 1); 1764 } 1765 if (q->n_op != CALL && q->n_op != UCALL) { 1766 uerror("invalid function definition"); 1767 p = bdty(UCALL, p); 1768 } else if (q->n_op == CALL) { 1769 blevel = 1; 1770 argoff = ARGINIT; 1771 if (oldstyle == 0) 1772 q->n_right = listfw(q->n_right, funargs); 1773 ftnarg(q); 1774 blevel = 0; 1775 } 1776 1777 if (p->n_op == CALL && p->n_left->n_op == NMLIST) { 1778 NODE *r = p->n_left; 1779 p->n_left = r->n_right; 1780 r->n_right = typ = tymerge(tp, p); 1781 p = r; 1782 } else 1783 typ = tymerge(tp, p); 1784 1785#ifdef GCC_COMPAT 1786 /* gcc seems to discard __builtin_ when declaring functions */ 1787 if (strncmp("__builtin_", (char *)typ->n_sp, 10) == 0) 1788 typ->n_sp = (struct symtab *)((char *)typ->n_sp + 10); 1789#endif 1790 1791 s = cxxftnfind(p, SNORMAL); 1792 nsthis = nscur; 1793 nscur = s->sdown; /* XXX fun in fun? */ 1794 1795 oclass = s->sclass; 1796 if (class == STATIC && oclass == EXTERN) 1797 werror("%s was first declared extern, then static", s->sname); 1798 1799 if (fun_inline) { 1800 /* special syntax for inline functions */ 1801 if (! strcmp(s->sname,"main")) 1802 uerror("cannot inline main()"); 1803 1804 s->sflags |= SINLINE; 1805 inline_start(s); 1806 if (class == EXTERN) 1807 class = EXTDEF; 1808 } else if (class == EXTERN) 1809 class = SNULL; /* same result */ 1810 1811 cftnsp = s; 1812#if 0 1813 defid(p, class); 1814#endif 1815 1816#ifdef GCC_COMPAT 1817 if (attr_find(p->n_ap, GCC_ATYP_ALW_INL)) { 1818 /* Temporary turn on temps to make always_inline work */ 1819 alwinl = 1; 1820 if (xtemps == 0) alwinl |= 2; 1821 xtemps = 1; 1822 } 1823#endif 1824 prolab = getlab(); 1825 if ((c = cftnsp->soname) == NULL) 1826 c = addname(exname(cftnsp->sname)); 1827 send_passt(IP_PROLOG, -1, c, cftnsp->stype, 1828 cftnsp->sclass == EXTDEF, prolab, ctval); 1829 blevel++; 1830#ifdef STABS 1831 if (gflag) 1832 stabs_func(s); 1833#endif 1834 tfree(tp); 1835 tfree(p); 1836 return nsthis; 1837} 1838 1839static void 1840fend(struct symtab *ns) 1841{ 1842 if (blevel) 1843 cerror("function level error"); 1844 ftnend(); 1845 fun_inline = 0; 1846 if (alwinl & 2) xtemps = 0; 1847 alwinl = 0; 1848 cftnsp = NULL; 1849 nscur = ns; 1850} 1851 1852NODE * 1853structref(NODE *p, int f, char *name) 1854{ 1855 NODE *r; 1856 1857 if (f == DOT) 1858 p = buildtree(ADDROF, p, NIL); 1859 r = biop(NAME, NIL, NIL); 1860 r->n_name = name; 1861 r = buildtree(STREF, p, r); 1862 return r; 1863} 1864 1865static void 1866olddecl(NODE *p, NODE *a) 1867{ 1868 struct symtab *s; 1869 1870 p = namekill(p, 0); 1871 s = p->n_sp; 1872 if (s->slevel != 1 || s->stype == UNDEF) 1873 uerror("parameter '%s' not defined", s->sname); 1874 else if (s->stype != FARG) 1875 uerror("parameter '%s' redefined", s->sname); 1876 1877 s->stype = p->n_type; 1878 s->sdf = p->n_df; 1879 s->sap = p->n_ap; 1880 if (ISARY(s->stype)) { 1881 s->stype += (PTR-ARY); 1882 s->sdf++; 1883 } else if (s->stype == FLOAT) 1884 s->stype = DOUBLE; 1885 if (a) 1886 attr_add(s->sap, gcc_attr_parse(a)); 1887 nfree(p); 1888} 1889 1890void 1891branch(int lbl) 1892{ 1893 int r = reached++; 1894 ecomp(biop(GOTO, bcon(lbl), NIL)); 1895 reached = r; 1896} 1897 1898/* 1899 * Create a printable string based on an encoded string. 1900 */ 1901static char * 1902mkpstr(char *str) 1903{ 1904 char *s, *os; 1905 int v, l = strlen(str)+3; /* \t + \n + \0 */ 1906 1907 os = s = inlalloc(l); 1908 *s++ = '\t'; 1909 for (; *str; ) { 1910 if (*str++ == '\\') 1911 v = esccon(&str); 1912 else 1913 v = str[-1]; 1914 *s++ = v; 1915 } 1916 *s++ = '\n'; 1917 *s = 0; 1918 return os; 1919} 1920 1921/* 1922 * Estimate the max length a string will have in its internal 1923 * representation based on number of \ characters. 1924 */ 1925static int 1926maxstlen(char *str) 1927{ 1928 int i; 1929 1930 for (i = 0; *str; str++, i++) 1931 if (*str == '\\' || *str < 32 || *str > 0176) 1932 i += 3; 1933 return i; 1934} 1935 1936static char * 1937voct(char *d, unsigned int v) 1938{ 1939 v &= (1 << SZCHAR) - 1; 1940 *d++ = '\\'; 1941 *d++ = v/64 + '0'; v &= 077; 1942 *d++ = v/8 + '0'; v &= 7; 1943 *d++ = v + '0'; 1944 return d; 1945} 1946 1947 1948/* 1949 * Convert a string to internal format. The resulting string may be no 1950 * more than len characters long. 1951 */ 1952static void 1953fixstr(char *d, char *s, int len) 1954{ 1955 unsigned int v; 1956 1957 while (*s) { 1958 if (len <= 0) 1959 cerror("fixstr"); 1960 if (*s == '\\') { 1961 s++; 1962 v = esccon(&s); 1963 d = voct(d, v); 1964 len -= 4; 1965 } else if (*s < ' ' || *s > 0176) { 1966 d = voct(d, *s++); 1967 len -= 4; 1968 } else 1969 *d++ = *s++, len--; 1970 } 1971 *d = 0; 1972} 1973 1974/* 1975 * Add "raw" string new to cleaned string old. 1976 */ 1977static char * 1978stradd(char *old, char *new) 1979{ 1980 char *rv; 1981 int len; 1982 1983 if (*new == 'L' && new[1] == '\"') 1984 widestr = 1, new++; 1985 if (*new == '\"') { 1986 new++; /* remove first " */ 1987 new[strlen(new) - 1] = 0;/* remove last " */ 1988 } 1989 len = strlen(old) + maxstlen(new) + 1; 1990 rv = tmpalloc(len); 1991 strlcpy(rv, old, len); 1992 fixstr(rv + strlen(old), new, maxstlen(new) + 1); 1993 return rv; 1994} 1995 1996/* 1997 * Fake a symtab entry for compound literals. 1998 */ 1999static struct symtab * 2000clbrace(NODE *p) 2001{ 2002 struct symtab *sp; 2003 2004 sp = getsymtab(simname("cl"), STEMP); 2005 sp->stype = p->n_type; 2006 sp->squal = p->n_qual; 2007 sp->sdf = p->n_df; 2008 sp->sap = p->n_ap; 2009 tfree(p); 2010 if (blevel == 0 && xnf != NULL) { 2011 sp->sclass = STATIC; 2012 sp->slevel = 2; 2013 sp->soffset = getlab(); 2014 } else { 2015 sp->sclass = blevel ? AUTO : STATIC; 2016 if (!ISARY(sp->stype) || sp->sdf->ddim != NOOFFSET) { 2017 sp->soffset = NOOFFSET; 2018 oalloc(sp, &autooff); 2019 } 2020 } 2021 beginit(sp); 2022 return sp; 2023} 2024 2025char * 2026simname(char *s) 2027{ 2028 int len = strlen(s) + 10 + 1; 2029 char *w = tmpalloc(len); 2030 2031 snprintf(w, len, "%s%d", s, getlab()); 2032 return w; 2033} 2034 2035NODE * 2036biop(int op, NODE *l, NODE *r) 2037{ 2038 return block(op, l, r, INT, 0, 0); 2039} 2040 2041static NODE * 2042cmop(NODE *l, NODE *r) 2043{ 2044 return biop(CM, l, r); 2045} 2046 2047static NODE * 2048voidcon(void) 2049{ 2050 return block(ICON, NIL, NIL, STRTY, 0, 0); 2051} 2052 2053/* Support for extended assembler a' la' gcc style follows below */ 2054 2055static NODE * 2056xmrg(NODE *out, NODE *in) 2057{ 2058 NODE *p = in; 2059 2060 if (p->n_op == XARG) { 2061 in = cmop(out, p); 2062 } else { 2063 while (p->n_left->n_op == CM) 2064 p = p->n_left; 2065 p->n_left = cmop(out, p->n_left); 2066 } 2067 return in; 2068} 2069 2070/* 2071 * Put together in and out node lists in one list, and balance it with 2072 * the constraints on the right side of a CM node. 2073 */ 2074static NODE * 2075xcmop(NODE *out, NODE *in, NODE *str) 2076{ 2077 NODE *p, *q; 2078 2079 if (out) { 2080 /* D out-list sanity check */ 2081 for (p = out; p->n_op == CM; p = p->n_left) { 2082 q = p->n_right; 2083 if (q->n_name[0] != '=' && q->n_name[0] != '+') 2084 uerror("output missing ="); 2085 } 2086 if (p->n_name[0] != '=' && p->n_name[0] != '+') 2087 uerror("output missing ="); 2088 if (in == NIL) 2089 p = out; 2090 else 2091 p = xmrg(out, in); 2092 } else if (in) { 2093 p = in; 2094 } else 2095 p = voidcon(); 2096 2097 if (str == NIL) 2098 str = voidcon(); 2099 return cmop(p, str); 2100} 2101 2102/* 2103 * Generate a XARG node based on a string and an expression. 2104 */ 2105static NODE * 2106xasmop(char *str, NODE *p) 2107{ 2108 2109 p = biop(XARG, p, NIL); 2110 p->n_name = isinlining ? newstring(str, strlen(str)+1) : str; 2111 return p; 2112} 2113 2114/* 2115 * Generate a XASM node based on a string and an expression. 2116 */ 2117static void 2118mkxasm(char *str, NODE *p) 2119{ 2120 NODE *q; 2121 2122 q = biop(XASM, p->n_left, p->n_right); 2123 q->n_name = isinlining ? newstring(str, strlen(str)+1) : str; 2124 nfree(p); 2125 ecomp(q); 2126} 2127 2128#ifdef GCC_COMPAT 2129static NODE * 2130tyof(NODE *p) 2131{ 2132 static struct symtab spp; 2133 NODE *q = block(TYPE, NIL, NIL, p->n_type, p->n_df, p->n_ap); 2134 q->n_qual = p->n_qual; 2135 q->n_sp = &spp; /* for typenode */ 2136 tfree(p); 2137 return q; 2138} 2139#endif 2140 2141/* 2142 * Rewrite ++/-- to (t=p, p++, t) ops on types that do not act act as usual. 2143 */ 2144static NODE * 2145rewincop(NODE *p1, NODE *p2, int op) 2146{ 2147 NODE *t, *r; 2148 2149 t = cstknode(p1->n_type, 0, 0); 2150 r = buildtree(ASSIGN, ccopy(t), ccopy(p1)); 2151 r = buildtree(COMOP, r, buildtree(op, p1, eve(p2))); 2152 return buildtree(COMOP, r, t); 2153} 2154 2155/* 2156 * Traverse an unhandled expression tree bottom-up and call buildtree() 2157 * or equivalent as needed. 2158 */ 2159NODE * 2160eve(NODE *p) 2161{ 2162 struct symtab *sp; 2163 NODE *r, *p1, *p2; 2164 int x; 2165 2166 p1 = p->n_left; 2167 p2 = p->n_right; 2168 switch (p->n_op) { 2169 case NMLIST: 2170 case NAME: 2171 sp = cxxlookup(p, SNORMAL|SNOCREAT); 2172 if (sp->sflags & SINLINE) 2173 inline_ref(sp); 2174 r = nametree(sp); 2175 if (sp->sflags & SDYNARRAY) 2176 r = buildtree(UMUL, r, NIL); 2177#ifdef GCC_COMPAT 2178 if (attr_find(sp->sap, GCC_ATYP_DEPRECATED)) 2179 werror("`%s' is deprecated", sp->sname); 2180#endif 2181 break; 2182 2183 case DOT: 2184 case STREF: 2185 r = cxxstructref(eve(p1), p->n_op, (char *)p2->n_sp); 2186 nfree(p2); 2187 break; 2188 2189 case CAST: 2190 p1 = buildtree(CAST, p1, eve(p2)); 2191 nfree(p1->n_left); 2192 r = p1->n_right; 2193 nfree(p1); 2194 break; 2195 2196 2197 case SZOF: 2198 x = xinline; xinline = 0; /* XXX hack */ 2199 if (p2->n_lval == 0) 2200 p1 = eve(p1); 2201 else 2202 TYMFIX(p1); 2203 nfree(p2); 2204 r = doszof(p1); 2205 xinline = x; 2206 break; 2207 2208 case LB: 2209 p1 = eve(p->n_left); 2210 r = buildtree(UMUL, buildtree(PLUS, p1, eve(p2)), NIL); 2211 break; 2212 2213 case COMPL: 2214#ifndef NO_COMPLEX 2215 p1 = eve(p1); 2216 if (ANYCX(p1)) 2217 r = cxconj(p1); 2218 else 2219 r = buildtree(COMPL, p1, NIL); 2220 break; 2221#endif 2222 case UMINUS: 2223 case NOT: 2224 case UMUL: 2225 r = buildtree(p->n_op, eve(p->n_left), NIL); 2226 break; 2227 2228 case ADDROF: 2229 r = eve(p1); 2230 if (ISFTN(p->n_type)/* || ISARY(p->n_type) */){ 2231#ifdef notdef 2232 werror( "& before array or function: ignored" ); 2233#endif 2234 } else 2235 r = buildtree(ADDROF, r, NIL); 2236 break; 2237 2238 case CALL: 2239 p2 = eve(p2); 2240 /* FALLTHROUGH */ 2241 case UCALL: 2242 if (p1->n_op == NAME || p1->n_op == NMLIST) { 2243 sp = cxxlookup(p1, SNORMAL); 2244 if (sp->stype == UNDEF) { 2245 if (!isbuiltin(sp->sname)) 2246 uerror("'%s' undefined", sp->sname); 2247 p1->n_type = FTN|INT; 2248 p1->n_sp = sp; 2249 p1->n_ap = NULL; 2250 defid(p1, EXTERN); 2251 } 2252 nfree(p1); 2253#ifdef GCC_COMPAT 2254 if (attr_find(sp->sap, GCC_ATYP_DEPRECATED)) 2255 werror("`%s' is deprecated", sp->sname); 2256#endif 2257 r = doacall(sp, nametree(sp), p2, 0); 2258 } else if (p1->n_op == DOT || p1->n_op == STREF) { 2259 /* 2260 * function as member of a struct. 2261 * - check args for correct overloaded function 2262 * - add hidden arg0 as pointer to this struct 2263 */ 2264 2265 p1->n_left = eve(p1->n_left); /* eval rest */ 2266 if (p->n_op == UCALL) 2267 p2 = NULL; 2268 r = cxxmatchftn(p1, p2); 2269 if (p1->n_op == DOT) 2270 p1->n_left = buildtree(ADDROF, p1->n_left, NIL); 2271 nfree(p1->n_right); 2272 p1 = nfree(p1); 2273 p2 = cxxaddhidden(p2, p1); 2274 r = doacall(NULL, r, p2, 1); 2275 } else 2276 r = doacall(NULL, eve(p1), p2, 0); 2277 break; 2278 2279#ifndef NO_COMPLEX 2280 case XREAL: 2281 case XIMAG: 2282 p1 = eve(p1); 2283 r = cxelem(p->n_op, p1); 2284 break; 2285#endif 2286 2287 case MUL: 2288 case DIV: 2289 case PLUS: 2290 case MINUS: 2291 case ASSIGN: 2292 case EQ: 2293 case NE: 2294#ifndef NO_COMPLEX 2295 p1 = eve(p1); 2296 p2 = eve(p2); 2297 if (ANYCX(p1) || ANYCX(p2)) { 2298 r = cxop(p->n_op, p1, p2); 2299 } else if (ISITY(p1->n_type) || ISITY(p2->n_type)) { 2300 r = imop(p->n_op, p1, p2); 2301 } else 2302 r = buildtree(p->n_op, p1, p2); 2303 break; 2304#endif 2305 case MOD: 2306 case CM: 2307 case GT: 2308 case GE: 2309 case LT: 2310 case LE: 2311 case RS: 2312 case LS: 2313 case RSEQ: 2314 case LSEQ: 2315 case AND: 2316 case OR: 2317 case ER: 2318 case OROR: 2319 case ANDAND: 2320 case EREQ: 2321 case OREQ: 2322 case ANDEQ: 2323 case QUEST: 2324 case COLON: 2325 p1 = eve(p1); 2326eve2: r = buildtree(p->n_op, p1, eve(p2)); 2327 break; 2328 2329 case INCR: 2330 case DECR: 2331 p1 = eve(p1); 2332 if (p1->n_type >= FLOAT && p1->n_type <= LDOUBLE) { 2333 /* ++/-- on floats isn't ((d+=1)-1) */ 2334 /* rewrite to (t=d,d++,t) */ 2335 /* XXX - side effects */ 2336 r = rewincop(p1, p2, p->n_op); 2337 break; 2338 } 2339 if (p1->n_type != BOOL) 2340 goto eve2; 2341 /* Hey, fun. ++ will always be 1, and -- will toggle result */ 2342 if (p->n_op == INCR) { 2343 /* (t=d,d=1,t) */ 2344 r = rewincop(p1, p2, ASSIGN); 2345 } else { 2346 /* (t=d,d^=1,t) */ 2347 r = rewincop(p1, p2, EREQ); 2348 } 2349 break; 2350 2351 case MODEQ: 2352 case MINUSEQ: 2353 case PLUSEQ: 2354 case MULEQ: 2355 case DIVEQ: 2356 p1 = eve(p1); 2357 p2 = eve(p2); 2358#ifndef NO_COMPLEX 2359 if (ANYCX(p1) || ANYCX(p2)) { 2360 r = cxop(UNASG p->n_op, ccopy(p1), p2); 2361 r = cxop(ASSIGN, p1, r); 2362 break; 2363 } else if (ISITY(p1->n_type) || ISITY(p2->n_type)) { 2364 r = imop(UNASG p->n_op, ccopy(p1), p2); 2365 r = cxop(ASSIGN, p1, r); 2366 break; 2367 } 2368 /* FALLTHROUGH */ 2369#endif 2370 if (p1->n_type == BOOL) { 2371 r = buildtree(UNASG p->n_op, ccopy(p1), p2); 2372 r = buildtree(ASSIGN, p1, r); 2373 } else { 2374 r = buildtree(p->n_op, p1, p2); 2375 } 2376 break; 2377 2378 case STRING: 2379 r = strend(p->n_lval, p->n_name); 2380 break; 2381 2382 case COMOP: 2383 if (p1->n_op == GOTO) { 2384 /* inside ({ }), eve already called */ 2385 r = buildtree(p->n_op, p1, p2); 2386 } else { 2387 p1 = eve(p1); 2388 r = buildtree(p->n_op, p1, eve(p2)); 2389 } 2390 break; 2391 2392 case TYPE: 2393 case ICON: 2394 case FCON: 2395 case TEMP: 2396 return p; 2397 2398 case CLOP: 2399 r = nametree(p->n_sp); 2400 break; 2401 2402 case DELETE: 2403 p1 = eve(p1); 2404 r = cxx_delete(p1, p2->n_lval); 2405 nfree(p2); 2406 break; 2407 2408 case NEWKW: 2409 r = cxx_new(p1); 2410 nfree(p2); 2411 break; 2412 2413 default: 2414#ifdef PCC_DEBUG 2415 fwalk(p, eprint, 0); 2416#endif 2417 cerror("eve"); 2418 r = NIL; 2419 } 2420 nfree(p); 2421 return r; 2422} 2423 2424int 2425con_e(NODE *p) 2426{ 2427#ifdef WORD_ADDRESSED 2428 return icons(optim(eve(p))); 2429#else 2430 return icons(optim(rmpconv(eve(p)))); 2431#endif 2432} 2433 2434void 2435uawarn(NODE *p, char *s) 2436{ 2437 if (p == 0) 2438 return; 2439 if (attrwarn) 2440 werror("unhandled %s attribute", s); 2441 tfree(p); 2442} 2443 2444static void 2445dainit(NODE *d, NODE *a) 2446{ 2447 if (d == NULL) { 2448 asginit(a); 2449 } else if (d->n_op == CM) { 2450 int is = con_e(d->n_left); 2451 int ie = con_e(d->n_right); 2452 int i; 2453 2454 nfree(d); 2455 if (ie < is) 2456 uerror("negative initializer range"); 2457 desinit(biop(LB, NIL, bcon(is))); 2458 for (i = is; i < ie; i++) 2459 asginit(ccopy(a)); 2460 asginit(a); 2461 } else { 2462 cerror("dainit"); 2463 } 2464} 2465 2466/* 2467 * Traverse down and tymerge() where appropriate. 2468 */ 2469static NODE * 2470tymfix(NODE *p) 2471{ 2472 NODE *q; 2473 int o = coptype(p->n_op); 2474 2475 switch (o) { 2476 case LTYPE: 2477 break; 2478 case UTYPE: 2479 p->n_left = tymfix(p->n_left); 2480 break; 2481 case BITYPE: 2482 p->n_left = tymfix(p->n_left); 2483 p->n_right = tymfix(p->n_right); 2484 if (p->n_op == TYMERGE) { 2485 q = tymerge(p->n_left, p->n_right); 2486 q->n_ap = attr_add(q->n_ap, p->n_ap); 2487 tfree(p->n_left); 2488 nfree(p); 2489 p = q; 2490 } 2491 break; 2492 } 2493 return p; 2494} 2495 2496static NODE * 2497aryfix(NODE *p) 2498{ 2499 NODE *q; 2500 2501 for (q = p; q->n_op != NAME; q = q->n_left) { 2502 if (q->n_op == LB) { 2503 q->n_right = optim(rmpconv(eve(q->n_right))); 2504 if ((blevel == 0 || rpole != NULL) && 2505 !nncon(q->n_right)) 2506 uerror("array size not constant"); 2507 /* 2508 * Checks according to 6.7.5.2 clause 1: 2509 * "...the expression shall have an integer type." 2510 * "If the expression is a constant expression, 2511 * it shall have a value greater than zero." 2512 */ 2513 if (!ISINTEGER(q->n_right->n_type)) 2514 werror("array size is not an integer"); 2515 else if (q->n_right->n_op == ICON && 2516 q->n_right->n_lval < 0 && 2517 q->n_right->n_lval != NOOFFSET) { 2518 uerror("array size cannot be negative"); 2519 q->n_right->n_lval = 1; 2520 } 2521 } else if (q->n_op == CALL) 2522 q->n_right = namekill(q->n_right, 1); 2523 } 2524 return p; 2525} 2526