📄 com.c
字号:
#include "cc.h"int compar(Node*, int);voidcomplex(Node *n){ if(n == Z) return; nearln = n->lineno; if(debug['t']) if(n->op != OCONST) prtree(n, "pre complex"); if(tcom(n)) return; if(debug['t']) if(n->op != OCONST) prtree(n, "t complex"); ccom(n); if(debug['t']) if(n->op != OCONST) prtree(n, "c complex"); acom(n); if(debug['t']) if(n->op != OCONST) prtree(n, "a complex"); xcom(n); if(debug['t']) if(n->op != OCONST) prtree(n, "x complex");}/* * evaluate types * evaluate lvalues (addable == 1) */enum{ ADDROF = 1<<0, CASTOF = 1<<1, ADDROP = 1<<2,};inttcom(Node *n){ return tcomo(n, ADDROF);}inttcomo(Node *n, int f){ Node *l, *r; Type *t; int o; if(n == Z) { diag(Z, "Z in tcom"); errorexit(); } n->addable = 0; l = n->left; r = n->right; switch(n->op) { default: diag(n, "unknown op in type complex: %O", n->op); goto bad; case ODOTDOT: /* * tcom has already been called on this subtree */ *n = *n->left; if(n->type == T) goto bad; break; case OCAST: if(n->type == T) break; if(n->type->width == types[TLONG]->width) { if(tcomo(l, ADDROF|CASTOF)) goto bad; } else if(tcom(l)) goto bad; if(isfunct(n)) break; if(tcompat(n, l->type, n->type, tcast)) goto bad; break; case ORETURN: if(l == Z) { if(n->type->etype != TVOID) warn(n, "null return of a typed function"); break; } if(tcom(l)) goto bad; typeext(n->type, l); if(tcompat(n, n->type, l->type, tasign)) break; constas(n, n->type, l->type); if(!sametype(n->type, l->type)) { l = new1(OCAST, l, Z); l->type = n->type; n->left = l; } break; case OASI: /* same as as, but no test for const */ n->op = OAS; o = tcom(l); if(o | tcom(r)) goto bad; typeext(l->type, r); if(tlvalue(l) || tcompat(n, l->type, r->type, tasign)) goto bad; if(!sametype(l->type, r->type)) { r = new1(OCAST, r, Z); r->type = l->type; n->right = r; } n->type = l->type; break; case OAS: o = tcom(l); if(o | tcom(r)) goto bad; if(tlvalue(l)) goto bad; if(isfunct(n)) break; typeext(l->type, r); if(tcompat(n, l->type, r->type, tasign)) goto bad; constas(n, l->type, r->type); if(!sametype(l->type, r->type)) { r = new1(OCAST, r, Z); r->type = l->type; n->right = r; } n->type = l->type; break; case OASADD: case OASSUB: o = tcom(l); if(o | tcom(r)) goto bad; if(tlvalue(l)) goto bad; if(isfunct(n)) break; typeext1(l->type, r); if(tcompat(n, l->type, r->type, tasadd)) goto bad; constas(n, l->type, r->type); t = l->type; arith(n, 0); while(n->left->op == OCAST) n->left = n->left->left; if(!sametype(t, n->type) && !mixedasop(t, n->type)) { r = new1(OCAST, n->right, Z); r->type = t; n->right = r; n->type = t; } break; case OASMUL: case OASLMUL: case OASDIV: case OASLDIV: o = tcom(l); if(o | tcom(r)) goto bad; if(tlvalue(l)) goto bad; if(isfunct(n)) break; typeext1(l->type, r); if(tcompat(n, l->type, r->type, tmul)) goto bad; constas(n, l->type, r->type); t = l->type; arith(n, 0); while(n->left->op == OCAST) n->left = n->left->left; if(!sametype(t, n->type) && !mixedasop(t, n->type)) { r = new1(OCAST, n->right, Z); r->type = t; n->right = r; n->type = t; } if(typeu[n->type->etype]) { if(n->op == OASDIV) n->op = OASLDIV; if(n->op == OASMUL) n->op = OASLMUL; } break; case OASLSHR: case OASASHR: case OASASHL: o = tcom(l); if(o | tcom(r)) goto bad; if(tlvalue(l)) goto bad; if(isfunct(n)) break; if(tcompat(n, l->type, r->type, tand)) goto bad; n->type = l->type; if(typeu[n->type->etype]) { if(n->op == OASASHR) n->op = OASLSHR; } break; case OASMOD: case OASLMOD: case OASOR: case OASAND: case OASXOR: o = tcom(l); if(o | tcom(r)) goto bad; if(tlvalue(l)) goto bad; if(isfunct(n)) break; if(tcompat(n, l->type, r->type, tand)) goto bad; t = l->type; arith(n, 0); while(n->left->op == OCAST) n->left = n->left->left; if(!sametype(t, n->type) && !mixedasop(t, n->type)) { r = new1(OCAST, n->right, Z); r->type = t; n->right = r; n->type = t; } if(typeu[n->type->etype]) { if(n->op == OASMOD) n->op = OASLMOD; } break; case OPREINC: case OPREDEC: case OPOSTINC: case OPOSTDEC: if(tcom(l)) goto bad; if(tlvalue(l)) goto bad; if(isfunct(n)) break; if(tcompat(n, l->type, types[TINT], tadd)) goto bad; n->type = l->type; if(n->type->etype == TIND) if(n->type->link->width < 1) diag(n, "inc/dec of a void pointer"); break; case OEQ: case ONE: o = tcom(l); if(o | tcom(r)) goto bad; if(isfunct(n)) break; typeext(l->type, r); typeext(r->type, l); if(tcompat(n, l->type, r->type, trel)) goto bad; arith(n, 0); n->type = types[TINT]; break; case OLT: case OGE: case OGT: case OLE: o = tcom(l); if(o | tcom(r)) goto bad; if(isfunct(n)) break; typeext1(l->type, r); typeext1(r->type, l); if(tcompat(n, l->type, r->type, trel)) goto bad; arith(n, 0); if(typeu[n->type->etype]) n->op = logrel[relindex(n->op)]; n->type = types[TINT]; break; case OCOND: o = tcom(l); o |= tcom(r->left); if(o | tcom(r->right)) goto bad; if(r->right->type->etype == TIND && vconst(r->left) == 0) { r->left->type = r->right->type; r->left->vconst = 0; } if(r->left->type->etype == TIND && vconst(r->right) == 0) { r->right->type = r->left->type; r->right->vconst = 0; } if(sametype(r->right->type, r->left->type)) { r->type = r->right->type; n->type = r->type; break; } if(tcompat(r, r->left->type, r->right->type, trel)) goto bad; arith(r, 0); n->type = r->type; break; case OADD: o = tcom(l); if(o | tcom(r)) goto bad; if(isfunct(n)) break; if(tcompat(n, l->type, r->type, tadd)) goto bad; arith(n, 1); break; case OSUB: o = tcom(l); if(o | tcom(r)) goto bad; if(isfunct(n)) break; if(tcompat(n, l->type, r->type, tsub)) goto bad; arith(n, 1); break; case OMUL: case OLMUL: case ODIV: case OLDIV: o = tcom(l); if(o | tcom(r)) goto bad; if(isfunct(n)) break; if(tcompat(n, l->type, r->type, tmul)) goto bad; arith(n, 1); if(typeu[n->type->etype]) { if(n->op == ODIV) n->op = OLDIV; if(n->op == OMUL) n->op = OLMUL; } break; case OLSHR: case OASHL: case OASHR: o = tcom(l); if(o | tcom(r)) goto bad; if(isfunct(n)) break; if(tcompat(n, l->type, r->type, tand)) goto bad; n->right = Z; arith(n, 1); n->right = new1(OCAST, r, Z); n->right->type = types[TINT]; if(typeu[n->type->etype]) if(n->op == OASHR) n->op = OLSHR; break; case OAND: case OOR: case OXOR: o = tcom(l); if(o | tcom(r)) goto bad; if(isfunct(n)) break; if(tcompat(n, l->type, r->type, tand)) goto bad; arith(n, 1); break; case OMOD: case OLMOD: o = tcom(l); if(o | tcom(r)) goto bad; if(isfunct(n)) break; if(tcompat(n, l->type, r->type, tand)) goto bad; arith(n, 1); if(typeu[n->type->etype]) n->op = OLMOD; break; case OPOS: if(tcom(l)) goto bad; if(isfunct(n)) break; r = l; l = new(OCONST, Z, Z); l->vconst = 0; l->type = types[TINT]; n->op = OADD; n->right = r; n->left = l; if(tcom(l)) goto bad; if(tcompat(n, l->type, r->type, tsub)) goto bad; arith(n, 1); break; case ONEG: if(tcom(l)) goto bad; if(isfunct(n)) break; if(!machcap(n)) { r = l; l = new(OCONST, Z, Z); l->vconst = 0; l->type = types[TINT]; n->op = OSUB; n->right = r; n->left = l; if(tcom(l)) goto bad; if(tcompat(n, l->type, r->type, tsub)) goto bad; } arith(n, 1); break; case OCOM: if(tcom(l)) goto bad; if(isfunct(n)) break; if(!machcap(n)) { r = l; l = new(OCONST, Z, Z); l->vconst = -1; l->type = types[TINT]; n->op = OXOR; n->right = r; n->left = l; if(tcom(l)) goto bad; if(tcompat(n, l->type, r->type, tand)) goto bad; } arith(n, 1); break; case ONOT: if(tcom(l)) goto bad; if(isfunct(n)) break; if(tcompat(n, T, l->type, tnot)) goto bad; n->type = types[TINT]; break; case OANDAND: case OOROR: o = tcom(l); if(o | tcom(r)) goto bad; if(tcompat(n, T, l->type, tnot) | tcompat(n, T, r->type, tnot)) goto bad; n->type = types[TINT]; break; case OCOMMA: o = tcom(l); if(o | tcom(r)) goto bad; n->type = r->type; break; case OSIGN: /* extension signof(type) returns a hash */ if(l != Z) { if(l->op != OSTRING && l->op != OLSTRING) if(tcomo(l, 0)) goto bad; if(l->op == OBIT) { diag(n, "signof bitfield"); goto bad; } n->type = l->type; } if(n->type == T) goto bad; if(n->type->width < 0) { diag(n, "signof undefined type"); goto bad; } n->op = OCONST; n->left = Z; n->right = Z; n->vconst = convvtox(signature(n->type), TULONG); n->type = types[TULONG]; break; case OSIZE: if(l != Z) { if(l->op != OSTRING && l->op != OLSTRING) if(tcomo(l, 0)) goto bad; if(l->op == OBIT) { diag(n, "sizeof bitfield"); goto bad; } n->type = l->type; } if(n->type == T) goto bad; if(n->type->width <= 0) { diag(n, "sizeof undefined type"); goto bad; } if(n->type->etype == TFUNC) { diag(n, "sizeof function"); goto bad; } n->op = OCONST; n->left = Z; n->right = Z; n->vconst = convvtox(n->type->width, TINT); n->type = types[TINT]; break; case OFUNC: o = tcomo(l, 0); if(o) goto bad; if(l->type->etype == TIND && l->type->link->etype == TFUNC) { l = new1(OIND, l, Z); l->type = l->left->type->link; n->left = l; } if(tcompat(n, T, l->type, tfunct)) goto bad; if(o | tcoma(l, r, l->type->down, 1)) goto bad; n->type = l->type->link; if(!debug['B']) if(l->type->down == T || l->type->down->etype == TOLD) { nerrors--; diag(n, "function args not checked: %F", l); } dpcheck(n); break; case ONAME: if(n->type == T) { diag(n, "name not declared: %F", n); goto bad; } if(n->type->etype == TENUM) { n->op = OCONST; n->type = n->sym->tenum; if(!typefd[n->type->etype]) n->vconst = n->sym->vconst; else n->fconst = n->sym->fconst; break; } n->addable = 1; if(n->class == CEXREG) { n->op = OREGISTER; n->reg = n->sym->offset; n->xoffset = 0; break; } break; case OLSTRING: if(n->type->link != types[TUSHORT]) { o = outstring(0, 0); while(o & 3) { outlstring(L"", sizeof(ushort)); o = outlstring(0, 0); } } n->op = ONAME; n->xoffset = outlstring(n->rstring, n->type->width); n->addable = 1; break; case OSTRING: if(n->type->link != types[TCHAR]) { o = outstring(0, 0); while(o & 3) { outstring("", 1); o = outstring(0, 0); } } n->op = ONAME; n->xoffset = outstring(n->cstring, n->type->width); n->addable = 1; break; case OCONST: break; case ODOT: if(tcom(l)) goto bad; if(tcompat(n, T, l->type, tdot)) goto bad; if(tcomd(n)) goto bad; break; case OADDR: if(tcomo(l, ADDROP)) goto bad; if(tlvalue(l)) goto bad; if(l->type->nbits) { diag(n, "address of a bit field"); goto bad; } if(l->op == OREGISTER) { diag(n, "address of a register"); goto bad; } n->type = typ(TIND, l->type); n->type->width = types[TIND]->width; break; case OIND: if(tcom(l)) goto bad;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -