/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include "cc.h" Node*new(int t, Node *l, Node *r){ Node *n; n = alloc(sizeof(*n)); n->op = t; n->left = l; n->right = r; if(l && t != OGOTO) n->lineno = l->lineno; else if(r) n->lineno = r->lineno; else n->lineno = lineno; newflag = 1; return n;} Node*new1(int o, Node *l, Node *r){ Node *n; n = new(o, l, r); n->lineno = nearln; return n;} voidprtree(Node *n, char *s){ print(" == %s ==\n", s); prtree1(n, 0, 0); print("\n");} voidprtree1(Node *n, int d, int f){ int i; if(f) for(i=0; i<d; i++) print(" "); if(n == Z) { print("Z\n"); return; } if(n->op == OLIST) { prtree1(n->left, d, 0); prtree1(n->right, d, 1); return; } d++; print("%O", n->op); i = 3; switch(n->op) { case ONAME: print(" \"%F\"", n); print(" %ld", n->xoffset); i = 0; break; case OINDREG: print(" %ld(R%d)", n->xoffset, n->reg); i = 0; break; case OREGISTER: if(n->xoffset) print(" %ld+R%d", n->xoffset, n->reg); else print(" R%d", n->reg); i = 0; break; case OSTRING: print(" \"%s\"", n->cstring); i = 0; break; case OLSTRING: if(sizeof(TRune) == sizeof(Rune)) print(" \"%S\"", (Rune*)n->rstring); else print(" \"...\""); i = 0; break; case ODOT: case OELEM: print(" \"%F\"", n); break; case OCONST: if(typefd[n->type->etype]) print(" \"%.8e\"", n->fconst); else print(" \"%lld\"", n->vconst); i = 0; break; } if(n->addable != 0) print(" <%d>", n->addable); if(n->type != T) print(" %T", n->type); if(n->complex != 0) print(" (%d)", n->complex); print(" %L\n", n->lineno); if(i & 2) prtree1(n->left, d, 1); if(i & 1) prtree1(n->right, d, 1);} Type*typ(int et, Type *d){ Type *t; t = alloc(sizeof(*t)); t->etype = et; t->link = d; t->down = T; t->sym = S; t->width = ewidth[et]; t->offset = 0; t->shift = 0; t->nbits = 0; t->garb = 0; return t;} Type*copytyp(Type *t){ Type *nt; nt = typ(TXXX, T); *nt = *t; return nt;} Type*garbt(Type *t, long b){ Type *t1; if(b & BGARB) { t1 = copytyp(t); t1->garb = simpleg(b); return t1; } return t;} intsimpleg(long b){ b &= BGARB; switch(b) { case BCONSTNT: return GCONSTNT; case BVOLATILE: return GVOLATILE; case BVOLATILE|BCONSTNT: return GCONSTNT|GVOLATILE; } return GXXX;} intsimplec(long b){ b &= BCLASS; switch(b) { case 0: case BREGISTER: return CXXX; case BAUTO: case BAUTO|BREGISTER: return CAUTO; case BEXTERN: return CEXTERN; case BEXTERN|BREGISTER: return CEXREG; case BSTATIC: return CSTATIC; case BTYPEDEF: return CTYPEDEF; case BTYPESTR: return CTYPESTR; } diag(Z, "illegal combination of classes %Q", b); return CXXX;} Type*simplet(long b){ b &= ~BCLASS & ~BGARB; switch(b) { case BCHAR: case BCHAR|BSIGNED: return types[TCHAR]; case BCHAR|BUNSIGNED: return types[TUCHAR]; case BSHORT: case BSHORT|BINT: case BSHORT|BSIGNED: case BSHORT|BINT|BSIGNED: return types[TSHORT]; case BUNSIGNED|BSHORT: case BUNSIGNED|BSHORT|BINT: return types[TUSHORT]; case 0: case BINT: case BINT|BSIGNED: case BSIGNED: return types[TINT]; case BUNSIGNED: case BUNSIGNED|BINT: return types[TUINT]; case BLONG: case BLONG|BINT: case BLONG|BSIGNED: case BLONG|BINT|BSIGNED: return types[TLONG]; case BUNSIGNED|BLONG: case BUNSIGNED|BLONG|BINT: return types[TULONG]; case BVLONG|BLONG: case BVLONG|BLONG|BINT: case BVLONG|BLONG|BSIGNED: case BVLONG|BLONG|BINT|BSIGNED: return types[TVLONG]; case BVLONG|BLONG|BUNSIGNED: case BVLONG|BLONG|BINT|BUNSIGNED: return types[TUVLONG]; case BFLOAT: return types[TFLOAT]; case BDOUBLE: case BDOUBLE|BLONG: case BFLOAT|BLONG: return types[TDOUBLE]; case BVOID: return types[TVOID]; } diag(Z, "illegal combination of types %Q", b); return types[TINT];} intstcompat(Node *n, Type *t1, Type *t2, long ttab[]){ int i; ulong b; i = 0; if(t2 != T) i = t2->etype; b = 1L << i; i = 0; if(t1 != T) i = t1->etype; if(b & ttab[i]) { if(ttab == tasign) if(b == BSTRUCT || b == BUNION) if(!sametype(t1, t2)) return 1; if(n->op != OCAST) if(b == BIND && i == TIND) if(!sametype(t1, t2)) return 1; return 0; } return 1;} inttcompat(Node *n, Type *t1, Type *t2, long ttab[]){ if(stcompat(n, t1, t2, ttab)) { if(t1 == T) diag(n, "incompatible type: \"%T\" for op \"%O\"", t2, n->op); else diag(n, "incompatible types: \"%T\" and \"%T\" for op \"%O\"", t1, t2, n->op); return 1; } return 0;} voidmakedot(Node *n, Type *t, long o){ Node *n1, *n2; if(t->nbits) { n1 = new(OXXX, Z, Z); *n1 = *n; n->op = OBIT; n->left = n1; n->right = Z; n->type = t; n->addable = n1->left->addable; n = n1; } n->addable = n->left->addable; if(n->addable == 0) { n1 = new1(OCONST, Z, Z); n1->vconst = o; n1->type = types[TLONG]; n->right = n1; n->type = t; return; } n->left->type = t; if(o == 0) { *n = *n->left; return; } n->type = t; n1 = new1(OCONST, Z, Z); n1->vconst = o; t = typ(TIND, t); t->width = types[TIND]->width; n1->type = t; n2 = new1(OADDR, n->left, Z); n2->type = t; n1 = new1(OADD, n1, n2); n1->type = t; n->op = OIND; n->left = n1; n->right = Z;} Type*dotsearch(Sym *s, Type *t, Node *n, long *off){ Type *t1, *xt, *rt; xt = T; /* * look it up by name */ for(t1 = t; t1 != T; t1 = t1->down) if(t1->sym == s) { if(xt != T) goto ambig; xt = t1; } /* * look it up by type */ if(s->class == CTYPEDEF || s->class == CTYPESTR) for(t1 = t; t1 != T; t1 = t1->down) if(t1->sym == S && typesu[t1->etype]) if(sametype(s->type, t1)) { if(xt != T) goto ambig; xt = t1; } if(xt != T) { *off = xt->offset; return xt; } /* * look it up in unnamed substructures */ for(t1 = t; t1 != T; t1 = t1->down) if(t1->sym == S && typesu[t1->etype]){ rt = dotsearch(s, t1->link, n, off); if(rt != T) { if(xt != T) goto ambig; xt = rt; *off += t1->offset; } } return xt; ambig: diag(n, "ambiguous structure element: %s", s->name); return xt;} longdotoffset(Type *st, Type *lt, Node *n){ Type *t; Sym *g; long o, o1; o = -1; /* * first try matching at the top level * for matching tag names */ g = st->tag; if(g != S) for(t=lt->link; t!=T; t=t->down) if(t->sym == S) if(g == t->tag) { if(o >= 0) goto ambig; o = t->offset; } if(o >= 0) return o; /* * second try matching at the top level * for similar types */ for(t=lt->link; t!=T; t=t->down) if(t->sym == S) if(sametype(st, t)) { if(o >= 0) goto ambig; o = t->offset; } if(o >= 0) return o; /* * last try matching sub-levels */ for(t=lt->link; t!=T; t=t->down) if(t->sym == S) if(typesu[t->etype]) { o1 = dotoffset(st, t, n); if(o1 >= 0) { if(o >= 0) goto ambig; o = o1 + t->offset; } } return o; ambig: diag(n, "ambiguous unnamed structure element"); return o;} /* * look into tree for floating point constant expressions */intallfloat(Node *n, int flag){ if(n != Z) { if(n->type->etype != TDOUBLE) return 1; switch(n->op) { case OCONST: if(flag) n->type = types[TFLOAT]; return 1; case OADD: /* no need to get more exotic than this */ case OSUB:Lines 1–500 of 2041. Load more
/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include "cc.h" Node* new(int t, Node *l, Node *r) { Node *n; n = alloc(sizeof(*n)); n->op = t; n->left = l; n->right = r; if(l && t != OGOTO) n->lineno = l->lineno; else if(r) n->lineno = r->lineno; else n->lineno = lineno; newflag = 1; return n; } Node* new1(int o, Node *l, Node *r) { Node *n; n = new(o, l, r); n->lineno = nearln; return n; } void prtree(Node *n, char *s) { print(" == %s ==\n", s); prtree1(n, 0, 0); print("\n"); } void prtree1(Node *n, int d, int f) { int i; if(f) for(i=0; i<d; i++) print(" "); if(n == Z) { print("Z\n"); return; } if(n->op == OLIST) { prtree1(n->left, d, 0); prtree1(n->right, d, 1); return; } d++; print("%O", n->op); i = 3; switch(n->op) { case ONAME: print(" \"%F\"", n); print(" %ld", n->xoffset); i = 0; break; case OINDREG: print(" %ld(R%d)", n->xoffset, n->reg); i = 0; break; case OREGISTER: if(n->xoffset) print(" %ld+R%d", n->xoffset, n->reg); else print(" R%d", n->reg); i = 0; break; case OSTRING: print(" \"%s\"", n->cstring); i = 0; break; case OLSTRING: if(sizeof(TRune) == sizeof(Rune)) print(" \"%S\"", (Rune*)n->rstring); else print(" \"...\""); i = 0; break; case ODOT: case OELEM: print(" \"%F\"", n); break; case OCONST: if(typefd[n->type->etype]) print(" \"%.8e\"", n->fconst); else print(" \"%lld\"", n->vconst); i = 0; break; } if(n->addable != 0) print(" <%d>", n->addable); if(n->type != T) print(" %T", n->type); if(n->complex != 0) print(" (%d)", n->complex); print(" %L\n", n->lineno); if(i & 2) prtree1(n->left, d, 1); if(i & 1) prtree1(n->right, d, 1); } Type* typ(int et, Type *d) { Type *t; t = alloc(sizeof(*t)); t->etype = et; t->link = d; t->down = T; t->sym = S; t->width = ewidth[et]; t->offset = 0; t->shift = 0; t->nbits = 0; t->garb = 0; return t; } Type* copytyp(Type *t) { Type *nt; nt = typ(TXXX, T); *nt = *t; return nt; } Type* garbt(Type *t, long b) { Type *t1; if(b & BGARB) { t1 = copytyp(t); t1->garb = simpleg(b); return t1; } return t; } int simpleg(long b) { b &= BGARB; switch(b) { case BCONSTNT: return GCONSTNT; case BVOLATILE: return GVOLATILE; case BVOLATILE|BCONSTNT: return GCONSTNT|GVOLATILE; } return GXXX; } int simplec(long b) { b &= BCLASS; switch(b) { case 0: case BREGISTER: return CXXX; case BAUTO: case BAUTO|BREGISTER: return CAUTO; case BEXTERN: return CEXTERN; case BEXTERN|BREGISTER: return CEXREG; case BSTATIC: return CSTATIC; case BTYPEDEF: return CTYPEDEF; case BTYPESTR: return CTYPESTR; } diag(Z, "illegal combination of classes %Q", b); return CXXX; } Type* simplet(long b) { b &= ~BCLASS & ~BGARB; switch(b) { case BCHAR: case BCHAR|BSIGNED: return types[TCHAR]; case BCHAR|BUNSIGNED: return types[TUCHAR]; case BSHORT: case BSHORT|BINT: case BSHORT|BSIGNED: case BSHORT|BINT|BSIGNED: return types[TSHORT]; case BUNSIGNED|BSHORT: case BUNSIGNED|BSHORT|BINT: return types[TUSHORT]; case 0: case BINT: case BINT|BSIGNED: case BSIGNED: return types[TINT]; case BUNSIGNED: case BUNSIGNED|BINT: return types[TUINT]; case BLONG: case BLONG|BINT: case BLONG|BSIGNED: case BLONG|BINT|BSIGNED: return types[TLONG]; case BUNSIGNED|BLONG: case BUNSIGNED|BLONG|BINT: return types[TULONG]; case BVLONG|BLONG: case BVLONG|BLONG|BINT: case BVLONG|BLONG|BSIGNED: case BVLONG|BLONG|BINT|BSIGNED: return types[TVLONG]; case BVLONG|BLONG|BUNSIGNED: case BVLONG|BLONG|BINT|BUNSIGNED: return types[TUVLONG]; case BFLOAT: return types[TFLOAT]; case BDOUBLE: case BDOUBLE|BLONG: case BFLOAT|BLONG: return types[TDOUBLE]; case BVOID: return types[TVOID]; } diag(Z, "illegal combination of types %Q", b); return types[TINT]; } int stcompat(Node *n, Type *t1, Type *t2, long ttab[]) { int i; ulong b; i = 0; if(t2 != T) i = t2->etype; b = 1L << i; i = 0; if(t1 != T) i = t1->etype; if(b & ttab[i]) { if(ttab == tasign) if(b == BSTRUCT || b == BUNION) if(!sametype(t1, t2)) return 1; if(n->op != OCAST) if(b == BIND && i == TIND) if(!sametype(t1, t2)) return 1; return 0; } return 1; } int tcompat(Node *n, Type *t1, Type *t2, long ttab[]) { if(stcompat(n, t1, t2, ttab)) { if(t1 == T) diag(n, "incompatible type: \"%T\" for op \"%O\"", t2, n->op); else diag(n, "incompatible types: \"%T\" and \"%T\" for op \"%O\"", t1, t2, n->op); return 1; } return 0; } void makedot(Node *n, Type *t, long o) { Node *n1, *n2; if(t->nbits) { n1 = new(OXXX, Z, Z); *n1 = *n; n->op = OBIT; n->left = n1; n->right = Z; n->type = t; n->addable = n1->left->addable; n = n1; } n->addable = n->left->addable; if(n->addable == 0) { n1 = new1(OCONST, Z, Z); n1->vconst = o; n1->type = types[TLONG]; n->right = n1; n->type = t; return; } n->left->type = t; if(o == 0) { *n = *n->left; return; } n->type = t; n1 = new1(OCONST, Z, Z); n1->vconst = o; t = typ(TIND, t); t->width = types[TIND]->width; n1->type = t; n2 = new1(OADDR, n->left, Z); n2->type = t; n1 = new1(OADD, n1, n2); n1->type = t; n->op = OIND; n->left = n1; n->right = Z; } Type* dotsearch(Sym *s, Type *t, Node *n, long *off) { Type *t1, *xt, *rt; xt = T; /* * look it up by name */ for(t1 = t; t1 != T; t1 = t1->down) if(t1->sym == s) { if(xt != T) goto ambig; xt = t1; } /* * look it up by type */ if(s->class == CTYPEDEF || s->class == CTYPESTR) for(t1 = t; t1 != T; t1 = t1->down) if(t1->sym == S && typesu[t1->etype]) if(sametype(s->type, t1)) { if(xt != T) goto ambig; xt = t1; } if(xt != T) { *off = xt->offset; return xt; } /* * look it up in unnamed substructures */ for(t1 = t; t1 != T; t1 = t1->down) if(t1->sym == S && typesu[t1->etype]){ rt = dotsearch(s, t1->link, n, off); if(rt != T) { if(xt != T) goto ambig; xt = rt; *off += t1->offset; } } return xt; ambig: diag(n, "ambiguous structure element: %s", s->name); return xt; } long dotoffset(Type *st, Type *lt, Node *n) { Type *t; Sym *g; long o, o1; o = -1; /* * first try matching at the top level * for matching tag names */ g = st->tag; if(g != S) for(t=lt->link; t!=T; t=t->down) if(t->sym == S) if(g == t->tag) { if(o >= 0) goto ambig; o = t->offset; } if(o >= 0) return o; /* * second try matching at the top level * for similar types */ for(t=lt->link; t!=T; t=t->down) if(t->sym == S) if(sametype(st, t)) { if(o >= 0) goto ambig; o = t->offset; } if(o >= 0) return o; /* * last try matching sub-levels */ for(t=lt->link; t!=T; t=t->down) if(t->sym == S) if(typesu[t->etype]) { o1 = dotoffset(st, t, n); if(o1 >= 0) { if(o >= 0) goto ambig; o = o1 + t->offset; } } return o; ambig: diag(n, "ambiguous unnamed structure element"); return o; } /* * look into tree for floating point constant expressions */ int allfloat(Node *n, int flag) { if(n != Z) { if(n->type->etype != TDOUBLE) return 1; switch(n->op) { case OCONST: if(flag) n->type = types[TFLOAT]; return 1; case OADD: /* no need to get more exotic than this */ case OSUB: