scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | README | LICENSE

expr.c (21191B)


      1 static char sccsid[] = "@(#) ./cc1/expr.c";
      2 #include <assert.h>
      3 #include <stdlib.h>
      4 #include <string.h>
      5 
      6 #include <scc/cstd.h>
      7 #include <scc/scc.h>
      8 #include "cc1.h"
      9 
     10 #define XCHG(lp, rp, np) (np = lp, lp = rp, rp = np)
     11 
     12 static Node *xexpr(void), *xassign(void);
     13 
     14 int
     15 cmpnode(Node *np, TUINT val)
     16 {
     17 	Symbol *sym;
     18 	Type *tp;
     19 	TUINT mask, nodeval;
     20 
     21 	if (!np || !(np->flags & NCONST) || !np->sym)
     22 		return 0;
     23 	sym = np->sym;
     24 	tp = sym->type;
     25 
     26 	switch (tp->op) {
     27 	case PTR:
     28 	case INT:
     29 		mask = (val > 1) ? ones(np->type->size) : -1;
     30 		nodeval = (tp->prop & TSIGNED) ? sym->u.i : sym->u.u;
     31 		return (nodeval & mask) == (val & mask);
     32 	case FLOAT:
     33 		return sym->u.f == val;
     34 	}
     35 	return 0;
     36 }
     37 
     38 static Node *
     39 promote(Node *np)
     40 {
     41 	Type *tp;
     42 	Node *new;
     43 	struct limits *lim, *ilim;
     44 
     45 	tp = np->type;
     46 
     47 	switch (tp->op) {
     48 	case ENUM:
     49 	case INT:
     50 		if (tp->n.rank >= inttype->n.rank)
     51 			return np;
     52 		lim = getlimits(tp);
     53 		ilim = getlimits(inttype);
     54 		tp = (lim->max.i <= ilim->max.i) ? inttype : uinttype;
     55 		break;
     56 	case FLOAT:
     57 		/* TODO: Add support for C99 float math */
     58 		tp = doubletype;
     59 		break;
     60 	default:
     61 		abort();
     62 	}
     63 	if ((new = convert(np, tp, 1)) != NULL)
     64 		return new;
     65 	return np;
     66 }
     67 
     68 static void
     69 arithconv(Node **p1, Node **p2)
     70 {
     71 	int to = 0, s1, s2;
     72 	unsigned r1, r2;
     73 	Type *tp1, *tp2;
     74 	Node *np1, *np2;
     75 	struct limits *lp1, *lp2;
     76 
     77 	np1 = promote(*p1);
     78 	np2 = promote(*p2);
     79 
     80 	tp1 = np1->type;
     81 	tp2 = np2->type;
     82 
     83 	if (tp1 == tp2)
     84 		goto set_p1_p2;
     85 
     86 	s1 = (tp1->prop & TSIGNED) != 0;
     87 	r1 = tp1->n.rank;
     88 	lp1 = getlimits(tp1);
     89 
     90 	s2 = (tp2->prop & TSIGNED) != 0;
     91 	r2 = tp2->n.rank;
     92 	lp2 = getlimits(tp2);
     93 
     94 	if (s1 == s2 || tp1->op == FLOAT || tp2->op == FLOAT) {
     95 		to = r1 - r2;
     96 	} else if (!s1) {
     97 		if (r1 >= r2 || lp1->max.i >= lp2->max.i)
     98 			to = 1;
     99 		else
    100 			to = -1;
    101 	} else {
    102 		if (r2 >= r1 || lp2->max.i >= lp1->max.i)
    103 			to = -1;
    104 		else
    105 			to = 1;
    106 	}
    107 
    108 	if (to > 0)
    109 		np2 = convert(np2, tp1, 1);
    110 	else if (to < 0)
    111 		np1 = convert(np1, tp2, 1);
    112 		
    113 set_p1_p2:
    114 	*p1 = np1;
    115 	*p2 = np2;
    116 }
    117 
    118 static int
    119 null(Node *np)
    120 {
    121 	if (np->type != pvoidtype || np->op != OCAST)
    122 		return 0;
    123 
    124 	np = np->left;
    125 	if (np->type != inttype)
    126 		return 0;
    127 
    128 	return cmpnode(np, 0);
    129 }
    130 
    131 static Node *
    132 chkternary(Node *yes, Node *no)
    133 {
    134 	/*
    135 	 * FIXME:
    136 	 * We are ignoring type qualifiers here,
    137 	 * but the standard has strong rules about this.
    138 	 * take a look to 6.5.15
    139 	 */
    140 
    141 	if (!eqtype(yes->type, no->type, 1)) {
    142 		if ((yes->type->prop & TARITH) && (no->type->prop & TARITH)) {
    143 			arithconv(&yes, &no);
    144 		} else if (yes->type->op != PTR && no->type->op != PTR) {
    145 			goto wrong_type;
    146 		} else {
    147 			/* convert integer 0 to NULL */
    148 			if ((yes->type->prop & TINTEGER) && cmpnode(yes, 0))
    149 				yes = convert(yes, pvoidtype, 0);
    150 			if ((no->type->prop & TINTEGER) && cmpnode(no, 0))
    151 				no = convert(no, pvoidtype, 0);
    152 			/*
    153 			 * At this point the type of both should be
    154 			 * a pointer to something, or we have don't
    155 			 * compatible types
    156 			 */
    157 			if (yes->type->op != PTR || no->type->op != PTR)
    158 				goto wrong_type;
    159 			/*
    160 			 * If we have a null pointer constant then
    161 			 * convert to the another type
    162 			 */
    163 			if (null(yes))
    164 				yes = convert(yes, no->type, 0);
    165 			if (null(no))
    166 				no = convert(no, yes->type, 0);
    167 
    168 			if (!eqtype(yes->type, no->type, 1))
    169 				goto wrong_type;
    170 		}
    171 	}
    172 	return node(OCOLON, yes->type, yes, no);
    173 
    174 wrong_type:
    175 	errorp("type mismatch in conditional expression");
    176 	freetree(yes);
    177 	freetree(no);
    178 	return constnode(zero);
    179 }
    180 
    181 static void
    182 chklvalue(Node *np)
    183 {
    184 	if (!(np->flags & NLVAL))
    185 		errorp("lvalue required in operation");
    186 	if (np->type == voidtype)
    187 		errorp("invalid use of void expression");
    188 }
    189 
    190 Node *
    191 decay(Node *np)
    192 {
    193 	Node *new;
    194 	Type *tp = np->type;
    195 
    196 	switch (tp->op) {
    197 	case ARY:
    198 		tp = tp->type;
    199 		if (np->op == OPTR) {
    200 			new = np->left;
    201 			free(np);
    202 			new->type = mktype(tp, PTR, 0, NULL);
    203 			return new;
    204 		}
    205 	case FTN:
    206 		new = node(OADDR, mktype(tp, PTR, 0, NULL), np, NULL);
    207 		if (np->sym && np->sym->flags & (SGLOBAL|SLOCAL|SPRIVATE))
    208 			new->flags |= NCONST;
    209 		return new;
    210 	default:
    211 		return np;
    212 	}
    213 }
    214 
    215 static Node *
    216 integerop(int op, Node *lp, Node *rp)
    217 {
    218 	if (!(lp->type->prop & TINTEGER) || !(rp->type->prop & TINTEGER))
    219 		error("operator requires integer operands");
    220 	arithconv(&lp, &rp);
    221 	return node(op, lp->type, lp, rp);
    222 }
    223 
    224 static Node *
    225 integeruop(int op, Node *np)
    226 {
    227 	if (!(np->type->prop & TINTEGER))
    228 		error("unary operator requires integer operand");
    229 	np = promote(np);
    230 	return node(op, np->type, np, NULL);
    231 }
    232 
    233 static Node *
    234 numericaluop(int op, Node *np)
    235 {
    236 	if (!(np->type->prop & TARITH))
    237 		error("unary operator requires numerical operand");
    238 	np = promote(np);
    239 	return node(op, np->type, np, NULL);
    240 }
    241 
    242 Node *
    243 convert(Node *np, Type *newtp, int iscast)
    244 {
    245 	Type *oldtp = np->type;
    246 
    247 	if (eqtype(newtp, oldtp, 0))
    248 		return np;
    249 
    250 	switch (oldtp->op) {
    251 	case ENUM:
    252 	case INT:
    253 	case FLOAT:
    254 		switch (newtp->op) {
    255 		case PTR:
    256 			if (oldtp->op == FLOAT || !cmpnode(np, 0) && !iscast)
    257 				return NULL;
    258 		case INT:
    259 		case FLOAT:
    260 		case ENUM:
    261 			break;
    262 		default:
    263 			return NULL;
    264 		}
    265 		break;
    266 	case PTR:
    267 		switch (newtp->op) {
    268 		case ENUM:
    269 		case INT:
    270 		case VOID:
    271 			if (!iscast)
    272 				return NULL;
    273 			break;
    274 		case PTR:
    275 			if (eqtype(newtp, oldtp, 1) ||
    276 			    iscast ||
    277 			    newtp == pvoidtype || oldtp == pvoidtype) {
    278 				np->type = newtp;
    279 				return np;
    280 			}
    281 		default:
    282 			return NULL;
    283 		}
    284 		break;
    285 	default:
    286 		return NULL;
    287 	}
    288 	return node(OCAST, newtp, np, NULL);
    289 }
    290 
    291 static Node *
    292 parithmetic(int op, Node *lp, Node *rp)
    293 {
    294 	Type *tp;
    295 	Node *size, *np;
    296 
    297 	if (lp->type->op != PTR)
    298 		XCHG(lp, rp, np);
    299 
    300 	tp = rp->type;
    301 	if (tp->op == PTR && !(tp->type->prop & TDEFINED))
    302 		goto incomplete;
    303 	tp = lp->type;
    304 	if (!(tp->type->prop & TDEFINED))
    305 		goto incomplete;
    306 	size = sizeofnode(tp->type);
    307 
    308 	if (op == OSUB && BTYPE(rp) == PTR) {
    309 		if ((rp = convert(rp, lp->type, 0)) == NULL)
    310 			goto incorrect;
    311 		lp = node(OSUB, pdifftype, lp, rp);
    312 		return node(ODIV, inttype, lp, size);
    313 	}
    314 	if (!(rp->type->prop & TINTEGER))
    315 		goto incorrect;
    316 
    317 	rp = convert(promote(rp), sizettype, 0);
    318 	rp = node(OMUL, sizettype, rp, size);
    319 	rp = convert(rp, tp, 1);
    320 
    321 	return node(op, tp, lp, rp);
    322 
    323 incomplete:
    324 	errorp("invalid use of undefined type");
    325 	return lp;
    326 incorrect:
    327 	errorp("incorrect arithmetic operands");
    328 	return lp;
    329 
    330 }
    331 
    332 static Node *
    333 arithmetic(int op, Node *lp, Node *rp)
    334 {
    335 	Type *ltp = lp->type, *rtp = rp->type;
    336 
    337 	if ((ltp->prop & TARITH) && (rtp->prop & TARITH)) {
    338 		arithconv(&lp, &rp);
    339 		return node(op, lp->type, lp, rp);
    340 	} else if ((ltp->op == PTR || rtp->op == PTR)) {
    341 		switch (op) {
    342 		case OADD:
    343 		case OSUB:
    344 		case OA_ADD:
    345 		case OA_SUB:
    346 		case OINC:
    347 		case ODEC:
    348 			return parithmetic(op, lp, rp);
    349 		}
    350 	}
    351 	errorp("incorrect arithmetic operands");
    352 }
    353 
    354 static Node *
    355 pcompare(int op, Node *lp, Node *rp)
    356 {
    357 	Node *np;
    358 
    359 	if (lp->type->prop & TINTEGER)
    360 		XCHG(lp, rp, np);
    361 	else if (eqtype(lp->type, pvoidtype, 1))
    362 		XCHG(lp, rp, np);
    363 
    364 	if ((np = convert(rp, lp->type, 0)) != NULL)
    365 		rp = np;
    366 	else
    367 		errorp("incompatible types in comparison");
    368 	return convert(node(op, pvoidtype, lp, rp), inttype, 1);
    369 }
    370 
    371 static Node *
    372 compare(int op, Node *lp, Node *rp)
    373 {
    374 	Type *ltp, *rtp;
    375 
    376 	ltp = lp->type;
    377 	rtp = rp->type;
    378 
    379 	if (ltp->op == PTR || rtp->op == PTR) {
    380 		return pcompare(op, rp, lp);
    381 	} else if ((ltp->prop & TARITH) && (rtp->prop & TARITH)) {
    382 		arithconv(&lp, &rp);
    383 		return convert(node(op, lp->type, lp, rp), inttype, 1);;
    384 	} else {
    385 		errorp("incompatible types in comparison");
    386 		freetree(lp);
    387 		freetree(rp);
    388 		return constnode(zero);
    389 	}
    390 }
    391 
    392 int
    393 negop(int op)
    394 {
    395 	switch (op) {
    396 	case OEQ:  return ONE;
    397 	case ONE:  return OEQ;
    398 	case OLT:  return OGE;
    399 	case OGE:  return OLT;
    400 	case OLE:  return OGT;
    401 	case OGT:  return OLE;
    402 	default:   abort();
    403 	}
    404 	return op;
    405 }
    406 
    407 static Node *
    408 exp2cond(Node *np, int neg)
    409 {
    410 	if (np->type->prop & TAGGREG) {
    411 		errorp("used struct/union type value where scalar is required");
    412 		return constnode(zero);
    413 	}
    414 	switch (np->op) {
    415 	case ONEG:
    416 	case OOR:
    417 	case OAND:
    418 		return (neg) ? node(ONEG, inttype, np, NULL) : np;
    419 	case OEQ:
    420 	case ONE:
    421 	case OLT:
    422 	case OGE:
    423 	case OLE:
    424 	case OGT:
    425 		if (neg)
    426 			np->op = negop(np->op);
    427 		return np;
    428 	default:
    429 		return compare((neg) ?  OEQ : ONE, np, constnode(zero));
    430 	}
    431 }
    432 
    433 static Node *
    434 logic(int op, Node *lp, Node *rp)
    435 {
    436 	lp = exp2cond(lp, 0);
    437 	rp = exp2cond(rp, 0);
    438 	return node(op, inttype, lp, rp);
    439 }
    440 
    441 static Node *
    442 field(Node *np)
    443 {
    444 	Symbol *sym;
    445 
    446 	namespace = np->type->ns;
    447 	next();
    448 	namespace = NS_IDEN;
    449 
    450 	sym = yylval.sym;
    451 	if (yytoken != IDEN)
    452 		unexpected();
    453 	next();
    454 
    455 	if (!(np->type->prop & TAGGREG)) {
    456 		errorp("request for member '%s' in something not a structure or union",
    457 		      yylval.sym->name);
    458 		goto free_np;
    459 	}
    460 	if ((sym->flags & SDECLARED) == 0) {
    461 		errorp("incorrect field in struct/union");
    462 		goto free_np;
    463 	}
    464 	np = node(OFIELD, sym->type, np, varnode(sym));
    465 	np->flags |= NLVAL;
    466 	return np;
    467 
    468 free_np:
    469 	freetree(np);
    470 	return constnode(zero);
    471 }
    472 
    473 static Node *
    474 content(int op, Node *np)
    475 {
    476 	if (BTYPE(np) != PTR) {
    477 		errorp("invalid argument of memory indirection");
    478 	} else {
    479 		if (np->op == OADDR) {
    480 			Node *new = np->left;
    481 			new->type = np->type->type;
    482 			free(np);
    483 			np = new;
    484 		} else {
    485 			np = node(op, np->type->type, np, NULL);
    486 		}
    487 		np->flags |= NLVAL;
    488 	}
    489 	return np;
    490 }
    491 
    492 static Node *
    493 array(Node *lp, Node *rp)
    494 {
    495 	Type *tp;
    496 	Node *np;
    497 
    498 	if (!(lp->type->prop & TINTEGER) && !(rp->type->prop & TINTEGER))
    499 		error("array subscript is not an integer");
    500 	np = arithmetic(OADD, lp, rp);
    501 	tp = np->type;
    502 	if (tp->op != PTR)
    503 		errorp("subscripted value is neither array nor pointer");
    504 	return content(OPTR, np);
    505 }
    506 
    507 static Node *
    508 assignop(int op, Node *lp, Node *rp)
    509 {
    510 	if ((rp = convert(rp, lp->type, 0)) == NULL) {
    511 		errorp("incompatible types when assigning");
    512 		return lp;
    513 	}
    514 
    515 	return node(op, lp->type, lp, rp);
    516 }
    517 
    518 static Node *
    519 incdec(Node *np, int op)
    520 {
    521 	Type *tp = np->type;
    522 	Node *inc;
    523 
    524 	chklvalue(np);
    525 	np->flags |= NEFFECT;
    526 
    527 	if (!(tp->prop & TDEFINED)) {
    528 		errorp("invalid use of undefined type");
    529 		return np;
    530 	} else if (tp->op == PTR && !(tp->type->prop & TDEFINED)) {
    531 		errorp("%s of pointer to an incomplete type",
    532 		       (op == OINC || op == OA_ADD) ? "increment" : "decrement");
    533 		return np;
    534 	} else if (tp->op == PTR || (tp->prop & TARITH)) {
    535 		inc = constnode(one);
    536 	} else {
    537 		errorp("wrong type argument to increment or decrement");
    538 		return np;
    539 	}
    540 	return arithmetic(op, np, inc);
    541 }
    542 
    543 static Node *
    544 address(int op, Node *np)
    545 {
    546 	Node *new;
    547 
    548 	/*
    549 	 * ansi c accepts & applied to a function name, and it generates
    550 	 * a function pointer
    551 	 */
    552 	if (np->op == OSYM) {
    553 		if (np->type->op == FTN)
    554 			return decay(np);
    555 		if (np->type->op == ARY)
    556 			goto dont_check_lvalue;
    557 	}
    558 	chklvalue(np);
    559 
    560 dont_check_lvalue:
    561 	if (np->sym && (np->sym->flags & SREGISTER))
    562 		errorp("address of register variable '%s' requested", yytext);
    563 	new = node(op, mktype(np->type, PTR, 0, NULL), np, NULL);
    564 	if (np->sym && np->sym->flags & (SGLOBAL|SLOCAL|SPRIVATE))
    565 		new->flags |= NCONST;
    566 	return new;
    567 }
    568 
    569 static Node *
    570 negation(int op, Node *np)
    571 {
    572 	if (!(np->type->prop & TARITH) && np->type->op != PTR) {
    573 		errorp("invalid argument of unary '!'");
    574 		return constnode(zero);
    575 	}
    576 	return exp2cond(np, 1);
    577 }
    578 
    579 static Symbol *
    580 notdefined(Symbol *sym)
    581 {
    582 	int isdef;
    583 
    584 	if (namespace == NS_CPP && !strcmp(sym->name, "defined")) {
    585 		disexpand = 1;
    586 		next();
    587 		expect('(');
    588 		sym = yylval.sym;
    589 		expect(IDEN);
    590 		expect(')');
    591 
    592 		isdef = (sym->flags & SDECLARED) != 0;
    593 		sym = newsym(NS_IDEN, NULL);
    594 		sym->type = inttype;
    595 		sym->flags |= SCONSTANT;
    596 		sym->u.i = isdef;
    597 		disexpand = 0;
    598 		return sym;
    599 	}
    600 	errorp("'%s' undeclared", yytext);
    601 	sym->type = inttype;
    602 	return install(sym->ns, yylval.sym);
    603 }
    604 
    605 static Symbol *
    606 adjstrings(Symbol *sym)
    607 {
    608 	char *s, *t;
    609 	size_t len, n;
    610 	Type *tp;
    611 
    612 	tp = sym->type;
    613 	s = sym->u.s;
    614 	for (len = strlen(s);; len += n) {
    615 		next();
    616 		if (yytoken != STRING)
    617 			break;
    618 		t = yylval.sym->u.s;
    619 		n = strlen(t);
    620 		s = xrealloc(s, len + n + 1);
    621 		memcpy(s+len, t, n);
    622 		s[len + n] = '\0';
    623 		killsym(yylval.sym);
    624 	}
    625 	++len;
    626 	if (tp->n.elem != len) {
    627 		sym->type = mktype(chartype, ARY, len, NULL);
    628 		sym->u.s = s;
    629 	}
    630 	return sym;
    631 }
    632 
    633 /*************************************************************
    634  * grammar functions                                         *
    635  *************************************************************/
    636 static Node *
    637 primary(void)
    638 {
    639 	Node *np;
    640 	Symbol *sym;
    641 	Node *(*fun)(Symbol *);
    642 
    643 	sym = yylval.sym;
    644 	switch (yytoken) {
    645 	case STRING:
    646 		np = constnode(adjstrings(sym));
    647 		sym->flags |= SHASINIT;
    648 		emit(ODECL, sym);
    649 		emit(OINIT, np);
    650 		return varnode(sym);
    651 	case BUILTIN:
    652 		fun = sym->u.fun;
    653 		next();
    654 		expect('(');
    655 		np = (*fun)(sym);
    656 		expect(')');
    657 
    658 		/* do not call to next */
    659 		return np;
    660 	case CONSTANT:
    661 		np = constnode(sym);
    662 		break;
    663 	case IDEN:
    664 		assert((sym->flags & SCONSTANT) == 0);
    665 		if ((sym->flags & SDECLARED) == 0) {
    666 			if (namespace == NS_CPP) {
    667 				np = constnode(zero);
    668 				break;
    669 			}
    670 			sym = notdefined(sym);
    671 		}
    672 		sym->flags |= SUSED;
    673 		np = varnode(sym);
    674 		break;
    675 	default:
    676 		unexpected();
    677 	}
    678 	next();
    679 
    680 	return np;
    681 }
    682 
    683 static Node *
    684 arguments(Node *np)
    685 {
    686 	int toomany, n, op;
    687 	Node *par = NULL, *arg;
    688 	Type *argtype, **targs, *tp = np->type, *rettype;
    689 
    690 	if (tp->op == PTR && tp->type->op == FTN) {
    691 		np = content(OPTR, np);
    692 		tp = np->type;
    693 	}
    694 	if (tp->op != FTN) {
    695 		targs = (Type *[]) {ellipsistype};
    696 		n = 1;
    697 		rettype = inttype;
    698 		errorp("function or function pointer expected");
    699 	} else {
    700 		targs = tp->p.pars;
    701 		n = tp->n.elem;
    702 		rettype = tp->type;
    703 	}
    704 
    705 	expect('(');
    706 	if (yytoken == ')')
    707 		goto no_pars;
    708 	toomany = 0;
    709 
    710 	do {
    711 		arg = xassign();
    712 		argtype = *targs;
    713 		if (argtype == ellipsistype) {
    714 			n = 0;
    715 			switch (arg->type->op) {
    716 			case INT:
    717 				arg = promote(arg);
    718 				break;
    719 			case FLOAT:
    720 				if (arg->type == floattype)
    721 					arg = convert(arg, doubletype, 1);
    722 				break;
    723 			}
    724 			par = node(OPAR, arg->type, par, arg);
    725 			continue;
    726 		}
    727 		if (--n < 0) {
    728 			if (!toomany)
    729 				errorp("too many arguments in function call");
    730 			toomany = 1;
    731 			continue;
    732 		}
    733 		++targs;
    734 		if ((arg = convert(arg, argtype, 0)) != NULL) {
    735 			par = node(OPAR, arg->type, par, arg);
    736 			continue;
    737 		}
    738 		errorp("incompatible type for argument %d in function call",
    739 		       tp->n.elem - n + 1);
    740 	} while (accept(','));
    741 
    742 no_pars:
    743 	expect(')');
    744 	if (n > 0 && *targs != ellipsistype)
    745 		errorp("too few arguments in function call");
    746 
    747 	op = (tp->prop&TELLIPSIS) ? OCALLE : OCALL;
    748 	return node(op, rettype, np, par);
    749 }
    750 
    751 static Node *unary(int);
    752 
    753 static Type *
    754 typeof(Node *np)
    755 {
    756 	Type *tp;
    757 
    758 	if (np == NULL)
    759 		unexpected();
    760 	tp = np->type;
    761 	freetree(np);
    762 	return tp;
    763 }
    764 
    765 static Type *
    766 sizeexp(void)
    767 {
    768 	Type *tp;
    769 
    770 	expect('(');
    771 	switch (yytoken) {
    772 	case TYPE:
    773 	case TYPEIDEN:
    774 		tp = typename();
    775 		break;
    776 	default:
    777 		tp = typeof(unary(0));
    778 		break;
    779 	}
    780 	expect(')');
    781 	return tp;
    782 }
    783 
    784 static Node *
    785 postfix(Node *lp)
    786 {
    787 	Node *rp;
    788 
    789 	for (;;) {
    790 		switch (yytoken) {
    791 		case '[':
    792 		case DEC:
    793 		case INC:
    794 		case INDIR:
    795 		case '.':
    796 		case '(':
    797 			lp = decay(lp);
    798 			switch (yytoken) {
    799 			case '[':
    800 				next();
    801 				rp = xexpr();
    802 				expect(']');
    803 				lp = array(lp, rp);
    804 				break;
    805 			case DEC:
    806 			case INC:
    807 				lp = incdec(lp, (yytoken == INC) ? OINC : ODEC);
    808 				next();
    809 				break;
    810 			case INDIR:
    811 				lp = content(OPTR, lp);
    812 			case '.':
    813 				lp = field(lp);
    814 				break;
    815 			case '(':
    816 				lp = arguments(lp);
    817 				lp->flags |= NEFFECT;
    818 				break;
    819 			}
    820 			break;
    821 		default:
    822 			return lp;
    823 		}
    824 	}
    825 }
    826 
    827 static Node *
    828 defined(void)
    829 {
    830 	Symbol *sym;
    831 	int paren;
    832 
    833 	disexpand = 1;
    834 	next();
    835 	paren = accept('(');
    836 	if (yytoken != IDEN && yytoken != TYPEIDEN)
    837 		cpperror("operator 'defined' requires an identifier");
    838 	if (yytoken == TYPEIDEN || !(yylval.sym->flags & SDECLARED))
    839 		sym = zero;
    840 	else
    841 		sym = one;
    842 	disexpand = 0;
    843 	next();
    844 	if (paren)
    845 		expect(')');
    846 	return constnode(sym);
    847 }
    848 
    849 static Node *cast(int);
    850 
    851 static Node *
    852 unary(int needdecay)
    853 {
    854 	Node *(*fun)(int, Node *), *np;
    855 	int op;
    856 	Type *tp;
    857 
    858 	switch (yytoken) {
    859 	case '!': op = 0;     fun = negation;     break;
    860 	case '+': op = OADD;  fun = numericaluop; break;
    861 	case '-': op = OSNEG; fun = numericaluop; break;
    862 	case '~': op = OCPL;  fun = integeruop;   break;
    863 	case '&': op = OADDR; fun = address;      break;
    864 	case '*': op = OPTR;  fun = content;      break;
    865 	case SIZEOF:
    866 		next();
    867 		tp = (yytoken == '(') ? sizeexp() : typeof(unary(0));
    868 		if (!(tp->prop & TDEFINED))
    869 			errorp("sizeof applied to an incomplete type");
    870 		return sizeofnode(tp);
    871 	case INC:
    872 	case DEC:
    873 		op = (yytoken == INC) ? OA_ADD : OA_SUB;
    874 		next();
    875 		np = incdec(unary(1), op);
    876 		goto chk_decay;
    877 	case IDEN:
    878 	case TYPEIDEN:
    879 		if (lexmode == CPPMODE && !strcmp(yylval.sym->name, "defined"))
    880 			return defined();
    881 	default:
    882 		np = postfix(primary());
    883 		goto chk_decay;
    884 	}
    885 
    886 	next();
    887 	np = (*fun)(op, cast(op != OADDR));
    888 
    889 chk_decay:
    890 	if (needdecay)
    891 		np = decay(np);
    892 	return np;
    893 }
    894 
    895 static Node *
    896 cast(int needdecay)
    897 {
    898 	Node *lp, *rp;
    899 	Type *tp;
    900 	static int nested;
    901 
    902 	if (!accept('('))
    903 		return unary(needdecay);
    904 
    905 	switch (yytoken) {
    906 	case TQUALIFIER:
    907 	case TYPE:
    908 	case TYPEIDEN:
    909 		tp = typename();
    910 		expect(')');
    911 
    912 		if (yytoken == '{')
    913 			return initlist(tp);
    914 
    915 		switch (tp->op) {
    916 		case ARY:
    917 			error("cast specifies an array type");
    918 		default:
    919 			lp = cast(needdecay);
    920 			if ((rp = convert(lp,  tp, 1)) == NULL)
    921 				error("bad type conversion requested");
    922 			rp->flags &= ~NLVAL;
    923 			rp->flags |= lp->flags & NLVAL;
    924 		}
    925 		break;
    926 	default:
    927 		if (nested == NR_SUBEXPR)
    928 			error("too many expressions nested by parentheses");
    929 		++nested;
    930 		rp = xexpr();
    931 		--nested;
    932 		expect(')');
    933 		rp = postfix(rp);
    934 		break;
    935 	}
    936 
    937 	return rp;
    938 }
    939 
    940 static Node *
    941 mul(void)
    942 {
    943 	Node *np, *(*fun)(int, Node *, Node *);
    944 	int op;
    945 
    946 	np = cast(1);
    947 	for (;;) {
    948 		switch (yytoken) {
    949 		case '*': op = OMUL; fun = arithmetic; break;
    950 		case '/': op = ODIV; fun = arithmetic; break;
    951 		case '%': op = OMOD; fun = integerop;  break;
    952 		default: return np;
    953 		}
    954 		next();
    955 		np = (*fun)(op, np, cast(1));
    956 	}
    957 }
    958 
    959 static Node *
    960 add(void)
    961 {
    962 	int op;
    963 	Node *np;
    964 
    965 	np = mul();
    966 	for (;;) {
    967 		switch (yytoken) {
    968 		case '+': op = OADD; break;
    969 		case '-': op = OSUB; break;
    970 		default:  return np;
    971 		}
    972 		next();
    973 		np = arithmetic(op, np, mul());
    974 	}
    975 }
    976 
    977 static Node *
    978 shift(void)
    979 {
    980 	int op;
    981 	Node *np;
    982 
    983 	np = add();
    984 	for (;;) {
    985 		switch (yytoken) {
    986 		case SHL: op = OSHL; break;
    987 		case SHR: op = OSHR; break;
    988 		default:  return np;
    989 		}
    990 		next();
    991 		np = integerop(op, np, add());
    992 	}
    993 }
    994 
    995 static Node *
    996 relational(void)
    997 {
    998 	int op;
    999 	Node *np;
   1000 
   1001 	np = shift();
   1002 	for (;;) {
   1003 		switch (yytoken) {
   1004 		case '<': op = OLT; break;
   1005 		case '>': op = OGT; break;
   1006 		case GE:  op = OGE; break;
   1007 		case LE:  op = OLE; break;
   1008 		default:  return np;
   1009 		}
   1010 		next();
   1011 		np = compare(op, np, shift());
   1012 	}
   1013 }
   1014 
   1015 static Node *
   1016 eq(void)
   1017 {
   1018 	int op;
   1019 	Node *np;
   1020 
   1021 	np = relational();
   1022 	for (;;) {
   1023 		switch (yytoken) {
   1024 		case EQ: op = OEQ; break;
   1025 		case NE: op = ONE; break;
   1026 		default: return np;
   1027 		}
   1028 		next();
   1029 		np = compare(op, np, relational());
   1030 	}
   1031 }
   1032 
   1033 static Node *
   1034 bit_and(void)
   1035 {
   1036 	Node *np;
   1037 
   1038 	np = eq();
   1039 	while (accept('&'))
   1040 		np = integerop(OBAND, np, eq());
   1041 	return np;
   1042 }
   1043 
   1044 static Node *
   1045 bit_xor(void)
   1046 {
   1047 	Node *np;
   1048 
   1049 	np = bit_and();
   1050 	while (accept('^'))
   1051 		np = integerop(OBXOR,  np, bit_and());
   1052 	return np;
   1053 }
   1054 
   1055 static Node *
   1056 bit_or(void)
   1057 {
   1058 	Node *np;
   1059 
   1060 	np = bit_xor();
   1061 	while (accept('|'))
   1062 		np = integerop(OBOR, np, bit_xor());
   1063 	return np;
   1064 }
   1065 
   1066 static Node *
   1067 and(void)
   1068 {
   1069 	Node *np;
   1070 
   1071 	np = bit_or();
   1072 	while (accept(AND))
   1073 		np = logic(OAND, np, bit_or());
   1074 	return np;
   1075 }
   1076 
   1077 static Node *
   1078 or(void)
   1079 {
   1080 	Node *np;
   1081 
   1082 	np = and();
   1083 	while (accept(OR))
   1084 		np = logic(OOR, np, and());
   1085 	return np;
   1086 }
   1087 
   1088 static Node *
   1089 ternary(void)
   1090 {
   1091 	Node *cond;
   1092 
   1093 	cond = or();
   1094 	while (accept('?')) {
   1095 		Node *ifyes, *ifno, *np;
   1096 
   1097 		cond = exp2cond(cond, 0);
   1098 		ifyes = xexpr();
   1099 		expect(':');
   1100 		ifno = ternary();
   1101 		np = chkternary(ifyes, ifno);
   1102 		cond = node(OASK, np->type, cond, np);
   1103 	}
   1104 	return cond;
   1105 }
   1106 
   1107 static Node *
   1108 xassign(void)
   1109 {
   1110 	Node *np, *(*fun)(int , Node *, Node *);
   1111 	int op;
   1112 
   1113 	np = ternary();
   1114 	for (;;) {
   1115 		switch (yytoken) {
   1116 		case '=':    op = OASSIGN; fun = assignop;   break;
   1117 		case MUL_EQ: op = OA_MUL;  fun = arithmetic; break;
   1118 		case DIV_EQ: op = OA_DIV;  fun = arithmetic; break;
   1119 		case MOD_EQ: op = OA_MOD;  fun = integerop;  break;
   1120 		case ADD_EQ: op = OA_ADD;  fun = arithmetic; break;
   1121 		case SUB_EQ: op = OA_SUB;  fun = arithmetic; break;
   1122 		case SHL_EQ: op = OA_SHL;  fun = integerop;  break;
   1123 		case SHR_EQ: op = OA_SHR;  fun = integerop;  break;
   1124 		case AND_EQ: op = OA_AND;  fun = integerop;  break;
   1125 		case XOR_EQ: op = OA_XOR;  fun = integerop;  break;
   1126 		case OR_EQ:  op = OA_OR;   fun = integerop;  break;
   1127 		default: return np;
   1128 		}
   1129 		chklvalue(np);
   1130 		np->flags |= NEFFECT;
   1131 		next();
   1132 		np = (fun)(op, np, assign());
   1133 	}
   1134 }
   1135 
   1136 static Node *
   1137 xexpr(void)
   1138 {
   1139 	Node *lp, *rp;
   1140 
   1141 	lp = xassign();
   1142 	while (accept(',')) {
   1143 		rp = xassign();
   1144 		lp = node(OCOMMA, rp->type, lp, rp);
   1145 	}
   1146 	return lp;
   1147 }
   1148 
   1149 Node *
   1150 assign(void)
   1151 {
   1152 	return simplify(xassign());
   1153 }
   1154 
   1155 Node *
   1156 constexpr(void)
   1157 {
   1158 	Node *np;
   1159 
   1160 	np = ternary();
   1161 	if (np && np->type->op == INT) {
   1162 		np = simplify(convert(np, inttype, 0));
   1163 		if (np->flags & NCONST)
   1164 			return np;
   1165 	}
   1166 	freetree(np);
   1167 	return NULL;
   1168 }
   1169 
   1170 Node *
   1171 expr(void)
   1172 {
   1173 	return simplify(xexpr());
   1174 }
   1175 
   1176 Node *
   1177 condexpr(int neg)
   1178 {
   1179 	Node *np;
   1180 
   1181 	np = exp2cond(xexpr(), neg);
   1182 	if (np->flags & NCONST)
   1183 		warn("conditional expression is constant");
   1184 	return simplify(np);
   1185 }