Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

enode.c (14205B)


      1 #include "c.h"
      2 
      3 
      4 static Tree addtree(int, Tree, Tree);
      5 static Tree andtree(int, Tree, Tree);
      6 static Tree cmptree(int, Tree, Tree);
      7 static int compatible(Type, Type);
      8 static int isnullptr(Tree e);
      9 static Tree multree(int, Tree, Tree);
     10 static Tree subtree(int, Tree, Tree);
     11 #define isvoidptr(ty) \
     12 	(isptr(ty) && unqual(ty->type) == voidtype)
     13 
     14 Tree (*optree[])(int, Tree, Tree) = {
     15 #define xx(a,b,c,d,e,f,g) e,
     16 #define yy(a,b,c,d,e,f,g) e,
     17 #include "token.h"
     18 };
     19 Tree call(Tree f, Type fty, Coordinate src) {
     20 	int n = 0;
     21 	Tree args = NULL, r = NULL, e;
     22 	Type *proto, rty = unqual(freturn(fty));
     23 	Symbol t3 = NULL;
     24 
     25 	if (fty->u.f.oldstyle)
     26 		proto = NULL;
     27 	else
     28 		proto = fty->u.f.proto;
     29 	if (hascall(f))
     30 		r = f;
     31 	if (isstruct(rty))
     32 		{
     33 			t3 = temporary(AUTO, unqual(rty));
     34 			if (rty->size == 0)
     35 				error("illegal use of incomplete type `%t'\n", rty);
     36 		}
     37 	if (t != ')')
     38 		for (;;) {
     39 			Tree q = pointer(expr1(0));
     40 			if (proto && *proto && *proto != voidtype)
     41 				{
     42 					Type aty;
     43 					q = value(q);
     44 					aty = assign(*proto, q);
     45 					if (aty)
     46 						q = cast(q, aty);
     47 					else
     48 						error("type error in argument %d to %s; found `%t' expected `%t'\n", n + 1, funcname(f),
     49 
     50 							q->type, *proto);
     51 					if ((isint(q->type) || isenum(q->type))
     52 					&& q->type->size != inttype->size)
     53 						q = cast(q, promote(q->type));
     54 					++proto;
     55 				}
     56 			else
     57 				{
     58 					if (!fty->u.f.oldstyle && *proto == NULL)
     59 						error("too many arguments to %s\n", funcname(f));
     60 					q = value(q);
     61 					if (isarray(q->type) || q->type->size == 0)
     62 						error("type error in argument %d to %s; `%t' is illegal\n", n + 1, funcname(f), q->type);
     63 
     64 					else
     65 						q = cast(q, promote(q->type));
     66 				}
     67 			if (!IR->wants_argb && isstruct(q->type))
     68 				if (iscallb(q))
     69 					q = addrof(q);
     70 				else {
     71 					Symbol t1 = temporary(AUTO, unqual(q->type));
     72 					q = asgn(t1, q);
     73 					q = tree(RIGHT, ptr(t1->type),
     74 						root(q), lvalue(idtree(t1)));
     75 				}
     76 			if (q->type->size == 0)
     77 				q->type = inttype;
     78 			if (hascall(q))
     79 				r = r ? tree(RIGHT, voidtype, r, q) : q;
     80 			args = tree(mkop(ARG, q->type), q->type, q, args);
     81 			n++;
     82 			if (Aflag >= 2 && n == 32)
     83 				warning("more than 31 arguments in a call to %s\n",
     84 					funcname(f));
     85 			if (t != ',')
     86 				break;
     87 			t = gettok();
     88 		}
     89 	expect(')');
     90 	if (proto && *proto && *proto != voidtype)
     91 		error("insufficient number of arguments to %s\n",
     92 			funcname(f));
     93 	if (r)
     94 		args = tree(RIGHT, voidtype, r, args);
     95 	e = calltree(f, rty, args, t3);
     96 	if (events.calls)
     97 		apply(events.calls, &src, &e);
     98 	return e;
     99 }
    100 Tree calltree(Tree f, Type ty, Tree args, Symbol t3) {
    101 	Tree p;
    102 
    103 	if (args)
    104 		f = tree(RIGHT, f->type, args, f);
    105 	if (isstruct(ty))
    106 		assert(t3),
    107 		p = tree(RIGHT, ty,
    108 			tree(CALL+B, ty, f, addrof(idtree(t3))),
    109 			idtree(t3));
    110 	else {
    111 		Type rty = ty;
    112 		if (isenum(ty))
    113 			rty = unqual(ty)->type;
    114 		if (!isfloat(rty))
    115 			rty = promote(rty);
    116 		p = tree(mkop(CALL, rty), rty, f, NULL);
    117 		if (isptr(ty) || p->type->size > ty->size)
    118 			p = cast(p, ty);
    119 	}
    120 	return p;
    121 }
    122 Tree vcall(Symbol func, Type ty, ...) {
    123 	va_list ap;
    124 	Tree args = NULL, e, f = pointer(idtree(func)), r = NULL;
    125 
    126 	assert(isfunc(func->type));
    127 	if (ty == NULL)
    128 		ty = freturn(func->type);
    129 	va_start(ap, ty);
    130 	while ((e = va_arg(ap, Tree)) != NULL) {
    131 		if (hascall(e))
    132 			r = r == NULL ? e : tree(RIGHT, voidtype, r, e);
    133 		args = tree(mkop(ARG, e->type), e->type, e, args);
    134 	}
    135 	va_end(ap);
    136 	if (r != NULL)
    137 		args = tree(RIGHT, voidtype, r, args);
    138 	return calltree(f, ty, args, NULL);
    139 }
    140 int iscallb(Tree e) {
    141 	return e->op == RIGHT && e->kids[0] && e->kids[1]
    142 		&& e->kids[0]->op == CALL+B
    143 		&& e->kids[1]->op == INDIR+B
    144 		&& isaddrop(e->kids[1]->kids[0]->op)
    145 		&& e->kids[1]->kids[0]->u.sym->temporary;
    146 }
    147 
    148 static Tree addtree(int op, Tree l, Tree r) {
    149 	Type ty = inttype;
    150 
    151 	if (isarith(l->type) && isarith(r->type)) {
    152 		ty = binary(l->type, r->type);
    153 		l = cast(l, ty);
    154 		r = cast(r, ty);		
    155 	} else if (isptr(l->type) && isint(r->type))
    156 		return addtree(ADD, r, l);
    157 	else if (  isptr(r->type) && isint(l->type)
    158 	&& !isfunc(r->type->type))
    159 		{
    160 			long n;
    161 			ty = unqual(r->type);
    162 			n = unqual(ty->type)->size;
    163 			if (n == 0)
    164 				error("unknown size for type `%t'\n", ty->type);
    165 			l = cast(l, promote(l->type));
    166 			if (n > 1)
    167 				l = multree(MUL, cnsttree(signedptr, n), l);
    168 			if (YYcheck && !isaddrop(r->op))		/* omit */
    169 				return nullcall(ty, YYcheck, r, l);	/* omit */
    170 			return simplify(ADD, ty, l, r);
    171 		}
    172 
    173 	else
    174 		typeerror(op, l, r);
    175 	return simplify(op, ty, l, r);
    176 }
    177 
    178 Tree cnsttree(Type ty, ...) {
    179 	Tree p = tree(mkop(CNST,ty), ty, NULL, NULL);
    180 	va_list ap;
    181 
    182 	va_start(ap, ty);
    183 	switch (ty->op) {
    184 	case INT:     p->u.v.i = va_arg(ap, long); break;
    185 	case UNSIGNED:p->u.v.u = va_arg(ap, unsigned long)&ones(8*ty->size); break;
    186 	case FLOAT:   p->u.v.d = va_arg(ap, long double); break;
    187 	case POINTER: p->u.v.p = va_arg(ap, void *); break;
    188 	default: assert(0);
    189 	}
    190 	va_end(ap);
    191 	return p;
    192 }
    193 
    194 Tree consttree(unsigned n, Type ty) {
    195 	if (isarray(ty))
    196 		ty = atop(ty);
    197 	else assert(isint(ty));
    198 	return cnsttree(ty, (unsigned long)n);
    199 }
    200 static Tree cmptree(int op, Tree l, Tree r) {
    201 	Type ty;
    202 
    203 	if (isarith(l->type) && isarith(r->type)) {
    204 		ty = binary(l->type, r->type);
    205 		l = cast(l, ty);
    206 		r = cast(r, ty);
    207 	} else if (compatible(l->type, r->type)) {
    208 		ty = unsignedptr;
    209 		l = cast(l, ty);
    210 		r = cast(r, ty);
    211 	} else {
    212 		ty = unsignedtype;
    213 		typeerror(op, l, r);
    214 	}
    215 	return simplify(mkop(op,ty), inttype, l, r);
    216 }
    217 static int compatible(Type ty1, Type ty2) {
    218 	return isptr(ty1) && !isfunc(ty1->type)
    219 	    && isptr(ty2) && !isfunc(ty2->type)
    220 	    && eqtype(unqual(ty1->type), unqual(ty2->type), 0);
    221 }
    222 static int isnullptr(Tree e) {
    223 	Type ty = unqual(e->type);
    224 
    225 	return generic(e->op) == CNST
    226 	    && (ty->op == INT      && e->u.v.i == 0
    227 	     || ty->op == UNSIGNED && e->u.v.u == 0
    228 	     || isvoidptr(ty)      && e->u.v.p == NULL);
    229 }
    230 Tree eqtree(int op, Tree l, Tree r) {
    231 	Type xty = l->type, yty = r->type;
    232 
    233 	if (isptr(xty) && isnullptr(r)
    234 	||  isptr(xty) && !isfunc(xty->type) && isvoidptr(yty)
    235 	||  (isptr(xty) && isptr(yty)
    236 	    && eqtype(unqual(xty->type), unqual(yty->type), 1))) {
    237 		Type ty = unsignedptr;
    238 		l = cast(l, ty);
    239 		r = cast(r, ty);
    240 		return simplify(mkop(op,ty), inttype, l, r);
    241 	}
    242 	if (isptr(yty) && isnullptr(l)
    243 	||  isptr(yty) && !isfunc(yty->type) && isvoidptr(xty))
    244 		return eqtree(op, r, l);
    245 	return cmptree(op, l, r);
    246 }
    247 
    248 Type assign(Type xty, Tree e) {
    249 	Type yty = unqual(e->type);
    250 
    251 	xty = unqual(xty);
    252 	if (isenum(xty))
    253 		xty = xty->type;
    254 	if (xty->size == 0 || yty->size == 0)
    255 		return NULL;
    256 	if ( isarith(xty) && isarith(yty)
    257 	||  isstruct(xty) && xty == yty)
    258 		return xty;
    259 	if (isptr(xty) && isnullptr(e))
    260 		return xty;
    261 	if ((isvoidptr(xty) && isptr(yty)
    262 	  || isptr(xty)     && isvoidptr(yty))
    263 	&& (  (isconst(xty->type)    || !isconst(yty->type))
    264 	   && (isvolatile(xty->type) || !isvolatile(yty->type))))
    265 		return xty;
    266 
    267 	if ((isptr(xty) && isptr(yty)
    268 	    && eqtype(unqual(xty->type), unqual(yty->type), 1))
    269 	&&  (  (isconst(xty->type)    || !isconst(yty->type))
    270 	    && (isvolatile(xty->type) || !isvolatile(yty->type))))
    271 		return xty;
    272 	if (isptr(xty) && isptr(yty)
    273 	&& (  (isconst(xty->type)    || !isconst(yty->type))
    274 	   && (isvolatile(xty->type) || !isvolatile(yty->type)))) {
    275 		Type lty = unqual(xty->type), rty = unqual(yty->type);
    276 		if (isenum(lty) && rty == inttype
    277 		||  isenum(rty) && lty == inttype) {
    278 			if (Aflag >= 1)
    279 				warning("assignment between `%t' and `%t' is compiler-dependent\n",
    280 					xty, yty);
    281 			return xty;
    282 		}
    283 	}
    284 	return NULL;
    285 }
    286 Tree asgntree(int op, Tree l, Tree r) {
    287 	Type aty, ty;
    288 
    289 	r = pointer(r);
    290 	ty = assign(l->type, r);
    291 	if (ty)
    292 		r = cast(r, ty);
    293 	else {
    294 		typeerror(ASGN, l, r);
    295 		if (r->type == voidtype)
    296 			r = retype(r, inttype);
    297 		ty = r->type;
    298 	}
    299 	if (l->op != FIELD)
    300 		l = lvalue(l);
    301 	aty = l->type;
    302 	if (isptr(aty))
    303 		aty = unqual(aty)->type;
    304 	if ( isconst(aty)
    305 	||  isstruct(aty) && unqual(aty)->u.sym->u.s.cfields)
    306 		if (isaddrop(l->op)
    307 		&& !l->u.sym->computed && !l->u.sym->generated)
    308 			error("assignment to const identifier `%s'\n",
    309 				l->u.sym->name);
    310 		else
    311 			error("assignment to const location\n");
    312 	if (l->op == FIELD) {
    313 		long n = 8*l->u.field->type->size - fieldsize(l->u.field);
    314 		if (n > 0 && isunsigned(l->u.field->type))
    315 			r = bittree(BAND, r,
    316 				cnsttree(r->type, (unsigned long)fieldmask(l->u.field)));
    317 		else if (n > 0) {
    318 			if (r->op == CNST+I) {
    319 				n = r->u.v.i;
    320 				if (n&(1<<(fieldsize(l->u.field)-1)))
    321 					n |= ~0UL<<fieldsize(l->u.field);
    322 				r = cnsttree(r->type, n);
    323 			} else
    324 				r = shtree(RSH,
    325 					shtree(LSH, r, cnsttree(inttype, n)),
    326 					cnsttree(inttype, n));
    327 		}
    328 	}
    329 	if (isstruct(ty) && isaddrop(l->op) && iscallb(r))
    330 		return tree(RIGHT, ty,
    331 			tree(CALL+B, ty, r->kids[0]->kids[0], l),
    332 			idtree(l->u.sym));
    333 	return tree(mkop(op,ty), ty, l, r);
    334 }
    335 Tree condtree(Tree e, Tree l, Tree r) {
    336 	Symbol t1;
    337 	Type ty, xty = l->type, yty = r->type;
    338 	Tree p;
    339 
    340 	if (isarith(xty) && isarith(yty))
    341 		ty = binary(xty, yty);
    342 	else if (eqtype(xty, yty, 1))
    343 		ty = unqual(xty);
    344 	else if (isptr(xty)   && isnullptr(r))
    345 		ty = xty;
    346 	else if (isnullptr(l) && isptr(yty))
    347 		ty = yty;
    348 	else if (isptr(xty) && !isfunc(xty->type) && isvoidptr(yty)
    349 	||       isptr(yty) && !isfunc(yty->type) && isvoidptr(xty))
    350 		ty = voidptype;
    351 	else if ((isptr(xty) && isptr(yty)
    352 		 && eqtype(unqual(xty->type), unqual(yty->type), 1)))
    353 		ty = xty;
    354 	else {
    355 		typeerror(COND, l, r);
    356 		return consttree(0, inttype);
    357 	}
    358 	if (isptr(ty)) {
    359 		ty = unqual(unqual(ty)->type);
    360 		if (isptr(xty) && isconst(unqual(xty)->type)
    361 		||  isptr(yty) && isconst(unqual(yty)->type))
    362 			ty = qual(CONST, ty);
    363 		if (isptr(xty) && isvolatile(unqual(xty)->type)
    364 		||  isptr(yty) && isvolatile(unqual(yty)->type))
    365 			ty = qual(VOLATILE, ty);
    366 		ty = ptr(ty);
    367 	}
    368 	switch (e->op) {
    369 	case CNST+I: return cast(e->u.v.i != 0   ? l : r, ty);
    370 	case CNST+U: return cast(e->u.v.u != 0   ? l : r, ty);
    371 	case CNST+P: return cast(e->u.v.p != 0   ? l : r, ty);
    372 	case CNST+F: return cast(e->u.v.d != 0.0 ? l : r, ty);
    373 	}
    374 	if (ty != voidtype && ty->size > 0) {
    375 		t1 = genident(REGISTER, unqual(ty), level);
    376 	/*	t1 = temporary(REGISTER, unqual(ty)); */
    377 		l = asgn(t1, l);
    378 		r = asgn(t1, r);
    379 	} else
    380 		t1 = NULL;
    381 	p = tree(COND, ty, cond(e),
    382 		tree(RIGHT, ty, root(l), root(r)));
    383 	p->u.sym = t1;
    384 	return p;
    385 }
    386 /* addrof - address of p */
    387 Tree addrof(Tree p) {
    388 	Tree q = p;
    389 
    390 	for (;;)
    391 		switch (generic(q->op)) {
    392 		case RIGHT:
    393 			assert(q->kids[0] || q->kids[1]);
    394 			q = q->kids[1] ? q->kids[1] : q->kids[0];
    395 			continue;
    396 		case ASGN:
    397 			q = q->kids[1];
    398 			continue;
    399 		case COND: {
    400 			Symbol t1 = q->u.sym;
    401 			q->u.sym = 0;
    402 			q = idtree(t1);
    403 			/* fall thru */
    404 			}
    405 		case INDIR:
    406 			if (p == q)
    407 				return q->kids[0];
    408 			q = q->kids[0];
    409 			return tree(RIGHT, q->type, root(p), q);
    410 		default:
    411 			error("addressable object required\n");
    412 			return value(p);
    413 		}
    414 }
    415 
    416 /* andtree - construct tree for l [&& ||] r */
    417 static Tree andtree(int op, Tree l, Tree r) {
    418 	if (!isscalar(l->type) || !isscalar(r->type))
    419 		typeerror(op, l, r);
    420 	return simplify(op, inttype, cond(l), cond(r));
    421 }
    422 
    423 /* asgn - generate tree for assignment of expr e to symbol p sans qualifiers */
    424 Tree asgn(Symbol p, Tree e) {
    425 	if (isarray(p->type))
    426 		e = tree(ASGN+B, p->type, idtree(p),
    427 			tree(INDIR+B, e->type, e, NULL));
    428 	else {
    429 		Type ty = p->type;
    430 		p->type = unqual(p->type);
    431 		if (isstruct(p->type) && p->type->u.sym->u.s.cfields) {
    432 			p->type->u.sym->u.s.cfields = 0;
    433 			e = asgntree(ASGN, idtree(p), e);
    434 			p->type->u.sym->u.s.cfields = 1;
    435 		} else
    436 			e = asgntree(ASGN, idtree(p), e);
    437 		p->type = ty;
    438 	}
    439 	return e;
    440 }
    441 
    442 /* bittree - construct tree for l [& | ^ %] r */
    443 Tree bittree(int op, Tree l, Tree r) {
    444 	Type ty = inttype;
    445 
    446 	if (isint(l->type) && isint(r->type)) {
    447  		ty = binary(l->type, r->type);
    448 		l = cast(l, ty);
    449 		r = cast(r, ty);		
    450 	} else
    451 		typeerror(op, l, r);
    452 	return simplify(op, ty, l, r);
    453 }
    454 
    455 /* multree - construct tree for l [* /] r */
    456 static Tree multree(int op, Tree l, Tree r) {
    457 	Type ty = inttype;
    458 
    459 	if (isarith(l->type) && isarith(r->type)) {
    460 		ty = binary(l->type, r->type);
    461 		l = cast(l, ty);
    462 		r = cast(r, ty);		
    463 	} else
    464 		typeerror(op, l, r);
    465 	return simplify(op, ty, l, r);
    466 }
    467 
    468 /* shtree - construct tree for l [>> <<] r */
    469 Tree shtree(int op, Tree l, Tree r) {
    470 	Type ty = inttype;
    471 
    472 	if (isint(l->type) && isint(r->type)) {
    473 		ty = promote(l->type);
    474 		l = cast(l, ty);
    475 		r = cast(r, inttype);
    476 	} else
    477 		typeerror(op, l, r);
    478 	return simplify(op, ty, l, r);
    479 }
    480 
    481 /* subtree - construct tree for l - r */
    482 static Tree subtree(int op, Tree l, Tree r) {
    483 	long n;
    484 	Type ty = inttype;
    485 
    486 	if (isarith(l->type) && isarith(r->type)) {
    487 		ty = binary(l->type, r->type);
    488 		l = cast(l, ty);
    489 		r = cast(r, ty);		
    490 	} else if (isptr(l->type) && !isfunc(l->type->type) && isint(r->type)) {
    491 		ty = unqual(l->type);
    492 		n = unqual(ty->type)->size;
    493 		if (n == 0)
    494 			error("unknown size for type `%t'\n", ty->type);
    495 		r = cast(r, promote(r->type));
    496 		if (n > 1)
    497 			r = multree(MUL, cnsttree(signedptr, n), r);
    498 		if (isunsigned(r->type))
    499 			r = cast(r, unsignedptr);
    500 		else
    501 			r = cast(r, signedptr);
    502 		return simplify(SUB+P, ty, l, r);
    503 	} else if (compatible(l->type, r->type)) {
    504 		ty = unqual(l->type);
    505 		n = unqual(ty->type)->size;
    506 		if (n == 0)
    507 			error("unknown size for type `%t'\n", ty->type);
    508 		l = simplify(SUB+U, unsignedptr,
    509 			cast(l, unsignedptr), cast(r, unsignedptr));
    510 		return simplify(DIV+I, longtype,
    511 			cast(l, longtype), cnsttree(longtype, n));
    512 	} else
    513 		typeerror(op, l, r);
    514 	return simplify(op, ty, l, r);
    515 }
    516 
    517 /* typeerror - issue "operands of op have illegal types `l' and `r'" */
    518 void typeerror(int op, Tree l, Tree r) {
    519 	int i;
    520 	static struct { int op; char *name; } ops[] = {
    521 		ASGN, "=",	INDIR, "*",	NEG,  "-",
    522 		ADD,  "+",	SUB,   "-",	LSH,  "<<",
    523 		MOD,  "%",	RSH,   ">>",	BAND, "&",
    524 		BCOM, "~",	BOR,   "|",	BXOR, "^",
    525 		DIV,  "/",	MUL,   "*",	EQ,   "==",
    526 		GE,   ">=",	GT,    ">",	LE,   "<=",
    527 		LT,   "<",	NE,    "!=",	AND,  "&&",
    528 		NOT,  "!",	OR,    "||",	COND, "?:",
    529 		0, 0
    530 	};
    531 
    532 	op = generic(op);
    533 	for (i = 0; ops[i].op; i++)
    534 		if (op == ops[i].op)
    535 			break;
    536 	assert(ops[i].name);
    537 	if (r)
    538 		error("operands of %s have illegal types `%t' and `%t'\n",
    539 			ops[i].name, l->type, r->type);
    540 	else
    541 		error("operand of unary %s has illegal type `%t'\n", ops[i].name,
    542 			l->type);
    543 }