174a4d8c2SCharles.Forsyth #include "cc.h"
274a4d8c2SCharles.Forsyth
374a4d8c2SCharles.Forsyth void
complex(Node * n)474a4d8c2SCharles.Forsyth complex(Node *n)
574a4d8c2SCharles.Forsyth {
674a4d8c2SCharles.Forsyth
774a4d8c2SCharles.Forsyth if(n == Z)
874a4d8c2SCharles.Forsyth return;
974a4d8c2SCharles.Forsyth
1074a4d8c2SCharles.Forsyth nearln = n->lineno;
1174a4d8c2SCharles.Forsyth if(tcom(n))
1274a4d8c2SCharles.Forsyth return;
1374a4d8c2SCharles.Forsyth ccom(n);
1474a4d8c2SCharles.Forsyth acom(n);
1574a4d8c2SCharles.Forsyth }
1674a4d8c2SCharles.Forsyth
1774a4d8c2SCharles.Forsyth /*
1874a4d8c2SCharles.Forsyth * evaluate types
1974a4d8c2SCharles.Forsyth * evaluate lvalues (addable == 1)
2074a4d8c2SCharles.Forsyth */
2174a4d8c2SCharles.Forsyth enum
2274a4d8c2SCharles.Forsyth {
2374a4d8c2SCharles.Forsyth ADDROF = 1<<0,
2474a4d8c2SCharles.Forsyth CASTOF = 1<<1,
2574a4d8c2SCharles.Forsyth ADDROP = 1<<2,
2674a4d8c2SCharles.Forsyth };
2774a4d8c2SCharles.Forsyth
2874a4d8c2SCharles.Forsyth int
tcom(Node * n)2974a4d8c2SCharles.Forsyth tcom(Node *n)
3074a4d8c2SCharles.Forsyth {
3174a4d8c2SCharles.Forsyth
3274a4d8c2SCharles.Forsyth return tcomo(n, ADDROF);
3374a4d8c2SCharles.Forsyth }
3474a4d8c2SCharles.Forsyth
3574a4d8c2SCharles.Forsyth int
tcomo(Node * n,int f)3674a4d8c2SCharles.Forsyth tcomo(Node *n, int f)
3774a4d8c2SCharles.Forsyth {
3874a4d8c2SCharles.Forsyth Node *l, *r;
3974a4d8c2SCharles.Forsyth Type *t;
4074a4d8c2SCharles.Forsyth int o;
4174a4d8c2SCharles.Forsyth
4274a4d8c2SCharles.Forsyth if(n == Z) {
4374a4d8c2SCharles.Forsyth diag(Z, "Z in tcom");
4474a4d8c2SCharles.Forsyth errorexit();
4574a4d8c2SCharles.Forsyth }
4674a4d8c2SCharles.Forsyth l = n->left;
4774a4d8c2SCharles.Forsyth r = n->right;
4874a4d8c2SCharles.Forsyth
4974a4d8c2SCharles.Forsyth switch(n->op) {
5074a4d8c2SCharles.Forsyth default:
5174a4d8c2SCharles.Forsyth diag(n, "unknown op in type complex: %O", n->op);
5274a4d8c2SCharles.Forsyth goto bad;
5374a4d8c2SCharles.Forsyth
5474a4d8c2SCharles.Forsyth case ODOTDOT:
5574a4d8c2SCharles.Forsyth /*
5674a4d8c2SCharles.Forsyth * tcom has already been called on this subtree
5774a4d8c2SCharles.Forsyth */
5874a4d8c2SCharles.Forsyth *n = *n->left;
5974a4d8c2SCharles.Forsyth if(n->type == T)
6074a4d8c2SCharles.Forsyth goto bad;
6174a4d8c2SCharles.Forsyth break;
6274a4d8c2SCharles.Forsyth
6374a4d8c2SCharles.Forsyth case OCAST:
6474a4d8c2SCharles.Forsyth if(n->type == T)
6574a4d8c2SCharles.Forsyth break;
6674a4d8c2SCharles.Forsyth if(n->type->width == types[TLONG]->width) {
6774a4d8c2SCharles.Forsyth if(tcomo(l, ADDROF|CASTOF))
6874a4d8c2SCharles.Forsyth goto bad;
6974a4d8c2SCharles.Forsyth } else
7074a4d8c2SCharles.Forsyth if(tcom(l))
7174a4d8c2SCharles.Forsyth goto bad;
7274a4d8c2SCharles.Forsyth if(tcompat(n, l->type, n->type, tcast))
7374a4d8c2SCharles.Forsyth goto bad;
7474a4d8c2SCharles.Forsyth break;
7574a4d8c2SCharles.Forsyth
7674a4d8c2SCharles.Forsyth case ORETURN:
7774a4d8c2SCharles.Forsyth if(l == Z) {
7874a4d8c2SCharles.Forsyth if(n->type->etype != TVOID)
7974a4d8c2SCharles.Forsyth warn(n, "null return of a typed function");
8074a4d8c2SCharles.Forsyth break;
8174a4d8c2SCharles.Forsyth }
8274a4d8c2SCharles.Forsyth if(tcom(l))
8374a4d8c2SCharles.Forsyth goto bad;
8474a4d8c2SCharles.Forsyth typeext(n->type, l);
8574a4d8c2SCharles.Forsyth if(tcompat(n, n->type, l->type, tasign))
8674a4d8c2SCharles.Forsyth break;
8774a4d8c2SCharles.Forsyth constas(n, n->type, l->type);
8874a4d8c2SCharles.Forsyth if(!sametype(n->type, l->type)) {
8974a4d8c2SCharles.Forsyth l = new1(OCAST, l, Z);
9074a4d8c2SCharles.Forsyth l->type = n->type;
9174a4d8c2SCharles.Forsyth n->left = l;
9274a4d8c2SCharles.Forsyth }
9374a4d8c2SCharles.Forsyth break;
9474a4d8c2SCharles.Forsyth
9574a4d8c2SCharles.Forsyth case OASI: /* same as as, but no test for const */
9674a4d8c2SCharles.Forsyth n->op = OAS;
9774a4d8c2SCharles.Forsyth o = tcom(l);
9874a4d8c2SCharles.Forsyth if(o | tcom(r))
9974a4d8c2SCharles.Forsyth goto bad;
10074a4d8c2SCharles.Forsyth
10174a4d8c2SCharles.Forsyth typeext(l->type, r);
10274a4d8c2SCharles.Forsyth if(tlvalue(l) || tcompat(n, l->type, r->type, tasign))
10374a4d8c2SCharles.Forsyth goto bad;
10474a4d8c2SCharles.Forsyth if(!sametype(l->type, r->type)) {
10574a4d8c2SCharles.Forsyth r = new1(OCAST, r, Z);
10674a4d8c2SCharles.Forsyth r->type = l->type;
10774a4d8c2SCharles.Forsyth n->right = r;
10874a4d8c2SCharles.Forsyth }
10974a4d8c2SCharles.Forsyth n->type = l->type;
11074a4d8c2SCharles.Forsyth break;
11174a4d8c2SCharles.Forsyth
11274a4d8c2SCharles.Forsyth case OAS:
11374a4d8c2SCharles.Forsyth case OASD:
11474a4d8c2SCharles.Forsyth o = tcom(l);
11574a4d8c2SCharles.Forsyth if(o | tcom(r))
11674a4d8c2SCharles.Forsyth goto bad;
11774a4d8c2SCharles.Forsyth
11874a4d8c2SCharles.Forsyth typeext(l->type, r);
11974a4d8c2SCharles.Forsyth if(tlvalue(l) || tcompat(n, l->type, r->type, tasign))
12074a4d8c2SCharles.Forsyth goto bad;
12174a4d8c2SCharles.Forsyth constas(n, l->type, r->type);
12274a4d8c2SCharles.Forsyth if(!sametype(l->type, r->type)) {
12374a4d8c2SCharles.Forsyth r = new1(OCAST, r, Z);
12474a4d8c2SCharles.Forsyth r->type = l->type;
12574a4d8c2SCharles.Forsyth n->right = r;
12674a4d8c2SCharles.Forsyth }
12774a4d8c2SCharles.Forsyth n->type = l->type;
12874a4d8c2SCharles.Forsyth break;
12974a4d8c2SCharles.Forsyth
13074a4d8c2SCharles.Forsyth case OASADD:
13174a4d8c2SCharles.Forsyth case OASSUB:
13274a4d8c2SCharles.Forsyth o = tcom(l);
13374a4d8c2SCharles.Forsyth if(o | tcom(r))
13474a4d8c2SCharles.Forsyth goto bad;
13574a4d8c2SCharles.Forsyth typeext1(l->type, r);
13674a4d8c2SCharles.Forsyth if(tlvalue(l) || tcompat(n, l->type, r->type, tasadd))
13774a4d8c2SCharles.Forsyth goto bad;
13874a4d8c2SCharles.Forsyth constas(n, l->type, r->type);
13974a4d8c2SCharles.Forsyth t = l->type;
14074a4d8c2SCharles.Forsyth arith(n, 0);
14174a4d8c2SCharles.Forsyth while(n->left->op == OCAST)
14274a4d8c2SCharles.Forsyth n->left = n->left->left;
14374a4d8c2SCharles.Forsyth if(!sametype(t, n->type)) {
14474a4d8c2SCharles.Forsyth r = new1(OCAST, n->right, Z);
14574a4d8c2SCharles.Forsyth r->type = t;
14674a4d8c2SCharles.Forsyth n->right = r;
14774a4d8c2SCharles.Forsyth n->type = t;
14874a4d8c2SCharles.Forsyth }
14974a4d8c2SCharles.Forsyth break;
15074a4d8c2SCharles.Forsyth
15174a4d8c2SCharles.Forsyth case OASMUL:
15274a4d8c2SCharles.Forsyth case OASLMUL:
15374a4d8c2SCharles.Forsyth case OASDIV:
15474a4d8c2SCharles.Forsyth case OASLDIV:
15574a4d8c2SCharles.Forsyth o = tcom(l);
15674a4d8c2SCharles.Forsyth if(o | tcom(r))
15774a4d8c2SCharles.Forsyth goto bad;
15874a4d8c2SCharles.Forsyth typeext1(l->type, r);
15974a4d8c2SCharles.Forsyth if(tlvalue(l) || tcompat(n, l->type, r->type, tmul))
16074a4d8c2SCharles.Forsyth goto bad;
16174a4d8c2SCharles.Forsyth constas(n, l->type, r->type);
16274a4d8c2SCharles.Forsyth t = l->type;
16374a4d8c2SCharles.Forsyth arith(n, 0);
16474a4d8c2SCharles.Forsyth while(n->left->op == OCAST)
16574a4d8c2SCharles.Forsyth n->left = n->left->left;
16674a4d8c2SCharles.Forsyth if(!sametype(t, n->type)) {
16774a4d8c2SCharles.Forsyth r = new1(OCAST, n->right, Z);
16874a4d8c2SCharles.Forsyth r->type = t;
16974a4d8c2SCharles.Forsyth n->right = r;
17074a4d8c2SCharles.Forsyth n->type = t;
17174a4d8c2SCharles.Forsyth }
17274a4d8c2SCharles.Forsyth if(typeu[n->type->etype]) {
17374a4d8c2SCharles.Forsyth if(n->op == OASDIV)
17474a4d8c2SCharles.Forsyth n->op = OASLDIV;
17574a4d8c2SCharles.Forsyth if(n->op == OASMUL)
17674a4d8c2SCharles.Forsyth n->op = OASLMUL;
17774a4d8c2SCharles.Forsyth }
17874a4d8c2SCharles.Forsyth break;
17974a4d8c2SCharles.Forsyth
18074a4d8c2SCharles.Forsyth case OASLSHR:
18174a4d8c2SCharles.Forsyth case OASASHR:
18274a4d8c2SCharles.Forsyth case OASASHL:
18374a4d8c2SCharles.Forsyth o = tcom(l);
18474a4d8c2SCharles.Forsyth if(o | tcom(r))
18574a4d8c2SCharles.Forsyth goto bad;
18674a4d8c2SCharles.Forsyth if(tlvalue(l) || tcompat(n, l->type, r->type, tand))
18774a4d8c2SCharles.Forsyth goto bad;
18874a4d8c2SCharles.Forsyth n->type = l->type;
18974a4d8c2SCharles.Forsyth if(typeu[n->type->etype]) {
19074a4d8c2SCharles.Forsyth if(n->op == OASASHR)
19174a4d8c2SCharles.Forsyth n->op = OASLSHR;
19274a4d8c2SCharles.Forsyth }
19374a4d8c2SCharles.Forsyth break;
19474a4d8c2SCharles.Forsyth
19574a4d8c2SCharles.Forsyth case OASMOD:
19674a4d8c2SCharles.Forsyth case OASLMOD:
19774a4d8c2SCharles.Forsyth case OASOR:
19874a4d8c2SCharles.Forsyth case OASAND:
19974a4d8c2SCharles.Forsyth case OASXOR:
20074a4d8c2SCharles.Forsyth o = tcom(l);
20174a4d8c2SCharles.Forsyth if(o | tcom(r))
20274a4d8c2SCharles.Forsyth goto bad;
20374a4d8c2SCharles.Forsyth if(tlvalue(l) || tcompat(n, l->type, r->type, tand))
20474a4d8c2SCharles.Forsyth goto bad;
20574a4d8c2SCharles.Forsyth t = l->type;
20674a4d8c2SCharles.Forsyth arith(n, 0);
20774a4d8c2SCharles.Forsyth while(n->left->op == OCAST)
20874a4d8c2SCharles.Forsyth n->left = n->left->left;
20974a4d8c2SCharles.Forsyth if(!sametype(t, n->type)) {
21074a4d8c2SCharles.Forsyth r = new1(OCAST, n->right, Z);
21174a4d8c2SCharles.Forsyth r->type = t;
21274a4d8c2SCharles.Forsyth n->right = r;
21374a4d8c2SCharles.Forsyth n->type = t;
21474a4d8c2SCharles.Forsyth }
21574a4d8c2SCharles.Forsyth if(typeu[n->type->etype]) {
21674a4d8c2SCharles.Forsyth if(n->op == OASMOD)
21774a4d8c2SCharles.Forsyth n->op = OASLMOD;
21874a4d8c2SCharles.Forsyth }
21974a4d8c2SCharles.Forsyth break;
22074a4d8c2SCharles.Forsyth
22174a4d8c2SCharles.Forsyth case OPREINC:
22274a4d8c2SCharles.Forsyth case OPREDEC:
22374a4d8c2SCharles.Forsyth case OPOSTINC:
22474a4d8c2SCharles.Forsyth case OPOSTDEC:
22574a4d8c2SCharles.Forsyth if(tcom(l))
22674a4d8c2SCharles.Forsyth goto bad;
22774a4d8c2SCharles.Forsyth if(tlvalue(l) || tcompat(n, l->type, types[TINT], tadd))
22874a4d8c2SCharles.Forsyth goto bad;
22974a4d8c2SCharles.Forsyth n->type = l->type;
23074a4d8c2SCharles.Forsyth if(n->type->etype == TIND)
23174a4d8c2SCharles.Forsyth if(n->type->link->width < 1)
23274a4d8c2SCharles.Forsyth diag(n, "inc/dec of a void pointer");
23374a4d8c2SCharles.Forsyth break;
23474a4d8c2SCharles.Forsyth
23574a4d8c2SCharles.Forsyth case OEQ:
23674a4d8c2SCharles.Forsyth case ONE:
23774a4d8c2SCharles.Forsyth o = tcom(l);
23874a4d8c2SCharles.Forsyth if(o | tcom(r))
23974a4d8c2SCharles.Forsyth goto bad;
24074a4d8c2SCharles.Forsyth typeext(l->type, r);
24174a4d8c2SCharles.Forsyth typeext(r->type, l);
24274a4d8c2SCharles.Forsyth if(tcompat(n, l->type, r->type, trel))
24374a4d8c2SCharles.Forsyth goto bad;
24474a4d8c2SCharles.Forsyth arith(n, 0);
24574a4d8c2SCharles.Forsyth n->type = types[TINT];
24674a4d8c2SCharles.Forsyth break;
24774a4d8c2SCharles.Forsyth
24874a4d8c2SCharles.Forsyth case OLT:
24974a4d8c2SCharles.Forsyth case OGE:
25074a4d8c2SCharles.Forsyth case OGT:
25174a4d8c2SCharles.Forsyth case OLE:
25274a4d8c2SCharles.Forsyth o = tcom(l);
25374a4d8c2SCharles.Forsyth if(o | tcom(r))
25474a4d8c2SCharles.Forsyth goto bad;
25574a4d8c2SCharles.Forsyth typeext1(l->type, r);
25674a4d8c2SCharles.Forsyth typeext1(r->type, l);
25774a4d8c2SCharles.Forsyth if(tcompat(n, l->type, r->type, trel))
25874a4d8c2SCharles.Forsyth goto bad;
25974a4d8c2SCharles.Forsyth arith(n, 0);
26074a4d8c2SCharles.Forsyth if(typeu[n->type->etype])
26174a4d8c2SCharles.Forsyth n->op = logrel[relindex(n->op)];
26274a4d8c2SCharles.Forsyth n->type = types[TINT];
26374a4d8c2SCharles.Forsyth break;
26474a4d8c2SCharles.Forsyth
26574a4d8c2SCharles.Forsyth case OCOND:
26674a4d8c2SCharles.Forsyth o = tcom(l);
26774a4d8c2SCharles.Forsyth o |= tcom(r->left);
26874a4d8c2SCharles.Forsyth if(o | tcom(r->right))
26974a4d8c2SCharles.Forsyth goto bad;
27074a4d8c2SCharles.Forsyth if(r->right->type->etype == TIND && vconst(r->left) == 0) {
27174a4d8c2SCharles.Forsyth r->left->type = r->right->type;
27274a4d8c2SCharles.Forsyth r->left->vconst = 0;
27374a4d8c2SCharles.Forsyth }
27474a4d8c2SCharles.Forsyth if(r->left->type->etype == TIND && vconst(r->right) == 0) {
27574a4d8c2SCharles.Forsyth r->right->type = r->left->type;
27674a4d8c2SCharles.Forsyth r->right->vconst = 0;
27774a4d8c2SCharles.Forsyth }
27874a4d8c2SCharles.Forsyth if(sametype(r->right->type, r->left->type)) {
27974a4d8c2SCharles.Forsyth r->type = r->right->type;
28074a4d8c2SCharles.Forsyth n->type = r->type;
28174a4d8c2SCharles.Forsyth break;
28274a4d8c2SCharles.Forsyth }
28374a4d8c2SCharles.Forsyth if(tcompat(r, r->left->type, r->right->type, trel))
28474a4d8c2SCharles.Forsyth goto bad;
28574a4d8c2SCharles.Forsyth arith(r, 0);
28674a4d8c2SCharles.Forsyth n->type = r->type;
28774a4d8c2SCharles.Forsyth break;
28874a4d8c2SCharles.Forsyth
28974a4d8c2SCharles.Forsyth case OADD:
29074a4d8c2SCharles.Forsyth o = tcom(l);
29174a4d8c2SCharles.Forsyth if(o | tcom(r))
29274a4d8c2SCharles.Forsyth goto bad;
29374a4d8c2SCharles.Forsyth if(tcompat(n, l->type, r->type, tadd))
29474a4d8c2SCharles.Forsyth goto bad;
29574a4d8c2SCharles.Forsyth arith(n, 1);
29674a4d8c2SCharles.Forsyth break;
29774a4d8c2SCharles.Forsyth
29874a4d8c2SCharles.Forsyth case OSUB:
29974a4d8c2SCharles.Forsyth o = tcom(l);
30074a4d8c2SCharles.Forsyth if(o | tcom(r))
30174a4d8c2SCharles.Forsyth goto bad;
30274a4d8c2SCharles.Forsyth if(tcompat(n, l->type, r->type, tsub))
30374a4d8c2SCharles.Forsyth goto bad;
30474a4d8c2SCharles.Forsyth arith(n, 1);
30574a4d8c2SCharles.Forsyth break;
30674a4d8c2SCharles.Forsyth
30774a4d8c2SCharles.Forsyth case OMUL:
30874a4d8c2SCharles.Forsyth case OLMUL:
30974a4d8c2SCharles.Forsyth case ODIV:
31074a4d8c2SCharles.Forsyth case OLDIV:
31174a4d8c2SCharles.Forsyth o = tcom(l);
31274a4d8c2SCharles.Forsyth if(o | tcom(r))
31374a4d8c2SCharles.Forsyth goto bad;
31474a4d8c2SCharles.Forsyth if(tcompat(n, l->type, r->type, tmul))
31574a4d8c2SCharles.Forsyth goto bad;
31674a4d8c2SCharles.Forsyth arith(n, 1);
31774a4d8c2SCharles.Forsyth if(typeu[n->type->etype]) {
31874a4d8c2SCharles.Forsyth if(n->op == ODIV)
31974a4d8c2SCharles.Forsyth n->op = OLDIV;
32074a4d8c2SCharles.Forsyth if(n->op == OMUL)
32174a4d8c2SCharles.Forsyth n->op = OLMUL;
32274a4d8c2SCharles.Forsyth }
32374a4d8c2SCharles.Forsyth break;
32474a4d8c2SCharles.Forsyth
32574a4d8c2SCharles.Forsyth case OLSHR:
32674a4d8c2SCharles.Forsyth case OASHL:
32774a4d8c2SCharles.Forsyth case OASHR:
32874a4d8c2SCharles.Forsyth o = tcom(l);
32974a4d8c2SCharles.Forsyth if(o | tcom(r))
33074a4d8c2SCharles.Forsyth goto bad;
33174a4d8c2SCharles.Forsyth if(tcompat(n, l->type, r->type, tand))
33274a4d8c2SCharles.Forsyth goto bad;
33374a4d8c2SCharles.Forsyth n->right = Z;
33474a4d8c2SCharles.Forsyth arith(n, 1);
33574a4d8c2SCharles.Forsyth n->right = new1(OCAST, r, Z);
33674a4d8c2SCharles.Forsyth n->right->type = types[TINT];
33774a4d8c2SCharles.Forsyth if(typeu[n->type->etype])
33874a4d8c2SCharles.Forsyth if(n->op == OASHR)
33974a4d8c2SCharles.Forsyth n->op = OLSHR;
34074a4d8c2SCharles.Forsyth break;
34174a4d8c2SCharles.Forsyth
34274a4d8c2SCharles.Forsyth case OAND:
34374a4d8c2SCharles.Forsyth case OOR:
34474a4d8c2SCharles.Forsyth case OXOR:
34574a4d8c2SCharles.Forsyth o = tcom(l);
34674a4d8c2SCharles.Forsyth if(o | tcom(r))
34774a4d8c2SCharles.Forsyth goto bad;
34874a4d8c2SCharles.Forsyth if(tcompat(n, l->type, r->type, tand))
34974a4d8c2SCharles.Forsyth goto bad;
35074a4d8c2SCharles.Forsyth arith(n, 1);
35174a4d8c2SCharles.Forsyth break;
35274a4d8c2SCharles.Forsyth
35374a4d8c2SCharles.Forsyth case OMOD:
35474a4d8c2SCharles.Forsyth case OLMOD:
35574a4d8c2SCharles.Forsyth o = tcom(l);
35674a4d8c2SCharles.Forsyth if(o | tcom(r))
35774a4d8c2SCharles.Forsyth goto bad;
35874a4d8c2SCharles.Forsyth if(tcompat(n, l->type, r->type, tand))
35974a4d8c2SCharles.Forsyth goto bad;
36074a4d8c2SCharles.Forsyth arith(n, 1);
36174a4d8c2SCharles.Forsyth if(typeu[n->type->etype])
36274a4d8c2SCharles.Forsyth n->op = OLMOD;
36374a4d8c2SCharles.Forsyth break;
36474a4d8c2SCharles.Forsyth
36574a4d8c2SCharles.Forsyth case ONOT:
36674a4d8c2SCharles.Forsyth if(tcom(l))
36774a4d8c2SCharles.Forsyth goto bad;
36874a4d8c2SCharles.Forsyth if(tcompat(n, T, l->type, tnot))
36974a4d8c2SCharles.Forsyth goto bad;
37074a4d8c2SCharles.Forsyth n->type = types[TINT];
37174a4d8c2SCharles.Forsyth break;
37274a4d8c2SCharles.Forsyth
37374a4d8c2SCharles.Forsyth case OPOS:
37474a4d8c2SCharles.Forsyth case ONEG:
37574a4d8c2SCharles.Forsyth case OCOM:
37674a4d8c2SCharles.Forsyth if(tcom(l))
37774a4d8c2SCharles.Forsyth goto bad;
37874a4d8c2SCharles.Forsyth n->type = l->type;
37974a4d8c2SCharles.Forsyth break;
38074a4d8c2SCharles.Forsyth
38174a4d8c2SCharles.Forsyth case ONUL:
38274a4d8c2SCharles.Forsyth break;
38374a4d8c2SCharles.Forsyth
38474a4d8c2SCharles.Forsyth case OIOTA:
38574a4d8c2SCharles.Forsyth n->type = types[TINT];
38674a4d8c2SCharles.Forsyth break;
38774a4d8c2SCharles.Forsyth
38874a4d8c2SCharles.Forsyth case ODAS:
38974a4d8c2SCharles.Forsyth n->type = n->left->type;
39074a4d8c2SCharles.Forsyth break;
39174a4d8c2SCharles.Forsyth
39274a4d8c2SCharles.Forsyth case OANDAND:
39374a4d8c2SCharles.Forsyth case OOROR:
39474a4d8c2SCharles.Forsyth o = tcom(l);
39574a4d8c2SCharles.Forsyth if(o | tcom(r))
39674a4d8c2SCharles.Forsyth goto bad;
39774a4d8c2SCharles.Forsyth if(tcompat(n, T, l->type, tnot) |
39874a4d8c2SCharles.Forsyth tcompat(n, T, r->type, tnot))
39974a4d8c2SCharles.Forsyth goto bad;
40074a4d8c2SCharles.Forsyth n->type = types[TINT];
40174a4d8c2SCharles.Forsyth break;
40274a4d8c2SCharles.Forsyth
40374a4d8c2SCharles.Forsyth case OCOMMA:
40474a4d8c2SCharles.Forsyth o = tcom(l);
40574a4d8c2SCharles.Forsyth if(o | tcom(r))
40674a4d8c2SCharles.Forsyth goto bad;
40774a4d8c2SCharles.Forsyth n->type = r->type;
40874a4d8c2SCharles.Forsyth break;
40974a4d8c2SCharles.Forsyth
41074a4d8c2SCharles.Forsyth
41174a4d8c2SCharles.Forsyth case OSIGN: /* extension signof(type) returns a hash */
41274a4d8c2SCharles.Forsyth if(l != Z) {
41374a4d8c2SCharles.Forsyth if(l->op != OSTRING && l->op != OLSTRING)
41474a4d8c2SCharles.Forsyth if(tcomo(l, 0))
41574a4d8c2SCharles.Forsyth goto bad;
41674a4d8c2SCharles.Forsyth if(l->op == OBIT) {
41774a4d8c2SCharles.Forsyth diag(n, "signof bitfield");
41874a4d8c2SCharles.Forsyth goto bad;
41974a4d8c2SCharles.Forsyth }
42074a4d8c2SCharles.Forsyth n->type = l->type;
42174a4d8c2SCharles.Forsyth }
42274a4d8c2SCharles.Forsyth if(n->type == T)
42374a4d8c2SCharles.Forsyth goto bad;
42474a4d8c2SCharles.Forsyth if(n->type->width < 0) {
42574a4d8c2SCharles.Forsyth diag(n, "signof undefined type");
42674a4d8c2SCharles.Forsyth goto bad;
42774a4d8c2SCharles.Forsyth }
42874a4d8c2SCharles.Forsyth n->right = ncopy(n);
42974a4d8c2SCharles.Forsyth n->op = OCONST;
43074a4d8c2SCharles.Forsyth n->left = Z;
43174a4d8c2SCharles.Forsyth /* n->right = Z; */
43274a4d8c2SCharles.Forsyth n->vconst = convvtox(signature(n->type, 10), TULONG);
43374a4d8c2SCharles.Forsyth n->type = types[TULONG];
43474a4d8c2SCharles.Forsyth break;
43574a4d8c2SCharles.Forsyth
43674a4d8c2SCharles.Forsyth case OSIZE:
43774a4d8c2SCharles.Forsyth if(l != Z) {
43874a4d8c2SCharles.Forsyth if(l->op != OSTRING && l->op != OLSTRING)
43974a4d8c2SCharles.Forsyth if(tcomo(l, 0))
44074a4d8c2SCharles.Forsyth goto bad;
44174a4d8c2SCharles.Forsyth if(l->op == OBIT) {
44274a4d8c2SCharles.Forsyth diag(n, "sizeof bitfield");
44374a4d8c2SCharles.Forsyth goto bad;
44474a4d8c2SCharles.Forsyth }
44574a4d8c2SCharles.Forsyth n->type = l->type;
44674a4d8c2SCharles.Forsyth }
44774a4d8c2SCharles.Forsyth if(n->type == T)
44874a4d8c2SCharles.Forsyth goto bad;
44974a4d8c2SCharles.Forsyth if(n->type->width <= 0) {
45074a4d8c2SCharles.Forsyth diag(n, "sizeof undefined type");
45174a4d8c2SCharles.Forsyth goto bad;
45274a4d8c2SCharles.Forsyth }
45374a4d8c2SCharles.Forsyth if(n->type->etype == TFUNC) {
45474a4d8c2SCharles.Forsyth diag(n, "sizeof function");
45574a4d8c2SCharles.Forsyth goto bad;
45674a4d8c2SCharles.Forsyth }
45774a4d8c2SCharles.Forsyth n->right = ncopy(n);
45874a4d8c2SCharles.Forsyth n->op = OCONST;
45974a4d8c2SCharles.Forsyth n->left = Z;
46074a4d8c2SCharles.Forsyth /* n->right = Z; */
46174a4d8c2SCharles.Forsyth n->vconst = convvtox(n->type->width, TINT);
46274a4d8c2SCharles.Forsyth n->type = types[TINT];
46374a4d8c2SCharles.Forsyth break;
46474a4d8c2SCharles.Forsyth
46574a4d8c2SCharles.Forsyth case OFUNC:
46674a4d8c2SCharles.Forsyth o = tcomo(l, 0);
46774a4d8c2SCharles.Forsyth if(o)
46874a4d8c2SCharles.Forsyth goto bad;
46974a4d8c2SCharles.Forsyth if(l->type->etype == TIND && l->type->link->etype == TFUNC) {
47074a4d8c2SCharles.Forsyth l = new1(OIND, l, Z);
47174a4d8c2SCharles.Forsyth l->type = l->left->type->link;
47274a4d8c2SCharles.Forsyth n->left = l;
47374a4d8c2SCharles.Forsyth }
47474a4d8c2SCharles.Forsyth if(tcompat(n, T, l->type, tfunct))
47574a4d8c2SCharles.Forsyth goto bad;
47674a4d8c2SCharles.Forsyth if(o | tcoma(l, r, l->type->down, 1))
47774a4d8c2SCharles.Forsyth goto bad;
47874a4d8c2SCharles.Forsyth n->type = l->type->link;
47974a4d8c2SCharles.Forsyth if(1)
48074a4d8c2SCharles.Forsyth if(l->type->down == T || l->type->down->etype == TOLD) {
48174a4d8c2SCharles.Forsyth nerrors--;
48274a4d8c2SCharles.Forsyth diag(n, "function args not checked: %F", l);
48374a4d8c2SCharles.Forsyth }
48474a4d8c2SCharles.Forsyth dpcheck(n);
48574a4d8c2SCharles.Forsyth break;
48674a4d8c2SCharles.Forsyth
48774a4d8c2SCharles.Forsyth case ONAME:
48874a4d8c2SCharles.Forsyth if(n->type == T) {
48974a4d8c2SCharles.Forsyth diag(n, "name not declared: %F", n);
49074a4d8c2SCharles.Forsyth goto bad;
49174a4d8c2SCharles.Forsyth }
49274a4d8c2SCharles.Forsyth if(n->type->etype == TENUM) {
49374a4d8c2SCharles.Forsyth if(n->sym->tenum->etype == TIND){
49474a4d8c2SCharles.Forsyth /* n->op = OSTRING; */
49574a4d8c2SCharles.Forsyth n->type = n->sym->tenum;
49674a4d8c2SCharles.Forsyth /* n->cstring = n->sym->sconst; */
49774a4d8c2SCharles.Forsyth break;
49874a4d8c2SCharles.Forsyth }
49974a4d8c2SCharles.Forsyth n->left = ncopy(n);
50074a4d8c2SCharles.Forsyth n->op = OCONST;
50174a4d8c2SCharles.Forsyth n->type = n->sym->tenum;
50274a4d8c2SCharles.Forsyth if(!typefd[n->type->etype])
50374a4d8c2SCharles.Forsyth n->vconst = n->sym->vconst;
50474a4d8c2SCharles.Forsyth else{
50574a4d8c2SCharles.Forsyth n->fconst = n->sym->fconst;
50674a4d8c2SCharles.Forsyth n->cstring = n->sym->cstring;
50774a4d8c2SCharles.Forsyth }
50874a4d8c2SCharles.Forsyth break;
50974a4d8c2SCharles.Forsyth }
51074a4d8c2SCharles.Forsyth break;
51174a4d8c2SCharles.Forsyth
51274a4d8c2SCharles.Forsyth case OLSTRING:
51374a4d8c2SCharles.Forsyth case OSTRING:
51474a4d8c2SCharles.Forsyth case OCONST:
51574a4d8c2SCharles.Forsyth break;
51674a4d8c2SCharles.Forsyth
51774a4d8c2SCharles.Forsyth case ODOT:
51874a4d8c2SCharles.Forsyth if(tcom(l))
51974a4d8c2SCharles.Forsyth goto bad;
52074a4d8c2SCharles.Forsyth if(tcompat(n, T, l->type, tdot))
52174a4d8c2SCharles.Forsyth goto bad;
52274a4d8c2SCharles.Forsyth if(tcomd(n, l->type))
52374a4d8c2SCharles.Forsyth goto bad;
52474a4d8c2SCharles.Forsyth break;
52574a4d8c2SCharles.Forsyth
52674a4d8c2SCharles.Forsyth case ODOTIND:
52774a4d8c2SCharles.Forsyth if(tcom(l))
52874a4d8c2SCharles.Forsyth goto bad;
52974a4d8c2SCharles.Forsyth if(tcompat(n, T, l->type, tindir))
53074a4d8c2SCharles.Forsyth goto bad;
53174a4d8c2SCharles.Forsyth if(tcompat(n, T, l->type->link, tdot))
53274a4d8c2SCharles.Forsyth goto bad;
53374a4d8c2SCharles.Forsyth if(tcomd(n, l->type->link))
53474a4d8c2SCharles.Forsyth goto bad;
53574a4d8c2SCharles.Forsyth break;
53674a4d8c2SCharles.Forsyth
53774a4d8c2SCharles.Forsyth case OARRIND:
53874a4d8c2SCharles.Forsyth if(tcom(l))
53974a4d8c2SCharles.Forsyth goto bad;
54074a4d8c2SCharles.Forsyth if(tcompat(n, T, l->type, tindir))
54174a4d8c2SCharles.Forsyth goto bad;
54274a4d8c2SCharles.Forsyth n->type = l->type->link;
54374a4d8c2SCharles.Forsyth if(tcom(r))
54474a4d8c2SCharles.Forsyth goto bad;
54574a4d8c2SCharles.Forsyth break;
54674a4d8c2SCharles.Forsyth
54774a4d8c2SCharles.Forsyth case OADDR:
54874a4d8c2SCharles.Forsyth if(tcomo(l, ADDROP))
54974a4d8c2SCharles.Forsyth goto bad;
55074a4d8c2SCharles.Forsyth if(tlvalue(l))
55174a4d8c2SCharles.Forsyth goto bad;
55274a4d8c2SCharles.Forsyth if(l->type->nbits) {
55374a4d8c2SCharles.Forsyth diag(n, "address of a bit field");
55474a4d8c2SCharles.Forsyth goto bad;
55574a4d8c2SCharles.Forsyth }
55674a4d8c2SCharles.Forsyth if(l->op == OREGISTER) {
55774a4d8c2SCharles.Forsyth diag(n, "address of a register");
55874a4d8c2SCharles.Forsyth goto bad;
55974a4d8c2SCharles.Forsyth }
56074a4d8c2SCharles.Forsyth n->type = typ1(TIND, l->type);
56174a4d8c2SCharles.Forsyth n->type->width = types[TIND]->width;
56274a4d8c2SCharles.Forsyth break;
56374a4d8c2SCharles.Forsyth
56474a4d8c2SCharles.Forsyth case OIND:
56574a4d8c2SCharles.Forsyth if(tcom(l))
56674a4d8c2SCharles.Forsyth goto bad;
56774a4d8c2SCharles.Forsyth if(tcompat(n, T, l->type, tindir))
56874a4d8c2SCharles.Forsyth goto bad;
56974a4d8c2SCharles.Forsyth n->type = l->type->link;
57074a4d8c2SCharles.Forsyth break;
57174a4d8c2SCharles.Forsyth
57274a4d8c2SCharles.Forsyth case OSTRUCT:
57374a4d8c2SCharles.Forsyth if(tcomx(n))
57474a4d8c2SCharles.Forsyth goto bad;
57574a4d8c2SCharles.Forsyth break;
57674a4d8c2SCharles.Forsyth }
57774a4d8c2SCharles.Forsyth t = n->type;
57874a4d8c2SCharles.Forsyth if(t == T)
57974a4d8c2SCharles.Forsyth goto bad;
58074a4d8c2SCharles.Forsyth if(t->width < 0) {
58174a4d8c2SCharles.Forsyth snap(t);
58274a4d8c2SCharles.Forsyth if(t->width < 0) {
58374a4d8c2SCharles.Forsyth if(typesu[t->etype] && t->tag)
58474a4d8c2SCharles.Forsyth diag(n, "structure not fully declared %s", t->tag->name);
58574a4d8c2SCharles.Forsyth else
58674a4d8c2SCharles.Forsyth diag(n, "structure not fully declared");
58774a4d8c2SCharles.Forsyth goto bad;
58874a4d8c2SCharles.Forsyth }
58974a4d8c2SCharles.Forsyth }
59074a4d8c2SCharles.Forsyth if(typeaf[t->etype]) {
59174a4d8c2SCharles.Forsyth if(f & ADDROF)
59274a4d8c2SCharles.Forsyth goto addaddr;
59374a4d8c2SCharles.Forsyth if(f & ADDROP)
59474a4d8c2SCharles.Forsyth warn(n, "address of array/func ignored");
59574a4d8c2SCharles.Forsyth }
59674a4d8c2SCharles.Forsyth return 0;
59774a4d8c2SCharles.Forsyth
59874a4d8c2SCharles.Forsyth addaddr:
59974a4d8c2SCharles.Forsyth if(n->type->etype == TARRAY)
60074a4d8c2SCharles.Forsyth n->type = typ1(TIND, n->type->link);
60174a4d8c2SCharles.Forsyth return 0;
602*d67b7dadSforsyth #ifdef WHATEVA
60374a4d8c2SCharles.Forsyth if(tlvalue(n))
60474a4d8c2SCharles.Forsyth goto bad;
60574a4d8c2SCharles.Forsyth l = new1(OXXX, Z, Z);
60674a4d8c2SCharles.Forsyth *l = *n;
60774a4d8c2SCharles.Forsyth n->op = OADDR;
60874a4d8c2SCharles.Forsyth if(l->type->etype == TARRAY)
60974a4d8c2SCharles.Forsyth l->type = l->type->link;
61074a4d8c2SCharles.Forsyth n->left = l;
61174a4d8c2SCharles.Forsyth n->right = Z;
61274a4d8c2SCharles.Forsyth n->type = typ1(TIND, l->type);
61374a4d8c2SCharles.Forsyth n->type->width = types[TIND]->width;
61474a4d8c2SCharles.Forsyth return 0;
615*d67b7dadSforsyth #endif
61674a4d8c2SCharles.Forsyth
61774a4d8c2SCharles.Forsyth bad:
61874a4d8c2SCharles.Forsyth n->type = T;
61974a4d8c2SCharles.Forsyth return 1;
62074a4d8c2SCharles.Forsyth }
62174a4d8c2SCharles.Forsyth
62274a4d8c2SCharles.Forsyth int
tcoma(Node * l,Node * n,Type * t,int f)62374a4d8c2SCharles.Forsyth tcoma(Node *l, Node *n, Type *t, int f)
62474a4d8c2SCharles.Forsyth {
62574a4d8c2SCharles.Forsyth Node *n1;
62674a4d8c2SCharles.Forsyth int o;
62774a4d8c2SCharles.Forsyth
62874a4d8c2SCharles.Forsyth if(t != T)
62974a4d8c2SCharles.Forsyth if(t->etype == TOLD || t->etype == TDOT) /* .../old in prototype */
63074a4d8c2SCharles.Forsyth t = T;
63174a4d8c2SCharles.Forsyth if(n == Z) {
63274a4d8c2SCharles.Forsyth if(t != T && !sametype(t, types[TVOID])) {
63374a4d8c2SCharles.Forsyth diag(n, "not enough function arguments: %F", l);
63474a4d8c2SCharles.Forsyth return 1;
63574a4d8c2SCharles.Forsyth }
63674a4d8c2SCharles.Forsyth return 0;
63774a4d8c2SCharles.Forsyth }
63874a4d8c2SCharles.Forsyth if(n->op == OLIST) {
63974a4d8c2SCharles.Forsyth o = tcoma(l, n->left, t, 0);
64074a4d8c2SCharles.Forsyth if(t != T) {
64174a4d8c2SCharles.Forsyth t = t->down;
64274a4d8c2SCharles.Forsyth if(t == T)
64374a4d8c2SCharles.Forsyth t = types[TVOID];
64474a4d8c2SCharles.Forsyth }
64574a4d8c2SCharles.Forsyth return o | tcoma(l, n->right, t, 1);
64674a4d8c2SCharles.Forsyth }
64774a4d8c2SCharles.Forsyth if(f && t != T)
64874a4d8c2SCharles.Forsyth tcoma(l, Z, t->down, 0);
64974a4d8c2SCharles.Forsyth if(tcom(n) || tcompat(n, T, n->type, targ))
65074a4d8c2SCharles.Forsyth return 1;
65174a4d8c2SCharles.Forsyth if(sametype(t, types[TVOID])) {
65274a4d8c2SCharles.Forsyth diag(n, "too many function arguments: %F", l);
65374a4d8c2SCharles.Forsyth return 1;
65474a4d8c2SCharles.Forsyth }
65574a4d8c2SCharles.Forsyth if(t != T) {
65674a4d8c2SCharles.Forsyth typeext(t, n);
65774a4d8c2SCharles.Forsyth if(stcompat(nodproto, t, n->type, tasign)) {
65874a4d8c2SCharles.Forsyth diag(l, "argument prototype mismatch \"%T\" for \"%T\": %F",
65974a4d8c2SCharles.Forsyth n->type, t, l);
66074a4d8c2SCharles.Forsyth return 1;
66174a4d8c2SCharles.Forsyth }
66274a4d8c2SCharles.Forsyth switch(t->etype) {
66374a4d8c2SCharles.Forsyth case TCHAR:
66474a4d8c2SCharles.Forsyth case TSHORT:
66574a4d8c2SCharles.Forsyth /* t = types[TINT]; */
66674a4d8c2SCharles.Forsyth break;
66774a4d8c2SCharles.Forsyth
66874a4d8c2SCharles.Forsyth case TUCHAR:
66974a4d8c2SCharles.Forsyth case TUSHORT:
67074a4d8c2SCharles.Forsyth /* t = types[TUINT]; */
67174a4d8c2SCharles.Forsyth break;
67274a4d8c2SCharles.Forsyth }
67374a4d8c2SCharles.Forsyth } else {
67474a4d8c2SCharles.Forsyth switch(n->type->etype)
67574a4d8c2SCharles.Forsyth {
67674a4d8c2SCharles.Forsyth case TCHAR:
67774a4d8c2SCharles.Forsyth case TSHORT:
67874a4d8c2SCharles.Forsyth /* t = types[TINT]; */
67974a4d8c2SCharles.Forsyth t = n->type;
68074a4d8c2SCharles.Forsyth break;
68174a4d8c2SCharles.Forsyth
68274a4d8c2SCharles.Forsyth case TUCHAR:
68374a4d8c2SCharles.Forsyth case TUSHORT:
68474a4d8c2SCharles.Forsyth /* t = types[TUINT]; */
68574a4d8c2SCharles.Forsyth t = n->type;
68674a4d8c2SCharles.Forsyth break;
68774a4d8c2SCharles.Forsyth
68874a4d8c2SCharles.Forsyth case TFLOAT:
68974a4d8c2SCharles.Forsyth /* t = types[TDOUBLE]; */
69074a4d8c2SCharles.Forsyth t = n->type;
69174a4d8c2SCharles.Forsyth }
69274a4d8c2SCharles.Forsyth }
69374a4d8c2SCharles.Forsyth if(t != T && !sametype(t, n->type)) {
69474a4d8c2SCharles.Forsyth n1 = new1(OXXX, Z, Z);
69574a4d8c2SCharles.Forsyth *n1 = *n;
69674a4d8c2SCharles.Forsyth n->op = OCAST;
69774a4d8c2SCharles.Forsyth n->left = n1;
69874a4d8c2SCharles.Forsyth n->right = Z;
69974a4d8c2SCharles.Forsyth n->type = t;
70074a4d8c2SCharles.Forsyth }
70174a4d8c2SCharles.Forsyth return 0;
70274a4d8c2SCharles.Forsyth }
70374a4d8c2SCharles.Forsyth
70474a4d8c2SCharles.Forsyth int
tcomd(Node * n,Type * t)70574a4d8c2SCharles.Forsyth tcomd(Node *n, Type *t)
70674a4d8c2SCharles.Forsyth {
70774a4d8c2SCharles.Forsyth long o;
70874a4d8c2SCharles.Forsyth
70974a4d8c2SCharles.Forsyth o = 0;
71074a4d8c2SCharles.Forsyth /* t = n->left->type; */
71174a4d8c2SCharles.Forsyth for(;;) {
71274a4d8c2SCharles.Forsyth t = dotsearch(n->sym, t->link, n);
71374a4d8c2SCharles.Forsyth if(t == T) {
71474a4d8c2SCharles.Forsyth diag(n, "not a member of struct/union: %F", n);
71574a4d8c2SCharles.Forsyth return 1;
71674a4d8c2SCharles.Forsyth }
71774a4d8c2SCharles.Forsyth o += t->offset;
71874a4d8c2SCharles.Forsyth if(t->sym == n->sym)
71974a4d8c2SCharles.Forsyth break;
72074a4d8c2SCharles.Forsyth if(sametype(t, n->sym->type))
72174a4d8c2SCharles.Forsyth break;
72274a4d8c2SCharles.Forsyth }
72374a4d8c2SCharles.Forsyth n->type = t;
72474a4d8c2SCharles.Forsyth return 0;
72574a4d8c2SCharles.Forsyth }
72674a4d8c2SCharles.Forsyth
72774a4d8c2SCharles.Forsyth int
tcomx(Node * n)72874a4d8c2SCharles.Forsyth tcomx(Node *n)
72974a4d8c2SCharles.Forsyth {
73074a4d8c2SCharles.Forsyth Type *t;
73174a4d8c2SCharles.Forsyth Node *l, *r, **ar, **al;
73274a4d8c2SCharles.Forsyth int e;
73374a4d8c2SCharles.Forsyth
73474a4d8c2SCharles.Forsyth e = 0;
73574a4d8c2SCharles.Forsyth if(n->type->etype != TSTRUCT) {
73674a4d8c2SCharles.Forsyth diag(n, "constructor must be a structure");
73774a4d8c2SCharles.Forsyth return 1;
73874a4d8c2SCharles.Forsyth }
73974a4d8c2SCharles.Forsyth l = invert(n->left);
74074a4d8c2SCharles.Forsyth n->left = l;
74174a4d8c2SCharles.Forsyth al = &n->left;
74274a4d8c2SCharles.Forsyth for(t = n->type->link; t != T; t = t->down) {
74374a4d8c2SCharles.Forsyth if(l == Z) {
74474a4d8c2SCharles.Forsyth diag(n, "constructor list too short");
74574a4d8c2SCharles.Forsyth return 1;
74674a4d8c2SCharles.Forsyth }
74774a4d8c2SCharles.Forsyth if(l->op == OLIST) {
74874a4d8c2SCharles.Forsyth r = l->left;
74974a4d8c2SCharles.Forsyth ar = &l->left;
75074a4d8c2SCharles.Forsyth al = &l->right;
75174a4d8c2SCharles.Forsyth l = l->right;
75274a4d8c2SCharles.Forsyth } else {
75374a4d8c2SCharles.Forsyth r = l;
75474a4d8c2SCharles.Forsyth ar = al;
75574a4d8c2SCharles.Forsyth l = Z;
75674a4d8c2SCharles.Forsyth }
75774a4d8c2SCharles.Forsyth if(tcom(r))
75874a4d8c2SCharles.Forsyth e++;
75974a4d8c2SCharles.Forsyth typeext(t, r);
76074a4d8c2SCharles.Forsyth if(tcompat(n, t, r->type, tasign))
76174a4d8c2SCharles.Forsyth e++;
76274a4d8c2SCharles.Forsyth constas(n, t, r->type);
76374a4d8c2SCharles.Forsyth if(!e && !sametype(t, r->type)) {
76474a4d8c2SCharles.Forsyth r = new1(OCAST, r, Z);
76574a4d8c2SCharles.Forsyth r->type = t;
76674a4d8c2SCharles.Forsyth *ar = r;
76774a4d8c2SCharles.Forsyth }
76874a4d8c2SCharles.Forsyth }
76974a4d8c2SCharles.Forsyth if(l != Z) {
77074a4d8c2SCharles.Forsyth diag(n, "constructor list too long");
77174a4d8c2SCharles.Forsyth return 1;
77274a4d8c2SCharles.Forsyth }
77374a4d8c2SCharles.Forsyth return e;
77474a4d8c2SCharles.Forsyth }
77574a4d8c2SCharles.Forsyth
77674a4d8c2SCharles.Forsyth int
tlvalue(Node * n)77774a4d8c2SCharles.Forsyth tlvalue(Node *n)
77874a4d8c2SCharles.Forsyth {
77974a4d8c2SCharles.Forsyth
78074a4d8c2SCharles.Forsyth if(0) {
78174a4d8c2SCharles.Forsyth diag(n, "not an l-value");
78274a4d8c2SCharles.Forsyth return 1;
78374a4d8c2SCharles.Forsyth }
78474a4d8c2SCharles.Forsyth return 0;
78574a4d8c2SCharles.Forsyth }
78674a4d8c2SCharles.Forsyth
78774a4d8c2SCharles.Forsyth /*
78874a4d8c2SCharles.Forsyth * general rewrite
78974a4d8c2SCharles.Forsyth * (IND(ADDR x)) ==> x
79074a4d8c2SCharles.Forsyth * (ADDR(IND x)) ==> x
79174a4d8c2SCharles.Forsyth * remove some zero operands
79274a4d8c2SCharles.Forsyth * remove no op casts
79374a4d8c2SCharles.Forsyth * evaluate constants
79474a4d8c2SCharles.Forsyth */
79574a4d8c2SCharles.Forsyth void
ccom(Node * n)79674a4d8c2SCharles.Forsyth ccom(Node *n)
79774a4d8c2SCharles.Forsyth {
79874a4d8c2SCharles.Forsyth Node *l, *r;
79974a4d8c2SCharles.Forsyth int t;
80074a4d8c2SCharles.Forsyth
80174a4d8c2SCharles.Forsyth if(n == Z)
80274a4d8c2SCharles.Forsyth return;
80374a4d8c2SCharles.Forsyth l = n->left;
80474a4d8c2SCharles.Forsyth r = n->right;
80574a4d8c2SCharles.Forsyth switch(n->op) {
80674a4d8c2SCharles.Forsyth
80774a4d8c2SCharles.Forsyth case OAS:
80874a4d8c2SCharles.Forsyth case OASD:
80974a4d8c2SCharles.Forsyth case OASXOR:
81074a4d8c2SCharles.Forsyth case OASAND:
81174a4d8c2SCharles.Forsyth case OASOR:
81274a4d8c2SCharles.Forsyth case OASMOD:
81374a4d8c2SCharles.Forsyth case OASLMOD:
81474a4d8c2SCharles.Forsyth case OASLSHR:
81574a4d8c2SCharles.Forsyth case OASASHR:
81674a4d8c2SCharles.Forsyth case OASASHL:
81774a4d8c2SCharles.Forsyth case OASDIV:
81874a4d8c2SCharles.Forsyth case OASLDIV:
81974a4d8c2SCharles.Forsyth case OASMUL:
82074a4d8c2SCharles.Forsyth case OASLMUL:
82174a4d8c2SCharles.Forsyth case OASSUB:
82274a4d8c2SCharles.Forsyth case OASADD:
82374a4d8c2SCharles.Forsyth ccom(l);
82474a4d8c2SCharles.Forsyth ccom(r);
82574a4d8c2SCharles.Forsyth if(n->op == OASLSHR || n->op == OASASHR || n->op == OASASHL)
82674a4d8c2SCharles.Forsyth if(r->op == OCONST) {
82774a4d8c2SCharles.Forsyth t = n->type->width * 8; /* bits per byte */
82874a4d8c2SCharles.Forsyth if(r->vconst >= t || r->vconst < 0)
82974a4d8c2SCharles.Forsyth warn(n, "stupid shift: %lld", r->vconst);
83074a4d8c2SCharles.Forsyth }
83174a4d8c2SCharles.Forsyth break;
83274a4d8c2SCharles.Forsyth
83374a4d8c2SCharles.Forsyth case OCAST:
83474a4d8c2SCharles.Forsyth ccom(l);
83574a4d8c2SCharles.Forsyth if(l->op == OCONST) {
83674a4d8c2SCharles.Forsyth evconst(n);
83774a4d8c2SCharles.Forsyth if(n->op == OCONST)
83874a4d8c2SCharles.Forsyth break;
83974a4d8c2SCharles.Forsyth }
84074a4d8c2SCharles.Forsyth if(nocast(l->type, n->type)) {
84174a4d8c2SCharles.Forsyth l->type = n->type;
84274a4d8c2SCharles.Forsyth *n = *l;
84374a4d8c2SCharles.Forsyth }
84474a4d8c2SCharles.Forsyth break;
84574a4d8c2SCharles.Forsyth
84674a4d8c2SCharles.Forsyth case OCOND:
84774a4d8c2SCharles.Forsyth ccom(l);
84874a4d8c2SCharles.Forsyth ccom(r);
84974a4d8c2SCharles.Forsyth break;
85074a4d8c2SCharles.Forsyth
85174a4d8c2SCharles.Forsyth case OREGISTER:
85274a4d8c2SCharles.Forsyth case OINDREG:
85374a4d8c2SCharles.Forsyth case OCONST:
85474a4d8c2SCharles.Forsyth case ONAME:
85574a4d8c2SCharles.Forsyth break;
85674a4d8c2SCharles.Forsyth
85774a4d8c2SCharles.Forsyth case OADDR:
85874a4d8c2SCharles.Forsyth ccom(l);
85974a4d8c2SCharles.Forsyth /* l->etype = TVOID; */
86074a4d8c2SCharles.Forsyth if(l->op == OIND) {
86174a4d8c2SCharles.Forsyth l->left->type = n->type;
86274a4d8c2SCharles.Forsyth *n = *l->left;
86374a4d8c2SCharles.Forsyth break;
86474a4d8c2SCharles.Forsyth }
86574a4d8c2SCharles.Forsyth goto common;
86674a4d8c2SCharles.Forsyth
86774a4d8c2SCharles.Forsyth case OIND:
86874a4d8c2SCharles.Forsyth ccom(l);
86974a4d8c2SCharles.Forsyth if(l->op == OADDR) {
87074a4d8c2SCharles.Forsyth l->left->type = n->type;
87174a4d8c2SCharles.Forsyth *n = *l->left;
87274a4d8c2SCharles.Forsyth break;
87374a4d8c2SCharles.Forsyth }
87474a4d8c2SCharles.Forsyth goto common;
87574a4d8c2SCharles.Forsyth
87674a4d8c2SCharles.Forsyth case OEQ:
87774a4d8c2SCharles.Forsyth case ONE:
87874a4d8c2SCharles.Forsyth
87974a4d8c2SCharles.Forsyth case OLE:
88074a4d8c2SCharles.Forsyth case OGE:
88174a4d8c2SCharles.Forsyth case OLT:
88274a4d8c2SCharles.Forsyth case OGT:
88374a4d8c2SCharles.Forsyth
88474a4d8c2SCharles.Forsyth case OLS:
88574a4d8c2SCharles.Forsyth case OHS:
88674a4d8c2SCharles.Forsyth case OLO:
88774a4d8c2SCharles.Forsyth case OHI:
88874a4d8c2SCharles.Forsyth ccom(l);
88974a4d8c2SCharles.Forsyth ccom(r);
89074a4d8c2SCharles.Forsyth relcon(l, r);
89174a4d8c2SCharles.Forsyth relcon(r, l);
89274a4d8c2SCharles.Forsyth goto common;
89374a4d8c2SCharles.Forsyth
89474a4d8c2SCharles.Forsyth case OASHR:
89574a4d8c2SCharles.Forsyth case OASHL:
89674a4d8c2SCharles.Forsyth case OLSHR:
89774a4d8c2SCharles.Forsyth ccom(l);
89874a4d8c2SCharles.Forsyth ccom(r);
89974a4d8c2SCharles.Forsyth if(r->op == OCONST) {
90074a4d8c2SCharles.Forsyth t = n->type->width * 8; /* bits per byte */
90174a4d8c2SCharles.Forsyth if(r->vconst >= t || r->vconst <= -t)
90274a4d8c2SCharles.Forsyth warn(n, "stupid shift: %lld", r->vconst);
90374a4d8c2SCharles.Forsyth }
90474a4d8c2SCharles.Forsyth goto common;
90574a4d8c2SCharles.Forsyth
90674a4d8c2SCharles.Forsyth default:
90774a4d8c2SCharles.Forsyth if(l != Z)
90874a4d8c2SCharles.Forsyth ccom(l);
90974a4d8c2SCharles.Forsyth if(r != Z)
91074a4d8c2SCharles.Forsyth ccom(r);
91174a4d8c2SCharles.Forsyth common:
91274a4d8c2SCharles.Forsyth if(l != Z)
91374a4d8c2SCharles.Forsyth if(l->op != OCONST)
91474a4d8c2SCharles.Forsyth break;
91574a4d8c2SCharles.Forsyth if(r != Z)
91674a4d8c2SCharles.Forsyth if(r->op != OCONST)
91774a4d8c2SCharles.Forsyth break;
91874a4d8c2SCharles.Forsyth evconst(n);
91974a4d8c2SCharles.Forsyth }
92074a4d8c2SCharles.Forsyth }
921