scc

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

expr.c (21147B)


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