Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

enode.c

Go to the documentation of this file.
00001 #include "c.h"
00002 
00003 
00004 static Tree addtree(int, Tree, Tree);
00005 static Tree andtree(int, Tree, Tree);
00006 static Tree cmptree(int, Tree, Tree);
00007 static int compatible(Type, Type);
00008 static int isnullptr(Tree e);
00009 static Tree multree(int, Tree, Tree);
00010 static Tree subtree(int, Tree, Tree);
00011 #define isvoidptr(ty) \
00012     (isptr(ty) && unqual(ty->type) == voidtype)
00013 
00014 Tree (*optree[])(int, Tree, Tree) = {
00015 #define xx(a,b,c,d,e,f,g) e,
00016 #define yy(a,b,c,d,e,f,g) e,
00017 #include "token.h"
00018 };
00019 Tree call(Tree f, Type fty, Coordinate src) {
00020     int n = 0;
00021     Tree args = NULL, r = NULL, e;
00022     Type *proto, rty = unqual(freturn(fty));
00023     Symbol t3 = NULL;
00024 
00025     if (fty->u.f.oldstyle)
00026         proto = NULL;
00027     else
00028         proto = fty->u.f.proto;
00029     if (hascall(f))
00030         r = f;
00031     if (isstruct(rty))
00032         {
00033             t3 = temporary(AUTO, unqual(rty));
00034             if (rty->size == 0)
00035                 error("illegal use of incomplete type `%t'\n", rty);
00036         }
00037     if (t != ')')
00038         for (;;) {
00039             Tree q = pointer(expr1(0));
00040             if (proto && *proto && *proto != voidtype)
00041                 {
00042                     Type aty;
00043                     q = value(q);
00044                     aty = assign(*proto, q);
00045                     if (aty)
00046                         q = cast(q, aty);
00047                     else
00048                         error("type error in argument %d to %s; found `%t' expected `%t'\n", n + 1, funcname(f),
00049 
00050                             q->type, *proto);
00051                     if ((isint(q->type) || isenum(q->type))
00052                     && q->type->size != inttype->size)
00053                         q = cast(q, promote(q->type));
00054                     ++proto;
00055                 }
00056             else
00057                 {
00058                     if (!fty->u.f.oldstyle && *proto == NULL)
00059                         error("too many arguments to %s\n", funcname(f));
00060                     q = value(q);
00061                     if (isarray(q->type) || q->type->size == 0)
00062                         error("type error in argument %d to %s; `%t' is illegal\n", n + 1, funcname(f), q->type);
00063 
00064                     else
00065                         q = cast(q, promote(q->type));
00066                 }
00067             if (!IR->wants_argb && isstruct(q->type))
00068                 if (iscallb(q))
00069                     q = addrof(q);
00070                 else {
00071                     Symbol t1 = temporary(AUTO, unqual(q->type));
00072                     q = asgn(t1, q);
00073                     q = tree(RIGHT, ptr(t1->type),
00074                         root(q), lvalue(idtree(t1)));
00075                 }
00076             if (q->type->size == 0)
00077                 q->type = inttype;
00078             if (hascall(q))
00079                 r = r ? tree(RIGHT, voidtype, r, q) : q;
00080             args = tree(mkop(ARG, q->type), q->type, q, args);
00081             n++;
00082             if (Aflag >= 2 && n == 32)
00083                 warning("more than 31 arguments in a call to %s\n",
00084                     funcname(f));
00085             if (t != ',')
00086                 break;
00087             t = gettok();
00088         }
00089     expect(')');
00090     if (proto && *proto && *proto != voidtype)
00091         error("insufficient number of arguments to %s\n",
00092             funcname(f));
00093     if (r)
00094         args = tree(RIGHT, voidtype, r, args);
00095     e = calltree(f, rty, args, t3);
00096     if (events.calls)
00097         apply(events.calls, &src, &e);
00098     return e;
00099 }
00100 Tree calltree(Tree f, Type ty, Tree args, Symbol t3) {
00101     Tree p;
00102 
00103     if (args)
00104         f = tree(RIGHT, f->type, args, f);
00105     if (isstruct(ty))
00106         assert(t3),
00107         p = tree(RIGHT, ty,
00108             tree(CALL+B, ty, f, addrof(idtree(t3))),
00109             idtree(t3));
00110     else {
00111         Type rty = ty;
00112         if (isenum(ty))
00113             rty = unqual(ty)->type;
00114         if (!isfloat(rty))
00115             rty = promote(rty);
00116         p = tree(mkop(CALL, rty), rty, f, NULL);
00117         if (isptr(ty) || p->type->size > ty->size)
00118             p = cast(p, ty);
00119     }
00120     return p;
00121 }
00122 Tree vcall(Symbol func, Type ty, ...) {
00123     va_list ap;
00124     Tree args = NULL, e, f = pointer(idtree(func)), r = NULL;
00125 
00126     assert(isfunc(func->type));
00127     if (ty == NULL)
00128         ty = freturn(func->type);
00129     va_start(ap, ty);
00130     while ((e = va_arg(ap, Tree)) != NULL) {
00131         if (hascall(e))
00132             r = r == NULL ? e : tree(RIGHT, voidtype, r, e);
00133         args = tree(mkop(ARG, e->type), e->type, e, args);
00134     }
00135     va_end(ap);
00136     if (r != NULL)
00137         args = tree(RIGHT, voidtype, r, args);
00138     return calltree(f, ty, args, NULL);
00139 }
00140 int iscallb(Tree e) {
00141     return e->op == RIGHT && e->kids[0] && e->kids[1]
00142         && e->kids[0]->op == CALL+B
00143         && e->kids[1]->op == INDIR+B
00144         && isaddrop(e->kids[1]->kids[0]->op)
00145         && e->kids[1]->kids[0]->u.sym->temporary;
00146 }
00147 
00148 static Tree addtree(int op, Tree l, Tree r) {
00149     Type ty = inttype;
00150 
00151     if (isarith(l->type) && isarith(r->type)) {
00152         ty = binary(l->type, r->type);
00153         l = cast(l, ty);
00154         r = cast(r, ty);        
00155     } else if (isptr(l->type) && isint(r->type))
00156         return addtree(ADD, r, l);
00157     else if (  isptr(r->type) && isint(l->type)
00158     && !isfunc(r->type->type))
00159         {
00160             long n;
00161             ty = unqual(r->type);
00162             n = unqual(ty->type)->size;
00163             if (n == 0)
00164                 error("unknown size for type `%t'\n", ty->type);
00165             l = cast(l, promote(l->type));
00166             if (n > 1)
00167                 l = multree(MUL, cnsttree(signedptr, n), l);
00168             if (YYcheck && !isaddrop(r->op))        /* omit */
00169                 return nullcall(ty, YYcheck, r, l); /* omit */
00170             return simplify(ADD, ty, l, r);
00171         }
00172 
00173     else
00174         typeerror(op, l, r);
00175     return simplify(op, ty, l, r);
00176 }
00177 
00178 Tree cnsttree(Type ty, ...) {
00179     Tree p = tree(mkop(CNST,ty), ty, NULL, NULL);
00180     va_list ap;
00181 
00182     va_start(ap, ty);
00183     switch (ty->op) {
00184     case INT:     p->u.v.i = va_arg(ap, long); break;
00185     case UNSIGNED:p->u.v.u = va_arg(ap, unsigned long)&ones(8*ty->size); break;
00186     case FLOAT:   p->u.v.d = va_arg(ap, long double); break;
00187     case POINTER: p->u.v.p = va_arg(ap, void *); break;
00188     default: assert(0);
00189     }
00190     va_end(ap);
00191     return p;
00192 }
00193 
00194 Tree consttree(unsigned n, Type ty) {
00195     if (isarray(ty))
00196         ty = atop(ty);
00197     else assert(isint(ty));
00198     return cnsttree(ty, (unsigned long)n);
00199 }
00200 static Tree cmptree(int op, Tree l, Tree r) {
00201     Type ty;
00202 
00203     if (isarith(l->type) && isarith(r->type)) {
00204         ty = binary(l->type, r->type);
00205         l = cast(l, ty);
00206         r = cast(r, ty);
00207     } else if (compatible(l->type, r->type)) {
00208         ty = unsignedptr;
00209         l = cast(l, ty);
00210         r = cast(r, ty);
00211     } else {
00212         ty = unsignedtype;
00213         typeerror(op, l, r);
00214     }
00215     return simplify(mkop(op,ty), inttype, l, r);
00216 }
00217 static int compatible(Type ty1, Type ty2) {
00218     return isptr(ty1) && !isfunc(ty1->type)
00219         && isptr(ty2) && !isfunc(ty2->type)
00220         && eqtype(unqual(ty1->type), unqual(ty2->type), 0);
00221 }
00222 static int isnullptr(Tree e) {
00223     Type ty = unqual(e->type);
00224 
00225     return generic(e->op) == CNST
00226         && (ty->op == INT      && e->u.v.i == 0
00227          || ty->op == UNSIGNED && e->u.v.u == 0
00228          || isvoidptr(ty)      && e->u.v.p == NULL);
00229 }
00230 Tree eqtree(int op, Tree l, Tree r) {
00231     Type xty = l->type, yty = r->type;
00232 
00233     if (isptr(xty) && isnullptr(r)
00234     ||  isptr(xty) && !isfunc(xty->type) && isvoidptr(yty)
00235     ||  (isptr(xty) && isptr(yty)
00236         && eqtype(unqual(xty->type), unqual(yty->type), 1))) {
00237         Type ty = unsignedptr;
00238         l = cast(l, ty);
00239         r = cast(r, ty);
00240         return simplify(mkop(op,ty), inttype, l, r);
00241     }
00242     if (isptr(yty) && isnullptr(l)
00243     ||  isptr(yty) && !isfunc(yty->type) && isvoidptr(xty))
00244         return eqtree(op, r, l);
00245     return cmptree(op, l, r);
00246 }
00247 
00248 Type assign(Type xty, Tree e) {
00249     Type yty = unqual(e->type);
00250 
00251     xty = unqual(xty);
00252     if (isenum(xty))
00253         xty = xty->type;
00254     if (xty->size == 0 || yty->size == 0)
00255         return NULL;
00256     if ( isarith(xty) && isarith(yty)
00257     ||  isstruct(xty) && xty == yty)
00258         return xty;
00259     if (isptr(xty) && isnullptr(e))
00260         return xty;
00261     if ((isvoidptr(xty) && isptr(yty)
00262       || isptr(xty)     && isvoidptr(yty))
00263     && (  (isconst(xty->type)    || !isconst(yty->type))
00264        && (isvolatile(xty->type) || !isvolatile(yty->type))))
00265         return xty;
00266 
00267     if ((isptr(xty) && isptr(yty)
00268         && eqtype(unqual(xty->type), unqual(yty->type), 1))
00269     &&  (  (isconst(xty->type)    || !isconst(yty->type))
00270         && (isvolatile(xty->type) || !isvolatile(yty->type))))
00271         return xty;
00272     if (isptr(xty) && isptr(yty)
00273     && (  (isconst(xty->type)    || !isconst(yty->type))
00274        && (isvolatile(xty->type) || !isvolatile(yty->type)))) {
00275         Type lty = unqual(xty->type), rty = unqual(yty->type);
00276         if (isenum(lty) && rty == inttype
00277         ||  isenum(rty) && lty == inttype) {
00278             if (Aflag >= 1)
00279                 warning("assignment between `%t' and `%t' is compiler-dependent\n",
00280                     xty, yty);
00281             return xty;
00282         }
00283     }
00284     return NULL;
00285 }
00286 Tree asgntree(int op, Tree l, Tree r) {
00287     Type aty, ty;
00288 
00289     r = pointer(r);
00290     ty = assign(l->type, r);
00291     if (ty)
00292         r = cast(r, ty);
00293     else {
00294         typeerror(ASGN, l, r);
00295         if (r->type == voidtype)
00296             r = retype(r, inttype);
00297         ty = r->type;
00298     }
00299     if (l->op != FIELD)
00300         l = lvalue(l);
00301     aty = l->type;
00302     if (isptr(aty))
00303         aty = unqual(aty)->type;
00304     if ( isconst(aty)
00305     ||  isstruct(aty) && unqual(aty)->u.sym->u.s.cfields)
00306         if (isaddrop(l->op)
00307         && !l->u.sym->computed && !l->u.sym->generated)
00308             error("assignment to const identifier `%s'\n",
00309                 l->u.sym->name);
00310         else
00311             error("assignment to const location\n");
00312     if (l->op == FIELD) {
00313         long n = 8*l->u.field->type->size - fieldsize(l->u.field);
00314         if (n > 0 && isunsigned(l->u.field->type))
00315             r = bittree(BAND, r,
00316                 cnsttree(r->type, (unsigned long)fieldmask(l->u.field)));
00317         else if (n > 0) {
00318             if (r->op == CNST+I) {
00319                 n = r->u.v.i;
00320                 if (n&(1<<(fieldsize(l->u.field)-1)))
00321                     n |= ~0UL<<fieldsize(l->u.field);
00322                 r = cnsttree(r->type, n);
00323             } else
00324                 r = shtree(RSH,
00325                     shtree(LSH, r, cnsttree(inttype, n)),
00326                     cnsttree(inttype, n));
00327         }
00328     }
00329     if (isstruct(ty) && isaddrop(l->op) && iscallb(r))
00330         return tree(RIGHT, ty,
00331             tree(CALL+B, ty, r->kids[0]->kids[0], l),
00332             idtree(l->u.sym));
00333     return tree(mkop(op,ty), ty, l, r);
00334 }
00335 Tree condtree(Tree e, Tree l, Tree r) {
00336     Symbol t1;
00337     Type ty, xty = l->type, yty = r->type;
00338     Tree p;
00339 
00340     if (isarith(xty) && isarith(yty))
00341         ty = binary(xty, yty);
00342     else if (eqtype(xty, yty, 1))
00343         ty = unqual(xty);
00344     else if (isptr(xty)   && isnullptr(r))
00345         ty = xty;
00346     else if (isnullptr(l) && isptr(yty))
00347         ty = yty;
00348     else if (isptr(xty) && !isfunc(xty->type) && isvoidptr(yty)
00349     ||       isptr(yty) && !isfunc(yty->type) && isvoidptr(xty))
00350         ty = voidptype;
00351     else if ((isptr(xty) && isptr(yty)
00352          && eqtype(unqual(xty->type), unqual(yty->type), 1)))
00353         ty = xty;
00354     else {
00355         typeerror(COND, l, r);
00356         return consttree(0, inttype);
00357     }
00358     if (isptr(ty)) {
00359         ty = unqual(unqual(ty)->type);
00360         if (isptr(xty) && isconst(unqual(xty)->type)
00361         ||  isptr(yty) && isconst(unqual(yty)->type))
00362             ty = qual(CONST, ty);
00363         if (isptr(xty) && isvolatile(unqual(xty)->type)
00364         ||  isptr(yty) && isvolatile(unqual(yty)->type))
00365             ty = qual(VOLATILE, ty);
00366         ty = ptr(ty);
00367     }
00368     switch (e->op) {
00369     case CNST+I: return cast(e->u.v.i != 0   ? l : r, ty);
00370     case CNST+U: return cast(e->u.v.u != 0   ? l : r, ty);
00371     case CNST+P: return cast(e->u.v.p != 0   ? l : r, ty);
00372     case CNST+F: return cast(e->u.v.d != 0.0 ? l : r, ty);
00373     }
00374     if (ty != voidtype && ty->size > 0) {
00375         t1 = genident(REGISTER, unqual(ty), level);
00376     /*  t1 = temporary(REGISTER, unqual(ty)); */
00377         l = asgn(t1, l);
00378         r = asgn(t1, r);
00379     } else
00380         t1 = NULL;
00381     p = tree(COND, ty, cond(e),
00382         tree(RIGHT, ty, root(l), root(r)));
00383     p->u.sym = t1;
00384     return p;
00385 }
00386 /* addrof - address of p */
00387 Tree addrof(Tree p) {
00388     Tree q = p;
00389 
00390     for (;;)
00391         switch (generic(q->op)) {
00392         case RIGHT:
00393             assert(q->kids[0] || q->kids[1]);
00394             q = q->kids[1] ? q->kids[1] : q->kids[0];
00395             continue;
00396         case ASGN:
00397             q = q->kids[1];
00398             continue;
00399         case COND: {
00400             Symbol t1 = q->u.sym;
00401             q->u.sym = 0;
00402             q = idtree(t1);
00403             /* fall thru */
00404             }
00405         case INDIR:
00406             if (p == q)
00407                 return q->kids[0];
00408             q = q->kids[0];
00409             return tree(RIGHT, q->type, root(p), q);
00410         default:
00411             error("addressable object required\n");
00412             return value(p);
00413         }
00414 }
00415 
00416 /* andtree - construct tree for l [&& ||] r */
00417 static Tree andtree(int op, Tree l, Tree r) {
00418     if (!isscalar(l->type) || !isscalar(r->type))
00419         typeerror(op, l, r);
00420     return simplify(op, inttype, cond(l), cond(r));
00421 }
00422 
00423 /* asgn - generate tree for assignment of expr e to symbol p sans qualifiers */
00424 Tree asgn(Symbol p, Tree e) {
00425     if (isarray(p->type))
00426         e = tree(ASGN+B, p->type, idtree(p),
00427             tree(INDIR+B, e->type, e, NULL));
00428     else {
00429         Type ty = p->type;
00430         p->type = unqual(p->type);
00431         if (isstruct(p->type) && p->type->u.sym->u.s.cfields) {
00432             p->type->u.sym->u.s.cfields = 0;
00433             e = asgntree(ASGN, idtree(p), e);
00434             p->type->u.sym->u.s.cfields = 1;
00435         } else
00436             e = asgntree(ASGN, idtree(p), e);
00437         p->type = ty;
00438     }
00439     return e;
00440 }
00441 
00442 /* bittree - construct tree for l [& | ^ %] r */
00443 Tree bittree(int op, Tree l, Tree r) {
00444     Type ty = inttype;
00445 
00446     if (isint(l->type) && isint(r->type)) {
00447         ty = binary(l->type, r->type);
00448         l = cast(l, ty);
00449         r = cast(r, ty);        
00450     } else
00451         typeerror(op, l, r);
00452     return simplify(op, ty, l, r);
00453 }
00454 
00455 /* multree - construct tree for l [* /] r */
00456 static Tree multree(int op, Tree l, Tree r) {
00457     Type ty = inttype;
00458 
00459     if (isarith(l->type) && isarith(r->type)) {
00460         ty = binary(l->type, r->type);
00461         l = cast(l, ty);
00462         r = cast(r, ty);        
00463     } else
00464         typeerror(op, l, r);
00465     return simplify(op, ty, l, r);
00466 }
00467 
00468 /* shtree - construct tree for l [>> <<] r */
00469 Tree shtree(int op, Tree l, Tree r) {
00470     Type ty = inttype;
00471 
00472     if (isint(l->type) && isint(r->type)) {
00473         ty = promote(l->type);
00474         l = cast(l, ty);
00475         r = cast(r, inttype);
00476     } else
00477         typeerror(op, l, r);
00478     return simplify(op, ty, l, r);
00479 }
00480 
00481 /* subtree - construct tree for l - r */
00482 static Tree subtree(int op, Tree l, Tree r) {
00483     long n;
00484     Type ty = inttype;
00485 
00486     if (isarith(l->type) && isarith(r->type)) {
00487         ty = binary(l->type, r->type);
00488         l = cast(l, ty);
00489         r = cast(r, ty);        
00490     } else if (isptr(l->type) && !isfunc(l->type->type) && isint(r->type)) {
00491         ty = unqual(l->type);
00492         n = unqual(ty->type)->size;
00493         if (n == 0)
00494             error("unknown size for type `%t'\n", ty->type);
00495         r = cast(r, promote(r->type));
00496         if (n > 1)
00497             r = multree(MUL, cnsttree(signedptr, n), r);
00498         if (isunsigned(r->type))
00499             r = cast(r, unsignedptr);
00500         else
00501             r = cast(r, signedptr);
00502         return simplify(SUB+P, ty, l, r);
00503     } else if (compatible(l->type, r->type)) {
00504         ty = unqual(l->type);
00505         n = unqual(ty->type)->size;
00506         if (n == 0)
00507             error("unknown size for type `%t'\n", ty->type);
00508         l = simplify(SUB+U, unsignedptr,
00509             cast(l, unsignedptr), cast(r, unsignedptr));
00510         return simplify(DIV+I, longtype,
00511             cast(l, longtype), cnsttree(longtype, n));
00512     } else
00513         typeerror(op, l, r);
00514     return simplify(op, ty, l, r);
00515 }
00516 
00517 /* typeerror - issue "operands of op have illegal types `l' and `r'" */
00518 void typeerror(int op, Tree l, Tree r) {
00519     int i;
00520     static struct { int op; char *name; } ops[] = {
00521         ASGN, "=",  INDIR, "*", NEG,  "-",
00522         ADD,  "+",  SUB,   "-", LSH,  "<<",
00523         MOD,  "%",  RSH,   ">>",    BAND, "&",
00524         BCOM, "~",  BOR,   "|", BXOR, "^",
00525         DIV,  "/",  MUL,   "*", EQ,   "==",
00526         GE,   ">=", GT,    ">", LE,   "<=",
00527         LT,   "<",  NE,    "!=",    AND,  "&&",
00528         NOT,  "!",  OR,    "||",    COND, "?:",
00529         0, 0
00530     };
00531 
00532     op = generic(op);
00533     for (i = 0; ops[i].op; i++)
00534         if (op == ops[i].op)
00535             break;
00536     assert(ops[i].name);
00537     if (r)
00538         error("operands of %s have illegal types `%t' and `%t'\n",
00539             ops[i].name, l->type, r->type);
00540     else
00541         error("operand of unary %s has illegal type `%t'\n", ops[i].name,
00542             l->type);
00543 }

Generated on Thu Aug 25 12:38:13 2005 for Quake III Arena by  doxygen 1.3.9.1