Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

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 }