|
|
1.1 root 1: /* C compiler: type-checking and tree construction for expressions */
2:
3: #include "c.h"
4:
5: dclproto(static Tree addnode,(int, Tree, Tree));
6: dclproto(static Tree andnode,(int, Tree, Tree));
7: dclproto(static Type binary,(Type, Type));
8: dclproto(static Tree cmpnode,(int, Tree, Tree));
9: dclproto(static int compatible,(Type, Type));
10: dclproto(static Tree mulnode,(int, Tree, Tree));
11: dclproto(static Tree subnode,(int, Tree, Tree));
12:
13: dclproto(Tree (*opnode[]),(int, Tree, Tree)) = {
14: #define xx(a,b,c,d,e,f,g) e,
15: #include "token.h"
16: };
17:
18: /* addnode - construct tree for l + r */
19: static Tree addnode(op, l, r) Tree l, r; {
20: int n;
21: Type ty = inttype;
22:
23: if (isarith(l->type) && isarith(r->type)) {
24: ty = binary(l->type, r->type);
25: l = cast(l, ty);
26: r = cast(r, ty);
27: } else if (isptr(l->type) && isint(r->type))
28: return addnode(ADD, r, l);
29: else if (isptr(r->type) && isint(l->type)) {
30: ty = unqual(r->type);
31: if ((n = ty->type->size) == 0)
32: error("unknown size of type `%t'\n", ty->type);
33: l = cast(l, promote(l->type));
34: if (n > 1)
35: l = mulnode(MUL, constnode(n, inttype), l);
36: return simplify(ADD+P, ty, l, r);
37: } else
38: typeerror(op, l, r);
39: return simplify(op, ty, l, r);
40: }
41:
42: /* andnode - construct tree for l [&& ||] r */
43: static Tree andnode(op, l, r) Tree l, r; {
44: if (!isscalar(l->type) || !isscalar(r->type))
45: typeerror(op, l, r);
46: return simplify(op, inttype, cond(l), cond(r));
47: }
48:
49: /* asgnnode - construct tree for l = r */
50: Tree asgnnode(op, l, r) Tree l, r; {
51: Type aty, ty;
52:
53: r = pointer(r);
54: if ((ty = assign(l->type, r)) == 0) {
55: typeerror(ASGN, l, r);
56: if (r->type == voidtype)
57: r = retype(r, inttype);
58: ty = r->type;
59: }
60: if (l->op != FIELD)
61: l = lvalue(l);
62: aty = l->type;
63: if (isptr(aty))
64: aty = unqual(aty)->type;
65: if (isconst(aty) || (isstruct(aty) && unqual(aty)->u.sym->u.s.cfields))
66: if (isaddrop(l->op) && !l->u.sym->computed && !l->u.sym->generated)
67: error("assignment to const identifier `%s'\n", l->u.sym->name);
68: else
69: error("assignment to const location\n");
70: r = cast(r, ty);
71: if (l->op == FIELD && fieldsize(l->u.field) < 8*l->u.field->type->size)
72: if (isunsigned(l->u.field->type))
73: r = bitnode(BAND, r,
74: constnode(fieldmask(l->u.field), unsignedtype));
75: else {
76: int n = 8*l->u.field->type->size - fieldsize(l->u.field);
77: /*
78: * The value of assignment is the value of the left
79: * operand (sec. 3.3.16), which for bit fields is the
80: * same as extracting the field. When r is a constant,
81: * the explicit left shift below avoids overflow that
82: * would occur if shnode(LSH, ...) were used. The
83: * subsequent shnode(RSH, ...) will be signed and thus
84: * extend the sign bit correctly.
85: */
86: if (r->op == CNST+I)
87: r = constnode(r->u.v.i<<n, inttype);
88: else
89: r = shnode(LSH, r, constnode(n, inttype));
90: r = shnode(RSH, r, constnode(n, inttype));
91: }
92: if (isstruct(ty)) {
93: if (r->op == RIGHT && r->kids[0] && r->kids[0]->op == CALL+B
94: && isaddrop(l->op)) {
95: /*
96: * When x=f() where f returns a struct and x is a simple
97: * address, release the temporary generated to hold f's
98: * return value and use x in its place. The RIGHT tree
99: * assigned to r below returns x's address, and
100: * rvalue(r) hangs that tree under an INDIR+B,
101: * thus identifying the result as an lvalue.
102: */
103: r = r->kids[0]; /* CALL+B node */
104: release(r->kids[1]->u.sym);
105: r = tree(RIGHT, l->type,
106: tree(CALL+B, r->kids[0]->type, r->kids[0], l),
107: retype(isarray(l->u.sym->type) ? idnode(l->u.sym) : addrof(idnode(l->u.sym)), l->type));
108: return rvalue(r);
109: }
110: return tree(ASGN+B, ty, l, r);
111: }
112: return tree(op + (isunsigned(ty) ? I : ttob(ty)), ty, l, r);
113: }
114:
115: /* binary - usual arithmetic conversions, return target type */
116: static Type binary(xty, yty) Type xty, yty; {
117: if (isdouble(xty) || isdouble(yty))
118: return doubletype;
119: if (xty == floattype || yty == floattype)
120: return floattype;
121: if (isunsigned(xty) || isunsigned(yty))
122: return unsignedtype;
123: return inttype;
124: }
125:
126: /* bitnode - construct tree for l [& | ^ %] r */
127: Tree bitnode(op, l, r) Tree l, r; {
128: Type ty = inttype;
129:
130: if (isint(l->type) && isint(r->type)) {
131: ty = binary(l->type, r->type);
132: l = cast(l, ty);
133: r = cast(r, ty);
134: if (op != MOD) {
135: l = cast(l, unsignedtype);
136: r = cast(r, unsignedtype);
137: }
138: } else
139: typeerror(op, l, r);
140: if (op == MOD)
141: return simplify(op, ty, l, r);
142: return cast(simplify(op, unsignedtype, l, r), ty);
143: }
144:
145: /* callnode - construct call node to f, return type ty, arguments args */
146: Tree callnode(f, ty, args) Tree f, args; Type ty; {
147: Tree p;
148:
149: if (args)
150: f = tree(RIGHT, f->type, args, f);
151: if (isstruct(ty)) {
152: Symbol t1 = temporary(AUTO, unqual(ty));
153: if (ty->size == 0)
154: error("illegal use of incomplete type `%t'\n", ty);
155: p = tree(RIGHT, ty, tree(CALL+B, ty, f, lvalue(idnode(t1))),
156: idnode(t1));
157: } else {
158: Type rty = ty;
159: if (isenum(ty))
160: rty = unqual(ty)->type;
161: else if (isptr(ty))
162: rty = unsignedtype;
163: p = tree(CALL + widen(rty), rty, f, 0);
164: if (isptr(ty))
165: p = cast(p, ty);
166: }
167: return p;
168: }
169:
170: /* cmpnode - construct tree for l [< <= >= >] r */
171: static Tree cmpnode(op, l, r) Tree l, r; {
172: Type ty = unsignedtype;
173:
174: if (isarith(l->type) && isarith(r->type)) {
175: ty = binary(l->type, r->type);
176: l = cast(l, ty);
177: r = cast(r, ty);
178: } else if (compatible(l->type, r->type)) {
179: l = cast(l, ty);
180: r = cast(r, ty);
181: } else
182: typeerror(op, l, r);
183: return simplify(op + ttob(ty), inttype, l, r);
184: }
185:
186: /* compatible - are ty1 & ty2 sans qualifiers pointers to compatible object or incomplete types? */
187: static int compatible(ty1, ty2) Type ty1, ty2; {
188: if (isptr(ty1) && !isfunc(ty1->type) && isptr(ty2) && !isfunc(ty2->type)) {
189: do {
190: ty1 = unqual(ty1->type);
191: ty2 = unqual(ty2->type);
192: } while (isptr(ty1) && isptr(ty2));
193: return eqtype(ty1, ty2, 0);
194: }
195: return 0;
196: }
197:
198: /* condnode - build a tree for e ? l : r */
199: Tree condnode(e, l, r) Tree e, l, r; {
200: Symbol t1 = 0;
201: Type ty = 0, lty = l->type, rty = r->type;
202: Tree p;
203:
204: if (isarith(lty) && isarith(rty)) {
205: ty = binary(lty, rty);
206: l = cast(l, ty);
207: r = cast(r, ty);
208: } else if (eqtype(lty, rty, 1)
209: || isptr(lty) && isint(rty) && assign(lty, r))
210: ty = unqual(lty);
211: else if (isptr(rty) && isint(lty) && assign(rty, l))
212: ty = unqual(rty);
213: else if (isptr(lty) && isptr(rty)) {
214: lty = lty->type;
215: rty = rty->type;
216: if (unqual(lty) == voidtype || unqual(rty) == voidtype)
217: ty = voidtype;
218: else if (eqtype(unqual(lty), unqual(rty), 1))
219: ty = unqual(lty);
220: if (ty) {
221: if (isconst(lty) || isconst(rty))
222: ty = qual(CONST, ty);
223: if (isvolatile(lty) || isvolatile(rty))
224: ty = qual(VOLATILE, ty);
225: ty = ptr(ty);
226: }
227: }
228: if (ty == 0) {
229: typeerror(COND, l, r);
230: ty = inttype;
231: } else if (e->op == CNST+D || e->op == CNST+F) {
232: e = cast(e, doubletype);
233: return retype(e->u.v.d != 0.0 ? l : r, ty);
234: } else if (generic(e->op) == CNST) {
235: e = cast(e, unsignedtype);
236: return retype(e->u.v.u ? l : r, ty);
237: } else if (ty != voidtype && ty->size > 0) {
238: Opcode op = generic(e->op);
239: t1 = temporary(REGISTER, ty);
240: l = root(asgn(t1, l));
241: if (op != AND && op != OR && op != NOT && op != EQ && op != NE
242: && op != LE && op != LT && op != GE && op != GT && op != RIGHT
243: && r->op == CNST+I && r->u.v.i == 0
244: && assign(e->type, r)) {
245: /* e1?e2:0 => ((t1=e1,t1)?(t1=e2): ) */
246: e = tree(RIGHT, ty, asgn(t1, cast(e, ty)), idnode(t1));
247: r = 0;
248: } else
249: r = root(asgn(t1, r));
250: }
251: p = tree(COND, ty, cond(e), tree(RIGHT, ty, l, r));
252: p->u.sym = t1;
253: return p;
254: }
255:
256: /* constnode - return a tree for a constant n of type ty (int or unsigned) */
257: Tree constnode(n, ty) unsigned n; Type ty; {
258: Tree p;
259:
260: if (isarray(ty))
261: p = tree(CNST+P, atop(ty), 0, 0);
262: else
263: p = tree(CNST + ttob(ty), ty, 0, 0);
264: p->u.v.u = n;
265: return p;
266: }
267:
268: /* eqnode - construct tree for l [== !=] r */
269: Tree eqnode(op, l, r) Tree l, r; {
270: if (isint(l->type) && isptr(r->type))
271: return eqnode(op, r, l);
272: if (isptr(l->type) && isint(r->type)) {
273: l = cast(l, unsignedtype);
274: r = cast(r, unsignedtype);
275: if (r->op != CNST+U || r->u.v.u)
276: error("operands of %s have incompatible types\n",
277: op == EQ ? "==" : "!=");
278: return simplify(op + U, inttype, l, r);
279: }
280: if (isptr(l->type) && isptr(r->type) && eqtype(unqual(l->type), unqual(r->type), 1)
281: || isptr(l->type) && !isfunc(l->type->type)
282: && (isptr(r->type) && unqual(r->type->type) == voidtype)
283: || isptr(r->type) && !isfunc(r->type->type)
284: && (isptr(l->type) && unqual(l->type->type) == voidtype)) {
285: l = cast(l, unsignedtype);
286: r = cast(r, unsignedtype);
287: return simplify(op + U, inttype, l, r);
288: }
289: return cmpnode(op, l, r);
290: }
291:
292: /* mulnode - construct tree for l [* /] r */
293: static Tree mulnode(op, l, r) Tree l, r; {
294: Type ty = inttype;
295:
296: if (isarith(l->type) && isarith(r->type)) {
297: ty = binary(l->type, r->type);
298: l = cast(l, ty);
299: r = cast(r, ty);
300: } else
301: typeerror(op, l, r);
302: return simplify(op, ty, l, r);
303: }
304:
305: /* shnode - construct tree for l [>> <<] r */
306: Tree shnode(op, l, r) Tree l, r; {
307: Type ty = inttype;
308:
309: if (isint(l->type) && isint(r->type)) {
310: ty = promote(l->type);
311: l = cast(l, ty);
312: r = cast(r, inttype);
313: } else
314: typeerror(op, l, r);
315: return simplify(op, ty, l, r);
316: }
317:
318: /* subnode - construct tree for l - r */
319: static Tree subnode(op, l, r) Tree l, r; {
320: int n;
321: Type ty = inttype;
322:
323: if (isarith(l->type) && isarith(r->type)) {
324: ty = binary(l->type, r->type);
325: l = cast(l, ty);
326: r = cast(r, ty);
327: } else if (isptr(l->type) && !isfunc(l->type->type) && isint(r->type)) {
328: ty = unqual(l->type);
329: if ((n = ty->type->size) == 0)
330: error("unknown size of type `%t'\n", ty->type);
331: r = cast(r, promote(r->type));
332: if (n > 1)
333: r = mulnode(MUL, constnode(n, inttype), r);
334: return simplify(SUB+P, ty, l, r);
335: } else if (compatible(l->type, r->type)) {
336: if ((n = deref(l->type)->size) == 0)
337: error("unknown size of type `%t'\n", deref(l->type));
338: l = simplify(SUB+U, unsignedtype, cast(l, unsignedtype),
339: cast(r, unsignedtype));
340: return simplify(DIV+I, inttype, cast(l, inttype), constnode(n, inttype));
341: } else
342: typeerror(op, l, r);
343: return simplify(op, ty, l, r);
344: }
345:
346: /* typeerror - issue "operands of op have illegal types `l' and `r'" */
347: void typeerror(op, l, r) Tree l, r; {
348: int i;
349: static struct { Opcode op; char *name; } ops[] = {
350: ASGN, "=", INDIR, "*", NEG, "-",
351: ADD, "+", SUB, "-", LSH, "<<",
352: MOD, "%", RSH, ">>", BAND, "&",
353: BCOM, "~", BOR, "|", BXOR, "^",
354: DIV, "/", MUL, "*", EQ, "==",
355: GE, ">=", GT, ">", LE, "<=",
356: LT, "<", NE, "!=", AND, "&&",
357: NOT, "!", OR, "||", COND, "?:",
358: 0, 0
359: };
360:
361: op = generic(op);
362: for (i = 0; ops[i].op; i++)
363: if (op == ops[i].op)
364: break;
365: assert(ops[i].name);
366: if (r)
367: error("operands of %s have illegal types `%t' and `%t'\n",
368: ops[i].name, l->type, r->type);
369: else
370: error("operand of unary %s has illegal type `%t'\n", ops[i].name,
371: l->type);
372: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.