expr.c (18307B)
1 #include "c.h" 2 3 4 static char prec[] = { 5 #define xx(a,b,c,d,e,f,g) c, 6 #define yy(a,b,c,d,e,f,g) c, 7 #include "token.h" 8 }; 9 static int oper[] = { 10 #define xx(a,b,c,d,e,f,g) d, 11 #define yy(a,b,c,d,e,f,g) d, 12 #include "token.h" 13 }; 14 float refinc = 1.0; 15 static Tree expr2(void); 16 static Tree expr3(int); 17 static Tree nullcheck(Tree); 18 static Tree postfix(Tree); 19 static Tree unary(void); 20 static Tree primary(void); 21 static Type super(Type ty); 22 23 static Type super(Type ty) { 24 switch (ty->op) { 25 case INT: 26 if (ty->size < inttype->size) 27 return inttype; 28 break; 29 case UNSIGNED: 30 if (ty->size < unsignedtype->size) 31 return unsignedtype; 32 break; 33 case POINTER: 34 return unsignedptr; 35 } 36 return ty; 37 } 38 Tree expr(int tok) { 39 static char stop[] = { IF, ID, '}', 0 }; 40 Tree p = expr1(0); 41 42 while (t == ',') { 43 Tree q; 44 t = gettok(); 45 q = pointer(expr1(0)); 46 p = tree(RIGHT, q->type, root(value(p)), q); 47 } 48 if (tok) 49 test(tok, stop); 50 return p; 51 } 52 Tree expr0(int tok) { 53 return root(expr(tok)); 54 } 55 Tree expr1(int tok) { 56 static char stop[] = { IF, ID, 0 }; 57 Tree p = expr2(); 58 59 if (t == '=' 60 || (prec[t] >= 6 && prec[t] <= 8) 61 || (prec[t] >= 11 && prec[t] <= 13)) { 62 int op = t; 63 t = gettok(); 64 if (oper[op] == ASGN) 65 p = asgntree(ASGN, p, value(expr1(0))); 66 else 67 { 68 expect('='); 69 p = incr(op, p, expr1(0)); 70 } 71 } 72 if (tok) 73 test(tok, stop); 74 return p; 75 } 76 Tree incr(int op, Tree v, Tree e) { 77 return asgntree(ASGN, v, (*optree[op])(oper[op], v, e)); 78 } 79 static Tree expr2(void) { 80 Tree p = expr3(4); 81 82 if (t == '?') { 83 Tree l, r; 84 Coordinate pts[2]; 85 if (Aflag > 1 && isfunc(p->type)) 86 warning("%s used in a conditional expression\n", 87 funcname(p)); 88 p = pointer(p); 89 t = gettok(); 90 pts[0] = src; 91 l = pointer(expr(':')); 92 pts[1] = src; 93 r = pointer(expr2()); 94 if (events.points) 95 { 96 apply(events.points, &pts[0], &l); 97 apply(events.points, &pts[1], &r); 98 } 99 p = condtree(p, l, r); 100 } 101 return p; 102 } 103 Tree value(Tree p) { 104 int op = generic(rightkid(p)->op); 105 106 if (p->type != voidtype 107 && (op==AND || op==OR || op==NOT || op==EQ || op==NE 108 || op== LE || op==LT || op== GE || op==GT)) 109 p = condtree(p, consttree(1, inttype), 110 consttree(0, inttype)); 111 return p; 112 } 113 static Tree expr3(int k) { 114 int k1; 115 Tree p = unary(); 116 117 for (k1 = prec[t]; k1 >= k; k1--) 118 while (prec[t] == k1 && *cp != '=') { 119 Tree r; 120 Coordinate pt; 121 int op = t; 122 t = gettok(); 123 pt = src; 124 p = pointer(p); 125 if (op == ANDAND || op == OROR) { 126 r = pointer(expr3(k1)); 127 if (events.points) 128 apply(events.points, &pt, &r); 129 } else 130 r = pointer(expr3(k1 + 1)); 131 p = (*optree[op])(oper[op], p, r); 132 } 133 return p; 134 } 135 static Tree unary(void) { 136 Tree p; 137 138 switch (t) { 139 case '*': t = gettok(); p = unary(); p = pointer(p); 140 if (isptr(p->type) 141 && (isfunc(p->type->type) || isarray(p->type->type))) 142 p = retype(p, p->type->type); 143 else { 144 if (YYnull) 145 p = nullcheck(p); 146 p = rvalue(p); 147 } break; 148 case '&': t = gettok(); p = unary(); if (isarray(p->type) || isfunc(p->type)) 149 p = retype(p, ptr(p->type)); 150 else 151 p = lvalue(p); 152 if (isaddrop(p->op) && p->u.sym->sclass == REGISTER) 153 error("invalid operand of unary &; `%s' is declared register\n", p->u.sym->name); 154 155 else if (isaddrop(p->op)) 156 p->u.sym->addressed = 1; 157 break; 158 case '+': t = gettok(); p = unary(); p = pointer(p); 159 if (isarith(p->type)) 160 p = cast(p, promote(p->type)); 161 else 162 typeerror(ADD, p, NULL); break; 163 case '-': t = gettok(); p = unary(); p = pointer(p); 164 if (isarith(p->type)) { 165 Type ty = promote(p->type); 166 p = cast(p, ty); 167 if (isunsigned(ty)) { 168 warning("unsigned operand of unary -\n"); 169 p = simplify(ADD, ty, simplify(BCOM, ty, p, NULL), cnsttree(ty, 1UL)); 170 } else 171 p = simplify(NEG, ty, p, NULL); 172 } else 173 typeerror(SUB, p, NULL); break; 174 case '~': t = gettok(); p = unary(); p = pointer(p); 175 if (isint(p->type)) { 176 Type ty = promote(p->type); 177 p = simplify(BCOM, ty, cast(p, ty), NULL); 178 } else 179 typeerror(BCOM, p, NULL); break; 180 case '!': t = gettok(); p = unary(); p = pointer(p); 181 if (isscalar(p->type)) 182 p = simplify(NOT, inttype, cond(p), NULL); 183 else 184 typeerror(NOT, p, NULL); break; 185 case INCR: t = gettok(); p = unary(); p = incr(INCR, pointer(p), consttree(1, inttype)); break; 186 case DECR: t = gettok(); p = unary(); p = incr(DECR, pointer(p), consttree(1, inttype)); break; 187 case TYPECODE: case SIZEOF: { int op = t; 188 Type ty; 189 p = NULL; 190 t = gettok(); 191 if (t == '(') { 192 t = gettok(); 193 if (istypename(t, tsym)) { 194 ty = typename(); 195 expect(')'); 196 } else { 197 p = postfix(expr(')')); 198 ty = p->type; 199 } 200 } else { 201 p = unary(); 202 ty = p->type; 203 } 204 assert(ty); 205 if (op == TYPECODE) 206 p = cnsttree(inttype, (long)ty->op); 207 else { 208 if (isfunc(ty) || ty->size == 0) 209 error("invalid type argument `%t' to `sizeof'\n", ty); 210 else if (p && rightkid(p)->op == FIELD) 211 error("`sizeof' applied to a bit field\n"); 212 p = cnsttree(unsignedlong, (unsigned long)ty->size); 213 } } break; 214 case '(': 215 t = gettok(); 216 if (istypename(t, tsym)) { 217 Type ty, ty1 = typename(), pty; 218 expect(')'); 219 ty = unqual(ty1); 220 if (isenum(ty)) { 221 Type ty2 = ty->type; 222 if (isconst(ty1)) 223 ty2 = qual(CONST, ty2); 224 if (isvolatile(ty1)) 225 ty2 = qual(VOLATILE, ty2); 226 ty1 = ty2; 227 ty = ty->type; 228 } 229 p = pointer(unary()); 230 pty = p->type; 231 if (isenum(pty)) 232 pty = pty->type; 233 if (isarith(pty) && isarith(ty) 234 || isptr(pty) && isptr(ty)) { 235 explicitCast++; 236 p = cast(p, ty); 237 explicitCast--; 238 } else if (isptr(pty) && isint(ty) 239 || isint(pty) && isptr(ty)) { 240 if (Aflag >= 1 && ty->size < pty->size) 241 warning("conversion from `%t' to `%t' is compiler dependent\n", p->type, ty); 242 243 p = cast(p, ty); 244 } else if (ty != voidtype) { 245 error("cast from `%t' to `%t' is illegal\n", 246 p->type, ty1); 247 ty1 = inttype; 248 } 249 if (generic(p->op) == INDIR || ty->size == 0) 250 p = tree(RIGHT, ty1, NULL, p); 251 else 252 p = retype(p, ty1); 253 } else 254 p = postfix(expr(')')); 255 break; 256 default: 257 p = postfix(primary()); 258 } 259 return p; 260 } 261 262 static Tree postfix(Tree p) { 263 for (;;) 264 switch (t) { 265 case INCR: p = tree(RIGHT, p->type, 266 tree(RIGHT, p->type, 267 p, 268 incr(t, p, consttree(1, inttype))), 269 p); 270 t = gettok(); break; 271 case DECR: p = tree(RIGHT, p->type, 272 tree(RIGHT, p->type, 273 p, 274 incr(t, p, consttree(1, inttype))), 275 p); 276 t = gettok(); break; 277 case '[': { 278 Tree q; 279 t = gettok(); 280 q = expr(']'); 281 if (YYnull) 282 if (isptr(p->type)) 283 p = nullcheck(p); 284 else if (isptr(q->type)) 285 q = nullcheck(q); 286 p = (*optree['+'])(ADD, pointer(p), pointer(q)); 287 if (isptr(p->type) && isarray(p->type->type)) 288 p = retype(p, p->type->type); 289 else 290 p = rvalue(p); 291 } break; 292 case '(': { 293 Type ty; 294 Coordinate pt; 295 p = pointer(p); 296 if (isptr(p->type) && isfunc(p->type->type)) 297 ty = p->type->type; 298 else { 299 error("found `%t' expected a function\n", p->type); 300 ty = func(voidtype, NULL, 1); 301 p = retype(p, ptr(ty)); 302 } 303 pt = src; 304 t = gettok(); 305 p = call(p, ty, pt); 306 } break; 307 case '.': t = gettok(); 308 if (t == ID) { 309 if (isstruct(p->type)) { 310 Tree q = addrof(p); 311 p = field(q, token); 312 q = rightkid(q); 313 if (isaddrop(q->op) && q->u.sym->temporary) 314 p = tree(RIGHT, p->type, p, NULL); 315 } else 316 error("left operand of . has incompatible type `%t'\n", 317 p->type); 318 t = gettok(); 319 } else 320 error("field name expected\n"); break; 321 case DEREF: t = gettok(); 322 p = pointer(p); 323 if (t == ID) { 324 if (isptr(p->type) && isstruct(p->type->type)) { 325 if (YYnull) 326 p = nullcheck(p); 327 p = field(p, token); 328 } else 329 error("left operand of -> has incompatible type `%t'\n", p->type); 330 331 t = gettok(); 332 } else 333 error("field name expected\n"); break; 334 default: 335 return p; 336 } 337 } 338 static Tree primary(void) { 339 Tree p; 340 341 assert(t != '('); 342 switch (t) { 343 case ICON: 344 case FCON: p = tree(mkop(CNST,tsym->type), tsym->type, NULL, NULL); 345 p->u.v = tsym->u.c.v; 346 break; 347 case SCON: if (ischar(tsym->type->type)) 348 tsym->u.c.v.p = stringn(tsym->u.c.v.p, tsym->type->size); 349 else 350 tsym->u.c.v.p = memcpy(allocate(tsym->type->size, PERM), tsym->u.c.v.p, tsym->type->size); 351 tsym = constant(tsym->type, tsym->u.c.v); 352 if (tsym->u.c.loc == NULL) 353 tsym->u.c.loc = genident(STATIC, tsym->type, GLOBAL); 354 p = idtree(tsym->u.c.loc); break; 355 case ID: if (tsym == NULL) 356 { 357 Symbol p = install(token, &identifiers, level, FUNC); 358 p->src = src; 359 if (getchr() == '(') { 360 Symbol q = lookup(token, externals); 361 p->type = func(inttype, NULL, 1); 362 p->sclass = EXTERN; 363 if (Aflag >= 1) 364 warning("missing prototype\n"); 365 if (q && !eqtype(q->type, p->type, 1)) 366 warning("implicit declaration of `%s' does not match previous declaration at %w\n", q->name, &q->src); 367 368 if (q == NULL) { 369 q = install(p->name, &externals, GLOBAL, PERM); 370 q->type = p->type; 371 q->sclass = EXTERN; 372 q->src = src; 373 (*IR->defsymbol)(q); 374 } 375 p->u.alias = q; 376 } else { 377 error("undeclared identifier `%s'\n", p->name); 378 p->sclass = AUTO; 379 p->type = inttype; 380 if (p->scope == GLOBAL) 381 (*IR->defsymbol)(p); 382 else 383 addlocal(p); 384 } 385 t = gettok(); 386 if (xref) 387 use(p, src); 388 return idtree(p); 389 } 390 if (xref) 391 use(tsym, src); 392 if (tsym->sclass == ENUM) 393 p = consttree(tsym->u.value, inttype); 394 else { 395 if (tsym->sclass == TYPEDEF) 396 error("illegal use of type name `%s'\n", tsym->name); 397 p = idtree(tsym); 398 } break; 399 case FIRSTARG: 400 if (level > PARAM && cfunc && cfunc->u.f.callee[0]) 401 p = idtree(cfunc->u.f.callee[0]); 402 else { 403 error("illegal use of `%k'\n", FIRSTARG); 404 p = cnsttree(inttype, 0L); 405 } 406 break; 407 default: 408 error("illegal expression\n"); 409 p = cnsttree(inttype, 0L); 410 } 411 t = gettok(); 412 return p; 413 } 414 Tree idtree(Symbol p) { 415 int op; 416 Tree e; 417 Type ty = p->type ? unqual(p->type) : voidptype; 418 419 if (p->scope == GLOBAL || p->sclass == STATIC) 420 op = ADDRG; 421 else if (p->scope == PARAM) { 422 op = ADDRF; 423 if (isstruct(p->type) && !IR->wants_argb) 424 { 425 e = tree(mkop(op,voidptype), ptr(ptr(p->type)), NULL, NULL); 426 e->u.sym = p; 427 return rvalue(rvalue(e)); 428 } 429 } else if (p->sclass == EXTERN) { 430 assert(p->u.alias); 431 p = p->u.alias; 432 op = ADDRG; 433 } else 434 op = ADDRL; 435 p->ref += refinc; 436 if (isarray(ty)) 437 e = tree(mkop(op,voidptype), p->type, NULL, NULL); 438 else if (isfunc(ty)) 439 e = tree(mkop(op,funcptype), p->type, NULL, NULL); 440 else 441 e = tree(mkop(op,voidptype), ptr(p->type), NULL, NULL); 442 e->u.sym = p; 443 if (isptr(e->type)) 444 e = rvalue(e); 445 return e; 446 } 447 448 Tree rvalue(Tree p) { 449 Type ty = deref(p->type); 450 451 ty = unqual(ty); 452 return tree(mkop(INDIR,ty), ty, p, NULL); 453 } 454 Tree lvalue(Tree p) { 455 if (generic(p->op) != INDIR) { 456 error("lvalue required\n"); 457 return value(p); 458 } else if (unqual(p->type) == voidtype) 459 warning("`%t' used as an lvalue\n", p->type); 460 return p->kids[0]; 461 } 462 Tree retype(Tree p, Type ty) { 463 Tree q; 464 465 if (p->type == ty) 466 return p; 467 q = tree(p->op, ty, p->kids[0], p->kids[1]); 468 q->node = p->node; 469 q->u = p->u; 470 return q; 471 } 472 Tree rightkid(Tree p) { 473 while (p && p->op == RIGHT) 474 if (p->kids[1]) 475 p = p->kids[1]; 476 else if (p->kids[0]) 477 p = p->kids[0]; 478 else 479 assert(0); 480 assert(p); 481 return p; 482 } 483 int hascall(Tree p) { 484 if (p == 0) 485 return 0; 486 if (generic(p->op) == CALL || (IR->mulops_calls && 487 (p->op == DIV+I || p->op == MOD+I || p->op == MUL+I 488 || p->op == DIV+U || p->op == MOD+U || p->op == MUL+U))) 489 return 1; 490 return hascall(p->kids[0]) || hascall(p->kids[1]); 491 } 492 Type binary(Type xty, Type yty) { 493 #define xx(t) if (xty == t || yty == t) return t 494 xx(longdouble); 495 xx(doubletype); 496 xx(floattype); 497 xx(unsignedlonglong); 498 xx(longlong); 499 xx(unsignedlong); 500 if (xty == longtype && yty == unsignedtype 501 || xty == unsignedtype && yty == longtype) 502 if (longtype->size > unsignedtype->size) 503 return longtype; 504 else 505 return unsignedlong; 506 xx(longtype); 507 xx(unsignedtype); 508 return inttype; 509 #undef xx 510 } 511 Tree pointer(Tree p) { 512 if (isarray(p->type)) 513 /* assert(p->op != RIGHT || p->u.sym == NULL), */ 514 p = retype(p, atop(p->type)); 515 else if (isfunc(p->type)) 516 p = retype(p, ptr(p->type)); 517 return p; 518 } 519 Tree cond(Tree p) { 520 int op = generic(rightkid(p)->op); 521 522 if (op == AND || op == OR || op == NOT 523 || op == EQ || op == NE 524 || op == LE || op == LT || op == GE || op == GT) 525 return p; 526 p = pointer(p); 527 return (*optree[NEQ])(NE, p, consttree(0, inttype)); 528 } 529 Tree cast(Tree p, Type type) { 530 Type src, dst; 531 532 p = value(p); 533 if (p->type == type) 534 return p; 535 dst = unqual(type); 536 src = unqual(p->type); 537 if (src->op != dst->op || src->size != dst->size) { 538 switch (src->op) { 539 case INT: 540 if (src->size < inttype->size) 541 p = simplify(CVI, inttype, p, NULL); 542 break; 543 case UNSIGNED: 544 if (src->size < inttype->size) 545 p = simplify(CVU, inttype, p, NULL); 546 else if (src->size < unsignedtype->size) 547 p = simplify(CVU, unsignedtype, p, NULL); 548 break; 549 case ENUM: 550 p = retype(p, inttype); 551 break; 552 case POINTER: 553 if (isint(dst) && src->size > dst->size) 554 warning("conversion from `%t' to `%t' is undefined\n", p->type, type); 555 p = simplify(CVP, super(src), p, NULL); 556 break; 557 case FLOAT: 558 break; 559 default: assert(0); 560 } 561 { 562 src = unqual(p->type); 563 dst = super(dst); 564 if (src->op != dst->op) 565 switch (src->op) { 566 case INT: 567 p = simplify(CVI, dst, p, NULL); 568 break; 569 case UNSIGNED: 570 if (isfloat(dst)) { 571 Type ssrc = signedint(src); 572 Tree two = cnsttree(longdouble, (long double)2.0); 573 p = (*optree['+'])(ADD, 574 (*optree['*'])(MUL, 575 two, 576 simplify(CVU, ssrc, 577 simplify(RSH, src, 578 p, consttree(1, inttype)), NULL)), 579 simplify(CVU, ssrc, 580 simplify(BAND, src, 581 p, consttree(1, unsignedtype)), NULL)); 582 } else 583 p = simplify(CVU, dst, p, NULL); 584 break; 585 case FLOAT: 586 if (isunsigned(dst)) { 587 Type sdst = signedint(dst); 588 Tree c = cast(cnsttree(longdouble, (long double)sdst->u.sym->u.limits.max.i + 1), src); 589 p = condtree( 590 simplify(GE, src, p, c), 591 (*optree['+'])(ADD, 592 cast(cast(simplify(SUB, src, p, c), sdst), dst), 593 cast(cnsttree(unsignedlong, (unsigned long)sdst->u.sym->u.limits.max.i + 1), dst)), 594 simplify(CVF, sdst, p, NULL)); 595 } else 596 p = simplify(CVF, dst, p, NULL); 597 break; 598 default: assert(0); 599 } 600 dst = unqual(type); 601 } 602 } 603 src = unqual(p->type); 604 switch (src->op) { 605 case INT: 606 if (src->op != dst->op || src->size != dst->size) 607 p = simplify(CVI, dst, p, NULL); 608 break; 609 case UNSIGNED: 610 if (src->op != dst->op || src->size != dst->size) 611 p = simplify(CVU, dst, p, NULL); 612 break; 613 case FLOAT: 614 if (src->op != dst->op || src->size != dst->size) 615 p = simplify(CVF, dst, p, NULL); 616 break; 617 case POINTER: 618 if (src->op != dst->op) 619 p = simplify(CVP, dst, p, NULL); 620 else { 621 if (isfunc(src->type) && !isfunc(dst->type) 622 || !isfunc(src->type) && isfunc(dst->type)) 623 warning("conversion from `%t' to `%t' is compiler dependent\n", p->type, type); 624 625 if (src->size != dst->size) 626 p = simplify(CVP, dst, p, NULL); 627 } 628 break; 629 default: assert(0); 630 } 631 return retype(p, type); 632 } 633 Tree field(Tree p, const char *name) { 634 Field q; 635 Type ty1, ty = p->type; 636 637 if (isptr(ty)) 638 ty = deref(ty); 639 ty1 = ty; 640 ty = unqual(ty); 641 if ((q = fieldref(name, ty)) != NULL) { 642 if (isarray(q->type)) { 643 ty = q->type->type; 644 if (isconst(ty1) && !isconst(ty)) 645 ty = qual(CONST, ty); 646 if (isvolatile(ty1) && !isvolatile(ty)) 647 ty = qual(VOLATILE, ty); 648 ty = array(ty, q->type->size/ty->size, q->type->align); 649 } else { 650 ty = q->type; 651 if (isconst(ty1) && !isconst(ty)) 652 ty = qual(CONST, ty); 653 if (isvolatile(ty1) && !isvolatile(ty)) 654 ty = qual(VOLATILE, ty); 655 ty = ptr(ty); 656 } 657 if (YYcheck && !isaddrop(p->op) && q->offset > 0) /* omit */ 658 p = nullcall(ty, YYcheck, p, consttree(q->offset, inttype)); /* omit */ 659 else /* omit */ 660 p = simplify(ADD+P, ty, p, consttree(q->offset, inttype)); 661 662 if (q->lsb) { 663 p = tree(FIELD, ty->type, rvalue(p), NULL); 664 p->u.field = q; 665 } else if (!isarray(q->type)) 666 p = rvalue(p); 667 668 } else { 669 error("unknown field `%s' of `%t'\n", name, ty); 670 p = rvalue(retype(p, ptr(inttype))); 671 } 672 return p; 673 } 674 /* funcname - return name of function f or a function' */ 675 char *funcname(Tree f) { 676 if (isaddrop(f->op)) 677 return stringf("`%s'", f->u.sym->name); 678 return "a function"; 679 } 680 static Tree nullcheck(Tree p) { 681 if (!needconst && YYnull && isptr(p->type)) { 682 p = value(p); 683 if (strcmp(YYnull->name, "_YYnull") == 0) { 684 Symbol t1 = temporary(REGISTER, voidptype); 685 p = tree(RIGHT, p->type, 686 tree(OR, voidtype, 687 cond(asgn(t1, cast(p, voidptype))), 688 vcall(YYnull, voidtype, (file && *file ? pointer(idtree(mkstr(file)->u.c.loc)) : cnsttree(voidptype, NULL)), cnsttree(inttype, (long)lineno) , NULL)), 689 idtree(t1)); 690 } 691 692 else 693 p = nullcall(p->type, YYnull, p, cnsttree(inttype, 0L)); 694 695 } 696 return p; 697 } 698 Tree nullcall(Type pty, Symbol f, Tree p, Tree e) { 699 Type ty; 700 701 if (isarray(pty)) 702 return retype(nullcall(atop(pty), f, p, e), pty); 703 ty = unqual(unqual(p->type)->type); 704 return vcall(f, pty, 705 p, e, 706 cnsttree(inttype, (long)ty->size), 707 cnsttree(inttype, (long)ty->align), 708 (file && *file ? pointer(idtree(mkstr(file)->u.c.loc)) : cnsttree(voidptype, NULL)), cnsttree(inttype, (long)lineno) , NULL); 709 }